diff --git a/DEPS b/DEPS
index 776a9bb..7320eda1 100644
--- a/DEPS
+++ b/DEPS
@@ -105,11 +105,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '9457546761a40c96f586b34b755fef47a7ad006a',
+  'skia_revision': '5741a5ba7f369a85cb1f93466cb710bcb0bb49d5',
   # 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': '7a5731ed6129d32905fdef1149410134393c1a30',
+  'v8_revision': 'f237b823b51f9001a8c75767581f6a7bc28bac22',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -117,7 +117,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '3237f75953c1a5aef37535fe9fdba5842f2b4a4e',
+  'angle_revision': '8a4c49fb794e34ce00ec11ea43c7b49a46dc5134',
   # 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.
@@ -165,7 +165,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '7a75f465f541280d20b4e96caf477517b0fc4b18',
+  'catapult_revision': '87eefd4f114377b460c952a4a89cb1875b7bd4cb',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -339,7 +339,7 @@
   },
 
   'src/media/cdm/api':
-    Var('chromium_git') + '/chromium/cdm.git' + '@' + 'd1260255637fe01acd08ba166f76945e83e02cc3',
+    Var('chromium_git') + '/chromium/cdm.git' + '@' + 'bd20cfc8e34ece484e4983dc0dfcca4ec9e53253',
 
   'src/native_client': {
       'url': Var('chromium_git') + '/native_client/src/native_client.git' + '@' + Var('nacl_revision'),
@@ -397,6 +397,28 @@
       'condition': 'checkout_android_native_support',
   },
 
+  'src/third_party/android_build_tools/aapt2': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_tools_aapt2',
+              'version': 'version:3.2.0-alpha18-4804415-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_build_tools/bundletool': {
+      'packages': [
+          {
+       'package': 'chromium/third_party/android_tools_bundletool',
+       'version': 'version:0.4.2-cr0',
+   },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
   'src/third_party/android_sdk/public': {
       'packages': [
           {
@@ -543,7 +565,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '4099daa97b38b2ddb95e34d9fc3e2d37f58df069',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c5a26a769e69377391ed9bf71ca74d7eae5e6717',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -578,7 +600,7 @@
   },
 
   'src/third_party/ffmpeg':
-    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'c3b8d611c12f31f9df0c0f7a86f1723b33a414fc',
+    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'de23348fef6fd063b066e9652005973f86ed52ff',
 
   'src/third_party/flac':
     Var('chromium_git') + '/chromium/deps/flac.git' + '@' + 'af862024c8c8fa0ae07ced05e89013d881b00596',
@@ -1010,7 +1032,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '5e83981c2c44f24109b96b555d6865d481e0c609',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '5f5819f8ed8ae0561109040fbdce0b2ee4854257',
+    Var('webrtc_git') + '/src.git' + '@' + '0d4ee0a9694680e2927314d5a8202ba283380a40',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index e9afb6d..d024c94 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -1876,6 +1876,7 @@
     "system/tray_tracing_unittest.cc",
     "system/unified/accessibility_feature_pod_controller_unittest.cc",
     "system/unified/feature_pods_container_view_unittest.cc",
+    "system/unified/quiet_mode_feature_pod_controller_unittest.cc",
     "system/unified/top_shortcuts_view_unittest.cc",
     "system/unified/unified_system_info_view_unittest.cc",
     "system/unified/unified_system_tray_controller_unittest.cc",
diff --git a/ash/system/model/clock_model.cc b/ash/system/model/clock_model.cc
index bddbd7b..4e85f345 100644
--- a/ash/system/model/clock_model.cc
+++ b/ash/system/model/clock_model.cc
@@ -39,7 +39,7 @@
 }
 
 bool ClockModel::IsLoggedIn() {
-  return Shell::Get()->session_controller()->login_status() ==
+  return Shell::Get()->session_controller()->login_status() !=
          LoginStatus::NOT_LOGGED_IN;
 }
 
diff --git a/ash/system/model/clock_model.h b/ash/system/model/clock_model.h
index f83bc08..c32b8e9 100644
--- a/ash/system/model/clock_model.h
+++ b/ash/system/model/clock_model.h
@@ -54,10 +54,10 @@
   void NotifySystemClockCanSetTimeChanged(bool can_set_time);
 
   // The type of clock hour display: 12 or 24 hour.
-  base::HourClockType hour_clock_type_;
+  base::HourClockType hour_clock_type_ = base::k12HourClock;
 
   // If system clock can be configured by user through SetTimeDialog.
-  bool can_set_time_;
+  bool can_set_time_ = false;
 
   base::ObserverList<ClockObserver> observers_;
 
diff --git a/ash/system/tray/tray_constants.cc b/ash/system/tray/tray_constants.cc
index 8ae0fc7..0acee76f 100644
--- a/ash/system/tray/tray_constants.cc
+++ b/ash/system/tray/tray_constants.cc
@@ -77,4 +77,11 @@
 
 const int kTrayPopupSystemInfoRowHeight = 40;
 
+static_assert(kTrayMenuWidth == kUnifiedFeaturePodHorizontalSidePadding * 2 +
+                                    kUnifiedFeaturePodHorizontalMiddlePadding *
+                                        (kUnifiedFeaturePodItemsInRow - 1) +
+                                    kUnifiedFeaturePodSize.width() *
+                                        kUnifiedFeaturePodItemsInRow,
+              "Total feature pod width does not match kTrayMenuWidth");
+
 }  // namespace ash
diff --git a/ash/system/tray/tray_constants.h b/ash/system/tray/tray_constants.h
index 87ce136..257d3a6 100644
--- a/ash/system/tray/tray_constants.h
+++ b/ash/system/tray/tray_constants.h
@@ -167,15 +167,15 @@
 
 // Constants used in FeaturePodsView of UnifiedSystemTray.
 constexpr gfx::Size kUnifiedFeaturePodIconSize(48, 48);
-constexpr gfx::Size kUnifiedFeaturePodSize(80, 88);
+constexpr gfx::Size kUnifiedFeaturePodSize(84, 88);
 constexpr gfx::Size kUnifiedFeaturePodCollapsedSize(48, 48);
 constexpr gfx::Insets kUnifiedFeaturePodIconPadding(4);
 constexpr gfx::Insets kUnifiedFeaturePodHoverPadding(2);
 constexpr int kUnifiedFeaturePodSpacing = 6;
 constexpr int kUnifiedFeaturePodHoverRadius = 4;
 constexpr int kUnifiedFeaturePodVerticalPadding = 28;
-constexpr int kUnifiedFeaturePodHorizontalSidePadding = 28;
-constexpr int kUnifiedFeaturePodHorizontalMiddlePadding = 32;
+constexpr int kUnifiedFeaturePodHorizontalSidePadding = 26;
+constexpr int kUnifiedFeaturePodHorizontalMiddlePadding = 28;
 constexpr int kUnifiedFeaturePodCollapsedVerticalPadding = 16;
 constexpr int kUnifiedFeaturePodCollapsedHorizontalPadding = 24;
 constexpr int kUnifiedFeaturePodItemsInRow = 3;
diff --git a/ash/system/unified/quiet_mode_feature_pod_controller.cc b/ash/system/unified/quiet_mode_feature_pod_controller.cc
index 543175d..03dd346 100644
--- a/ash/system/unified/quiet_mode_feature_pod_controller.cc
+++ b/ash/system/unified/quiet_mode_feature_pod_controller.cc
@@ -5,6 +5,8 @@
 #include "ash/system/unified/quiet_mode_feature_pod_controller.h"
 
 #include "ash/resources/vector_icons/vector_icons.h"
+#include "ash/session/session_controller.h"
+#include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/system/unified/feature_pod_button.h"
 #include "ash/system/unified/unified_system_tray_controller.h"
@@ -28,6 +30,9 @@
 FeaturePodButton* QuietModeFeaturePodController::CreateButton() {
   DCHECK(!button_);
   button_ = new FeaturePodButton(this);
+  button_->SetVisible(
+      Shell::Get()->session_controller()->ShouldShowNotificationTray() &&
+      !Shell::Get()->session_controller()->IsScreenLocked());
   button_->SetLabel(
       l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NOTIFICATIONS_LABEL));
   OnQuietModeChanged(MessageCenter::Get()->IsQuietMode());
diff --git a/ash/system/unified/quiet_mode_feature_pod_controller.h b/ash/system/unified/quiet_mode_feature_pod_controller.h
index 8d21b5d..5fc4f48 100644
--- a/ash/system/unified/quiet_mode_feature_pod_controller.h
+++ b/ash/system/unified/quiet_mode_feature_pod_controller.h
@@ -5,6 +5,7 @@
 #ifndef ASH_SYSTEM_UNIFIED_QUIET_MODE_FEATURE_POD_CONTROLLER_H_
 #define ASH_SYSTEM_UNIFIED_QUIET_MODE_FEATURE_POD_CONTROLLER_H_
 
+#include "ash/ash_export.h"
 #include "ash/system/unified/feature_pod_controller_base.h"
 #include "base/macros.h"
 #include "base/strings/string16.h"
@@ -17,7 +18,7 @@
 // Controller of a feature pod button that toggles do-not-disturb mode.
 // If the do-not-disturb mode is enabled, the button indicates it by bright
 // background color and different icon.
-class QuietModeFeaturePodController
+class ASH_EXPORT QuietModeFeaturePodController
     : public FeaturePodControllerBase,
       public message_center::MessageCenterObserver {
  public:
diff --git a/ash/system/unified/quiet_mode_feature_pod_controller_unittest.cc b/ash/system/unified/quiet_mode_feature_pod_controller_unittest.cc
new file mode 100644
index 0000000..b2c762a
--- /dev/null
+++ b/ash/system/unified/quiet_mode_feature_pod_controller_unittest.cc
@@ -0,0 +1,79 @@
+// 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/unified/quiet_mode_feature_pod_controller.h"
+
+#include "ash/system/unified/feature_pod_button.h"
+#include "ash/system/unified/unified_system_tray_controller.h"
+#include "ash/system/unified/unified_system_tray_model.h"
+#include "ash/test/ash_test_base.h"
+
+namespace ash {
+
+// Tests manually control their session state.
+class QuietModeFeaturePodControllerTest : public NoSessionAshTestBase {
+ public:
+  QuietModeFeaturePodControllerTest() = default;
+  ~QuietModeFeaturePodControllerTest() override = default;
+
+  void SetUp() override {
+    NoSessionAshTestBase::SetUp();
+
+    tray_model_ = std::make_unique<UnifiedSystemTrayModel>();
+    tray_controller_ =
+        std::make_unique<UnifiedSystemTrayController>(tray_model_.get());
+  }
+
+  void TearDown() override {
+    button_.reset();
+    controller_.reset();
+    tray_controller_.reset();
+    tray_model_.reset();
+    NoSessionAshTestBase::TearDown();
+  }
+
+ protected:
+  void SetUpButton() {
+    controller_ =
+        std::make_unique<QuietModeFeaturePodController>(tray_controller());
+    button_.reset(controller_->CreateButton());
+  }
+
+  UnifiedSystemTrayController* tray_controller() {
+    return tray_controller_.get();
+  }
+
+  FeaturePodButton* button() { return button_.get(); }
+
+ private:
+  std::unique_ptr<UnifiedSystemTrayModel> tray_model_;
+  std::unique_ptr<UnifiedSystemTrayController> tray_controller_;
+  std::unique_ptr<QuietModeFeaturePodController> controller_;
+  std::unique_ptr<FeaturePodButton> button_;
+
+  DISALLOW_COPY_AND_ASSIGN(QuietModeFeaturePodControllerTest);
+};
+
+TEST_F(QuietModeFeaturePodControllerTest, ButtonVisibilityNotLoggedIn) {
+  SetUpButton();
+  // If not logged in, it should not be visible.
+  EXPECT_FALSE(button()->visible());
+}
+
+TEST_F(QuietModeFeaturePodControllerTest, ButtonVisibilityLoggedIn) {
+  CreateUserSessions(1);
+  SetUpButton();
+  // If logged in, it should be visible.
+  EXPECT_TRUE(button()->visible());
+}
+
+TEST_F(QuietModeFeaturePodControllerTest, ButtonVisibilityLocked) {
+  CreateUserSessions(1);
+  BlockUserSession(UserSessionBlockReason::BLOCKED_BY_LOCK_SCREEN);
+  SetUpButton();
+  // If locked, it should not be visible.
+  EXPECT_FALSE(button()->visible());
+}
+
+}  // namespace ash
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc
index 080d536..1f50968 100644
--- a/ash/system/unified/unified_system_tray_controller.cc
+++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -132,11 +132,14 @@
 }
 
 void UnifiedSystemTrayController::HandleOpenDateTimeSettingsAction() {
-  if (Shell::Get()->system_tray_model()->clock()->can_set_time()) {
-    Shell::Get()->system_tray_model()->clock()->ShowSetTimeDialog();
-  } else {
-    Shell::Get()->system_tray_model()->clock()->ShowDateSettings();
-  }
+  ClockModel* model = Shell::Get()->system_tray_model()->clock();
+  if (!model->can_set_time())
+    return;
+
+  if (Shell::Get()->session_controller()->ShouldEnableSettings())
+    model->ShowDateSettings();
+  else
+    model->ShowSetTimeDialog();
   CloseBubble();
 }
 
@@ -251,6 +254,8 @@
 }
 
 void UnifiedSystemTrayController::ShowNotifierSettingsView() {
+  DCHECK(Shell::Get()->session_controller()->ShouldShowNotificationTray());
+  DCHECK(!Shell::Get()->session_controller()->IsScreenLocked());
   ShowDetailedView(std::make_unique<UnifiedNotifierSettingsController>(this));
 }
 
diff --git a/ash/system/unified/unified_system_tray_view.cc b/ash/system/unified/unified_system_tray_view.cc
index 87eca1c..a50e3a7 100644
--- a/ash/system/unified/unified_system_tray_view.cc
+++ b/ash/system/unified/unified_system_tray_view.cc
@@ -5,6 +5,8 @@
 #include "ash/system/unified/unified_system_tray_view.h"
 
 #include "ash/public/cpp/app_list/app_list_features.h"
+#include "ash/session/session_controller.h"
+#include "ash/shell.h"
 #include "ash/system/tray/interacted_by_tap_recorder.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/unified/feature_pod_button.h"
@@ -141,6 +143,9 @@
   SetPaintToLayer();
   layer()->SetFillsBoundsOpaquely(false);
 
+  message_center_view_->SetVisible(
+      Shell::Get()->session_controller()->ShouldShowNotificationTray() &&
+      !Shell::Get()->session_controller()->IsScreenLocked());
   AddChildView(message_center_view_);
   layout->SetFlexForView(message_center_view_, 1);
 
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 57b78161..d0a4653 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -2419,6 +2419,7 @@
     "trace_event/memory_allocator_dump_unittest.cc",
     "trace_event/memory_dump_manager_unittest.cc",
     "trace_event/memory_dump_scheduler_unittest.cc",
+    "trace_event/memory_infra_background_whitelist_unittest.cc",
     "trace_event/memory_usage_estimator_unittest.cc",
     "trace_event/process_memory_dump_unittest.cc",
     "trace_event/trace_category_unittest.cc",
diff --git a/base/optional.h b/base/optional.h
index 8b570ccd..f6263b8b 100644
--- a/base/optional.h
+++ b/base/optional.h
@@ -636,7 +636,7 @@
     static_assert(std::is_convertible<U, T>::value,
                   "U must be convertible to T");
     return storage_.is_populated_
-               ? value()
+               ? storage_.value_
                : static_cast<T>(std::forward<U>(default_value));
   }
 
@@ -648,7 +648,7 @@
     static_assert(std::is_convertible<U, T>::value,
                   "U must be convertible to T");
     return storage_.is_populated_
-               ? std::move(value())
+               ? std::move(storage_.value_)
                : static_cast<T>(std::forward<U>(default_value));
   }
 
diff --git a/base/trace_event/memory_infra_background_whitelist_unittest.cc b/base/trace_event/memory_infra_background_whitelist_unittest.cc
new file mode 100644
index 0000000..3037eb1
--- /dev/null
+++ b/base/trace_event/memory_infra_background_whitelist_unittest.cc
@@ -0,0 +1,37 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/trace_event/memory_infra_background_whitelist.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+namespace trace_event {
+
+TEST(MemoryInfraBackgroundWhitelist, Whitelist) {
+  // Global dumps that are of hex digits are all whitelisted for background use.
+  EXPECT_TRUE(IsMemoryAllocatorDumpNameWhitelisted("global/01234ABCDEF"));
+  EXPECT_TRUE(
+      IsMemoryAllocatorDumpNameWhitelisted("shared_memory/01234ABCDEF"));
+
+  // Global dumps that contain non-hex digits are not whitelisted.
+  EXPECT_FALSE(IsMemoryAllocatorDumpNameWhitelisted("global/GHIJK"));
+  EXPECT_FALSE(IsMemoryAllocatorDumpNameWhitelisted("shared_memory/GHIJK"));
+
+  // Test a couple that contain pointer values.
+  EXPECT_TRUE(IsMemoryAllocatorDumpNameWhitelisted("net/url_request_context"));
+  EXPECT_TRUE(IsMemoryAllocatorDumpNameWhitelisted(
+      "net/url_request_context/app_request/0x123/cookie_monster"));
+  EXPECT_TRUE(
+      IsMemoryAllocatorDumpNameWhitelisted("net/http_network_session_0x123"));
+  EXPECT_FALSE(
+      IsMemoryAllocatorDumpNameWhitelisted("net/http_network_session/0x123"));
+  EXPECT_TRUE(IsMemoryAllocatorDumpNameWhitelisted(
+      "net/http_network_session_0x123/quic_stream_factory"));
+}
+
+}  // namespace trace_event
+
+}  // namespace base
diff --git a/base/trace_event/process_memory_dump.cc b/base/trace_event/process_memory_dump.cc
index cebe528..362641c 100644
--- a/base/trace_event/process_memory_dump.cc
+++ b/base/trace_event/process_memory_dump.cc
@@ -272,8 +272,6 @@
   auto it = allocator_dumps_.find(absolute_name);
   if (it != allocator_dumps_.end())
     return it->second.get();
-  if (black_hole_mad_)
-    return black_hole_mad_.get();
   return nullptr;
 }
 
diff --git a/base/trace_event/process_memory_dump_unittest.cc b/base/trace_event/process_memory_dump_unittest.cc
index 72efad9..d5f771d 100644
--- a/base/trace_event/process_memory_dump_unittest.cc
+++ b/base/trace_event/process_memory_dump_unittest.cc
@@ -386,6 +386,10 @@
   SetAllocatorDumpNameWhitelistForTesting(kTestDumpNameWhitelist);
   MemoryAllocatorDump* black_hole_mad = pmd->GetBlackHoleMad();
 
+  // GetAllocatorDump works for uncreated dumps.
+  EXPECT_EQ(nullptr, pmd->GetAllocatorDump("NotWhitelisted/TestName"));
+  EXPECT_EQ(nullptr, pmd->GetAllocatorDump("Whitelisted/TestName"));
+
   // Invalid dump names.
   EXPECT_EQ(black_hole_mad,
             pmd->CreateAllocatorDump("NotWhitelisted/TestName"));
@@ -419,7 +423,7 @@
             pmd->CreateAllocatorDump("Whitelisted/0xaB/TestName"));
 
   // GetAllocatorDump is consistent.
-  EXPECT_EQ(black_hole_mad, pmd->GetAllocatorDump("NotWhitelisted/TestName"));
+  EXPECT_EQ(nullptr, pmd->GetAllocatorDump("NotWhitelisted/TestName"));
   EXPECT_NE(black_hole_mad, pmd->GetAllocatorDump("Whitelisted/TestName"));
 
   // Test whitelisted entries.
diff --git a/build/android/gyp/bundletool.py b/build/android/gyp/bundletool.py
new file mode 100755
index 0000000..1bd5c36
--- /dev/null
+++ b/build/android/gyp/bundletool.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+# 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.
+
+"""Simple wrapper around the bundletool tool.
+
+Bundletool is distributed as a versioned jar file. This script abstracts the
+location and version of this jar file, as well as the JVM invokation."""
+
+import os
+import subprocess
+import sys
+
+# Assume this is stored under build/android/gyp/
+BUNDLETOOL_DIR = os.path.abspath(os.path.join(
+    sys.argv[0], '..', '..', '..', '..', 'third_party', 'android_build_tools',
+    'bundletool'))
+
+BUNDLETOOL_VERSION = '0.4.2'
+
+BUNDLETOOL_JAR_PATH = os.path.join(
+    BUNDLETOOL_DIR, 'bundletool-all-%s.jar' % BUNDLETOOL_VERSION)
+
+args = ['java', '-jar', BUNDLETOOL_JAR_PATH] + sys.argv[1:]
+subprocess.check_call(args)
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 667f1e3..c498000 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -16,6 +16,7 @@
 #include "base/auto_reset.h"
 #include "base/bind.h"
 #include "base/command_line.h"
+#include "base/json/json_writer.h"
 #include "base/location.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
@@ -789,6 +790,17 @@
     draw_property_utils::UpdatePropertyTrees(this, property_trees);
     draw_property_utils::FindLayersThatNeedUpdates(this, property_trees,
                                                    &update_layer_list);
+
+    // Dump property trees useful for debugging --blink-gen-property-trees
+    // flag. We care only about the renderer compositor.
+    if (VLOG_IS_ON(3) && GetClientNameForMetrics() == std::string("Renderer")) {
+      VLOG(3) << "CC Property Trees:";
+      std::string out;
+      base::JSONWriter::WriteWithOptions(
+          *property_trees->AsTracedValue()->ToBaseValue(),
+          base::JSONWriter::OPTIONS_PRETTY_PRINT, &out);
+      VLOG(3) << out;
+    }
   }
 
   bool painted_content_has_slow_paths = false;
diff --git a/chrome/VERSION b/chrome/VERSION
index 1266901..e7349d3 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=69
 MINOR=0
-BUILD=3469
+BUILD=3470
 PATCH=0
diff --git a/chrome/android/java/res/xml/sync_and_services_preferences.xml b/chrome/android/java/res/xml/sync_and_services_preferences.xml
new file mode 100644
index 0000000..b0e6615
--- /dev/null
+++ b/chrome/android/java/res/xml/sync_and_services_preferences.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-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. -->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+    <org.chromium.chrome.browser.preferences.ChromeSwitchPreference
+        android:persistent="false"
+        android:key="use_sync_and_all_services"
+        android:title="@string/use_sync_and_all_services"/>
+
+    <Preference
+        android:key="sign_out_divider"
+        android:layout="@layout/divider_preference"/>
+    <org.chromium.chrome.browser.preferences.SigninExpandablePreferenceGroup
+        android:persistent="false"
+        android:key="sync_and_personalization"
+        android:title="@string/sync_and_personalization_title"
+        android:summary="@string/sync_and_personalization_summary"/>
+
+    <Preference
+        android:layout="@layout/divider_preference"/>
+
+    <org.chromium.chrome.browser.preferences.SigninExpandablePreferenceGroup
+        android:key="nonpersonalized_services"
+        android:title="@string/prefs_nonpersonalized_services_section_title"
+        android:summary="@string/prefs_nonpersonalized_services_section_summary">
+
+        <org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference
+            android:key="navigation_error"
+            android:title="@string/navigation_error_title"
+            android:summary="@string/navigation_error_summary"
+            android:defaultValue="true"/>
+        <org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference
+            android:key="search_suggestions"
+            android:title="@string/search_suggestions_title"
+            android:summary="@string/search_suggestions_summary"
+            android:defaultValue="true"/>
+        <org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference
+            android:key="safe_browsing_extended_reporting"
+            android:title="@string/safe_browsing_extended_reporting_title"
+            android:summary="@string/safe_browsing_extended_reporting_summary"/>
+        <org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference
+            android:key="safe_browsing_scout_reporting"
+            android:title="@string/safe_browsing_scout_reporting_title"
+            android:summary="@string/safe_browsing_scout_reporting_summary"/>
+        <org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference
+            android:key="safe_browsing"
+            android:title="@string/safe_browsing_title"
+            android:summary="@string/safe_browsing_summary"/>
+        <org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference
+            android:key="network_predictions"
+            android:title="@string/network_predictions_title"
+            android:summary="@string/network_predictions_summary"
+            android:persistent="false"/>
+        <org.chromium.chrome.browser.preferences.ChromeBasePreference
+            android:key="usage_and_crash_reports"
+            android:title="@string/usage_and_crash_reports_title"
+            android:fragment="org.chromium.chrome.browser.preferences.privacy.UsageAndCrashReportsPreferenceFragment"/>
+        <org.chromium.chrome.browser.preferences.ChromeBasePreference
+            android:key="contextual_search"
+            android:title="@string/contextual_search_title"
+            android:fragment="org.chromium.chrome.browser.preferences.privacy.ContextualSearchPreferenceFragment"/>
+    </org.chromium.chrome.browser.preferences.SigninExpandablePreferenceGroup>
+
+    <Preference
+        android:layout="@layout/divider_preference"/>
+</PreferenceScreen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/PasswordGenerationPopupBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/PasswordGenerationPopupBridge.java
index 52ab9f1..be516ae 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/PasswordGenerationPopupBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/PasswordGenerationPopupBridge.java
@@ -10,20 +10,12 @@
 import android.widget.AdapterView;
 import android.widget.PopupWindow;
 
-import org.chromium.base.Callback;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeActivity;
-import org.chromium.chrome.browser.ChromeFeatureList;
-import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryCoordinator;
-import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData;
-import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Action;
 import org.chromium.ui.DropdownPopupWindow;
 import org.chromium.ui.base.WindowAndroid;
 
-import javax.annotation.Nullable;
-
 /**
  * JNI call glue for password generation between native and Java objects.
  */
@@ -35,11 +27,6 @@
     private final Context mContext;
     private final DropdownPopupWindow mPopup;
     private final View mAnchorView;
-    private final KeyboardAccessoryData.PropertyProvider<Action> mActionProvider =
-            new KeyboardAccessoryData.PropertyProvider<>();
-    private @Nullable Action mKeyboardAccessoryAction;
-    private final @Nullable KeyboardAccessoryCoordinator mKeyboardAccessory;
-
     /**
      * A convenience method for the constructor to be invoked from the native counterpart.
      * @param anchorView View anchored for popup.
@@ -66,17 +53,10 @@
         // mContext could've been garbage collected.
         if (mContext == null) {
             mPopup = null;
-            mKeyboardAccessory = null;
             // Prevent destroying the native counterpart when it's about to derefence its own
             // members in UpdateBoundsAndRedrawPopup().
             new Handler().post(this::onDismiss);
         } else {
-            if (mContext instanceof ChromeActivity) {
-                mKeyboardAccessory = ((ChromeActivity) mContext).getKeyboardAccessory();
-                mKeyboardAccessory.registerActionListProvider(mActionProvider);
-            } else {
-                mKeyboardAccessory = null;
-            }
             mPopup = new DropdownPopupWindow(mContext, anchorView);
             mPopup.setOnItemClickListener(this);
             mPopup.setOnDismissListener(this);
@@ -130,13 +110,6 @@
             String suggestionTitle, String explanationText, int explanationTextLinkRangeStart,
             int explanationTextLinkRangeEnd) {
         if (mPopup != null) {
-            // If an action can be shown in the popup, provide the same in the accessory or sheet.
-            if (providesGenerationAction() && mKeyboardAccessoryAction == null) {
-                // TODO(ioanap): Move these lines to a new native call or even a separate bridge.
-                createGeneratePasswordAction(suggestionTitle, this::onActionTriggered);
-                mActionProvider.notifyObservers(new Action[] {mKeyboardAccessoryAction});
-                // Don't return for now. We want to have both mechanisms in place initially.
-            }
             float anchorWidth = mAnchorView.getLayoutParams().width;
             assert anchorWidth > 0;
             PasswordGenerationAdapter adapter = new PasswordGenerationAdapter(mContext, this,
@@ -166,22 +139,4 @@
     private void hide() {
         if (mPopup != null) mPopup.dismiss();
     }
-
-    private void onActionTriggered(Action action) {
-        assert action == mKeyboardAccessoryAction;
-        nativePasswordSelected(mNativePasswordGenerationPopupViewAndroid);
-        // TODO(ioanap): Create and use this call instead to start the ModalDialog flow:
-        // nativePasswordGenerationRequested(mNativePasswordGenerationPopupViewAndroid);
-    }
-
-    private boolean providesGenerationAction() {
-        return mKeyboardAccessory != null && ChromeFeatureList.isInitialized()
-                && (ChromeFeatureList.isEnabled(ChromeFeatureList.PASSWORDS_KEYBOARD_ACCESSORY)
-                           || ChromeFeatureList.isEnabled(ChromeFeatureList.EXPERIMENTAL_UI));
-    }
-
-    private void createGeneratePasswordAction(String caption, Callback<Action> delegate) {
-        assert mKeyboardAccessoryAction == null : "Accessory Action should only be created once!";
-        mKeyboardAccessoryAction = new Action(caption, delegate);
-    }
-}
+}
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessoryBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessoryBridge.java
index c646fe0..e3dae4c1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessoryBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessoryBridge.java
@@ -46,12 +46,12 @@
             items[i] = new Item(type[i], text[i], description[i], isPassword[i] == 1, (item) -> {
                 assert mNativeView
                         != 0 : "Controller has been destroyed but the bridge wasn't cleaned up!";
-                nativeOnFillingTriggered(mNativeView, item.getCaption());
+                nativeOnFillingTriggered(mNativeView, item.isPassword(), item.getCaption());
             });
         }
         return items;
     }
 
     private native void nativeOnFillingTriggered(
-            long nativePasswordAccessoryViewAndroid, String textToFill);
+            long nativePasswordAccessoryViewAndroid, boolean isPassword, String textToFill);
 }
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SigninExpandablePreferenceGroup.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SigninExpandablePreferenceGroup.java
new file mode 100644
index 0000000..9ec3fe7
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SigninExpandablePreferenceGroup.java
@@ -0,0 +1,67 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.preferences;
+
+import android.content.Context;
+import android.preference.Preference;
+import android.util.AttributeSet;
+
+import org.chromium.base.ThreadUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An expandable preference group that subclasses {@link ExpandablePreferenceGroup} to hide/reveal
+ * child preferences on clicks.
+ */
+public class SigninExpandablePreferenceGroup extends ExpandablePreferenceGroup {
+    private final List<Preference> mAllPreferences = new ArrayList<>();
+
+    public SigninExpandablePreferenceGroup(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onClick() {
+        super.onClick();
+        ThreadUtils.postOnUiThread(() -> setExpanded(!isExpanded()));
+    }
+
+    @Override
+    public boolean addPreference(Preference preference) {
+        mAllPreferences.add(preference);
+        if (!isExpanded()) return true;
+        return addPreferenceInternal(preference);
+    }
+
+    @Override
+    public boolean removePreference(Preference preference) {
+        if (!mAllPreferences.remove(preference)) return false;
+        if (!isExpanded()) return true;
+        return removePreferenceInternal(preference);
+    }
+
+    @Override
+    protected void onExpandedChanged(boolean expanded) {
+        if (expanded) {
+            for (Preference preference : mAllPreferences) {
+                addPreferenceInternal(preference);
+            }
+        } else {
+            for (Preference preference : mAllPreferences) {
+                removePreferenceInternal(preference);
+            }
+        }
+    }
+
+    private boolean addPreferenceInternal(Preference preference) {
+        return super.addPreference(preference);
+    }
+
+    private boolean removePreferenceInternal(Preference preference) {
+        return super.removePreference(preference);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java
index 5d02611..5f509235 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java
@@ -5,22 +5,231 @@
 package org.chromium.chrome.browser.preferences;
 
 import android.os.Bundle;
+import android.preference.Preference;
 import android.preference.PreferenceFragment;
+import android.preference.PreferenceGroup;
 import android.support.annotation.Nullable;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.ListView;
 
+import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.chrome.browser.contextualsearch.ContextualSearchFieldTrial;
+import org.chromium.chrome.browser.help.HelpAndFeedback;
+import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager;
+import org.chromium.chrome.browser.profiles.Profile;
 
 /**
  * Settings fragment to customize Sync options (data types, encryption) and other services that
  * communicate with Google.
  */
-public class SyncAndServicesPreferences extends PreferenceFragment {
+public class SyncAndServicesPreferences
+        extends PreferenceFragment implements Preference.OnPreferenceChangeListener {
+    private static final String USE_SYNC_AND_ALL_SERVICES = "use_sync_and_all_services";
+    private static final String SYNC_AND_PERSONALIZATION = "sync_and_personalization";
+    private static final String NONPERSONALIZED_SERVICES = "nonpersonalized_services";
+    private static final String PREF_NAVIGATION_ERROR = "navigation_error";
+    private static final String PREF_SEARCH_SUGGESTIONS = "search_suggestions";
+    private static final String PREF_SAFE_BROWSING_EXTENDED_REPORTING =
+            "safe_browsing_extended_reporting";
+    private static final String PREF_SAFE_BROWSING_SCOUT_REPORTING =
+            "safe_browsing_scout_reporting";
+    private static final String PREF_SAFE_BROWSING = "safe_browsing";
+    private static final String PREF_CONTEXTUAL_SEARCH = "contextual_search";
+    private static final String PREF_NETWORK_PREDICTIONS = "network_predictions";
+    private static final String PREF_USAGE_AND_CRASH_REPORTING = "usage_and_crash_reports";
+
+    private final PrefServiceBridge mPrefServiceBridge = PrefServiceBridge.getInstance();
+    private final PrivacyPreferencesManager mPrivacyPrefManager =
+            PrivacyPreferencesManager.getInstance();
+    private final ManagedPreferenceDelegate mManagedPreferenceDelegate =
+            createManagedPreferenceDelegate();
+
+    private ChromeSwitchPreference mUseSyncAndAllServices;
+    private SigninExpandablePreferenceGroup mSyncGroup;
+
+    private SigninExpandablePreferenceGroup mNonpersonalizedServices;
+    private ChromeBaseCheckBoxPreference mNavigationError;
+    private ChromeBaseCheckBoxPreference mNetworkPredictions;
+    private ChromeBaseCheckBoxPreference mSearchSuggestions;
+    private Preference mContextualSearch;
+    private ChromeBaseCheckBoxPreference mSafeBrowsingReporting;
+    private ChromeBaseCheckBoxPreference mSafeBrowsing;
+    private Preference mUsageAndCrashReporting;
+
     @Override
     public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        getActivity().setTitle(R.string.prefs_sync_and_services);
+        mPrivacyPrefManager.migrateNetworkPredictionPreferences();
 
-        // TODO(https://crbug.com/814728): Add UnifiedConsent preferences here.
+        getActivity().setTitle(R.string.prefs_sync_and_services);
+        setHasOptionsMenu(true);
+
+        PreferenceUtils.addPreferencesFromResource(this, R.xml.sync_and_services_preferences);
+
+        mUseSyncAndAllServices = (ChromeSwitchPreference) findPreference(USE_SYNC_AND_ALL_SERVICES);
+        mSyncGroup = (SigninExpandablePreferenceGroup) findPreference(SYNC_AND_PERSONALIZATION);
+        mNonpersonalizedServices =
+                (SigninExpandablePreferenceGroup) findPreference(NONPERSONALIZED_SERVICES);
+        mUseSyncAndAllServices.setOnPreferenceClickListener(preference -> {
+            if (!mUseSyncAndAllServices.isChecked()) {
+                mSyncGroup.setExpanded(true);
+                mNonpersonalizedServices.setExpanded(true);
+            }
+            return false;
+        });
+
+        mNetworkPredictions =
+                (ChromeBaseCheckBoxPreference) findPreference(PREF_NETWORK_PREDICTIONS);
+        mNetworkPredictions.setOnPreferenceChangeListener(this);
+        mNetworkPredictions.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
+
+        mNavigationError = (ChromeBaseCheckBoxPreference) findPreference(PREF_NAVIGATION_ERROR);
+        mNavigationError.setOnPreferenceChangeListener(this);
+        mNavigationError.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
+
+        mSearchSuggestions = (ChromeBaseCheckBoxPreference) findPreference(PREF_SEARCH_SUGGESTIONS);
+        mSearchSuggestions.setOnPreferenceChangeListener(this);
+        mSearchSuggestions.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
+        if (ChromeFeatureList.isEnabled(ChromeFeatureList.CONTENT_SUGGESTIONS_SETTINGS)) {
+            mSearchSuggestions.setTitle(R.string.search_site_suggestions_title);
+            mSearchSuggestions.setSummary(R.string.search_site_suggestions_summary);
+        }
+
+        mContextualSearch = findPreference(PREF_CONTEXTUAL_SEARCH);
+        if (!ContextualSearchFieldTrial.isEnabled()) {
+            removePreference(mNonpersonalizedServices, mContextualSearch);
+            mContextualSearch = null;
+        }
+
+        Preference extendedReporting = findPreference(PREF_SAFE_BROWSING_EXTENDED_REPORTING);
+        Preference scoutReporting = findPreference(PREF_SAFE_BROWSING_SCOUT_REPORTING);
+        // Remove the extended reporting preference that is NOT active.
+        if (mPrefServiceBridge.isSafeBrowsingScoutReportingActive()) {
+            removePreference(mNonpersonalizedServices, extendedReporting);
+            mSafeBrowsingReporting = (ChromeBaseCheckBoxPreference) scoutReporting;
+        } else {
+            removePreference(mNonpersonalizedServices, scoutReporting);
+            mSafeBrowsingReporting = (ChromeBaseCheckBoxPreference) extendedReporting;
+        }
+        mSafeBrowsingReporting.setOnPreferenceChangeListener(this);
+        mSafeBrowsingReporting.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
+
+        mSafeBrowsing = (ChromeBaseCheckBoxPreference) findPreference(PREF_SAFE_BROWSING);
+        mSafeBrowsing.setOnPreferenceChangeListener(this);
+        mSafeBrowsing.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
+
+        mUsageAndCrashReporting = findPreference(PREF_USAGE_AND_CRASH_REPORTING);
+
+        updatePreferences();
+    }
+
+    @Override
+    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        ListView list = (ListView) getView().findViewById(android.R.id.list);
+        list.setDivider(null);
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        menu.clear();
+        MenuItem help =
+                menu.add(Menu.NONE, R.id.menu_id_targeted_help, Menu.NONE, R.string.menu_help);
+        help.setIcon(R.drawable.ic_help_and_feedback);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (item.getItemId() == R.id.menu_id_targeted_help) {
+            HelpAndFeedback.getInstance(getActivity())
+                    .show(getActivity(), getString(R.string.help_context_privacy),
+                            Profile.getLastUsedProfile(), null);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        String key = preference.getKey();
+        if (PREF_SEARCH_SUGGESTIONS.equals(key)) {
+            PrefServiceBridge.getInstance().setSearchSuggestEnabled((boolean) newValue);
+        } else if (PREF_SAFE_BROWSING.equals(key)) {
+            PrefServiceBridge.getInstance().setSafeBrowsingEnabled((boolean) newValue);
+        } else if (PREF_SAFE_BROWSING_EXTENDED_REPORTING.equals(key)
+                || PREF_SAFE_BROWSING_SCOUT_REPORTING.equals(key)) {
+            PrefServiceBridge.getInstance().setSafeBrowsingExtendedReportingEnabled(
+                    (boolean) newValue);
+        } else if (PREF_NETWORK_PREDICTIONS.equals(key)) {
+            PrefServiceBridge.getInstance().setNetworkPredictionEnabled((boolean) newValue);
+            recordNetworkPredictionEnablingUMA((boolean) newValue);
+        } else if (PREF_NAVIGATION_ERROR.equals(key)) {
+            PrefServiceBridge.getInstance().setResolveNavigationErrorEnabled((boolean) newValue);
+        }
+
+        return true;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        updatePreferences();
+    }
+
+    private void recordNetworkPredictionEnablingUMA(boolean enabled) {
+        // Report user turning on and off NetworkPrediction.
+        RecordHistogram.recordBooleanHistogram("PrefService.NetworkPredictionEnabled", enabled);
+    }
+
+    private static void removePreference(PreferenceGroup from, Preference preference) {
+        boolean found = from.removePreference(preference);
+        assert found : "Don't have such preference! Preference key: " + preference.getKey();
+    }
+
+    private void updatePreferences() {
+        mNavigationError.setChecked(mPrefServiceBridge.isResolveNavigationErrorEnabled());
+        mNetworkPredictions.setChecked(mPrefServiceBridge.getNetworkPredictionEnabled());
+        mSearchSuggestions.setChecked(mPrefServiceBridge.isSearchSuggestEnabled());
+        mSafeBrowsing.setChecked(mPrefServiceBridge.isSafeBrowsingEnabled());
+        mSafeBrowsingReporting.setChecked(
+                mPrefServiceBridge.isSafeBrowsingExtendedReportingEnabled());
+
+        CharSequence textOn = getActivity().getResources().getText(R.string.text_on);
+        CharSequence textOff = getActivity().getResources().getText(R.string.text_off);
+        if (mContextualSearch != null) {
+            boolean isContextualSearchEnabled = !mPrefServiceBridge.isContextualSearchDisabled();
+            mContextualSearch.setSummary(isContextualSearchEnabled ? textOn : textOff);
+        }
+        mUsageAndCrashReporting.setSummary(
+                mPrivacyPrefManager.isUsageAndCrashReportingPermittedByUser() ? textOn : textOff);
+    }
+
+    private ManagedPreferenceDelegate createManagedPreferenceDelegate() {
+        return preference -> {
+            String key = preference.getKey();
+            if (PREF_NAVIGATION_ERROR.equals(key)) {
+                return mPrefServiceBridge.isResolveNavigationErrorManaged();
+            }
+            if (PREF_SEARCH_SUGGESTIONS.equals(key)) {
+                return mPrefServiceBridge.isSearchSuggestManaged();
+            }
+            if (PREF_SAFE_BROWSING_EXTENDED_REPORTING.equals(key)
+                    || PREF_SAFE_BROWSING_SCOUT_REPORTING.equals(key)) {
+                return mPrefServiceBridge.isSafeBrowsingExtendedReportingManaged();
+            }
+            if (PREF_SAFE_BROWSING.equals(key)) {
+                return mPrefServiceBridge.isSafeBrowsingManaged();
+            }
+            if (PREF_NETWORK_PREDICTIONS.equals(key)) {
+                return mPrefServiceBridge.isNetworkPredictionManaged();
+            }
+            return false;
+        };
     }
 }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index 72c9385..adae64a 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -309,6 +309,22 @@
       <message name="IDS_SIGN_IN_SYNC_ERROR_WIDGET" desc="Accessibility description of the sync error widget in settings screen">
         Sync error occurred, tap to get details.
       </message>
+      <!-- Unified consent preferences -->
+      <message name="IDS_USE_SYNC_AND_ALL_SERVICES" desc="Title for switch preference which enables sync'ing of all data types and turns on all Chrome services that communicate with Google.">
+        Use sync and all services
+      </message>
+      <message name="IDS_SYNC_AND_PERSONALIZATION_TITLE" desc="Title for the expandable group of Sync-related entries in Settings. This group contains preferences for data tied to user's Google Account.">
+        Sync and personalization
+      </message>
+      <message name="IDS_SYNC_AND_PERSONALIZATION_SUMMARY" desc="Summary for the expandable group of Sync-related entries in Settings. This group contains preferences for data tied to user's Google Account.">
+        Your browsing data and activity, synced to your Google Account
+      </message>
+      <message name="IDS_PREFS_NONPERSONALIZED_SERVICES_SECTION_TITLE" desc="Title for the expandable group of preferences that control non-personalized Google services. This group contains preferences for data that is not tied to user's Google Account.">
+        Non-personalized services
+      </message>
+      <message name="IDS_PREFS_NONPERSONALIZED_SERVICES_SECTION_SUMMARY" desc="Summary for the expandable group of preferences that control non-personalized Google services. This group contains preferences for data that is not tied to user's Google Account.">
+        Communicates with Google to improve browsing and Chrome
+      </message>
 
       <!-- Search engine preferences -->
       <message name="IDS_PREFS_SEARCH_ENGINE" desc="Title for Search Engine preferences. [CHAR-LIMIT=32]">
@@ -3253,7 +3269,7 @@
         Establishing a tunnel via proxy server failed
       </message>
       <message name="IDS_TWA_RUNNING_IN_CHROME" desc="Disclosure on opening a TWA that it may use Chrome data. Shown on a Toast." translateable="false">
-        Running in Chrome.
+        Running in Chrome
       </message>
 
       <!-- Keyboard shortcuts in Android N-->
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index ccb0de3..e7789a8 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1066,6 +1066,7 @@
   "java/src/org/chromium/chrome/browser/preferences/SearchEnginePreference.java",
   "java/src/org/chromium/chrome/browser/preferences/SeekBarLinkedCheckBoxPreference.java",
   "java/src/org/chromium/chrome/browser/preferences/SeekBarPreference.java",
+  "java/src/org/chromium/chrome/browser/preferences/SigninExpandablePreferenceGroup.java",
   "java/src/org/chromium/chrome/browser/preferences/SignInPreference.java",
   "java/src/org/chromium/chrome/browser/preferences/SpinnerPreference.java",
   "java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java
index 4a10398..7d6b0bb 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java
@@ -28,6 +28,7 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.FlakyTest;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
@@ -158,6 +159,7 @@
 
     @Test
     @MediumTest
+    @FlakyTest(message = "crbug.com/855168")
     public void testSpaceDisplay() throws Exception {
         // This first check is a Criteria because initialization of the Adapter is asynchronous.
         CriteriaHelper.pollUiThread(new Criteria() {
@@ -251,6 +253,7 @@
     @Test
     @MediumTest
     @RetryOnFailure
+    @FlakyTest(message = "crbug.com/854241")
     public void testDeleteFiles() throws Exception {
         SnackbarManager.setDurationForTesting(1);
 
@@ -290,6 +293,7 @@
     @Test
     @MediumTest
     @RetryOnFailure
+    @FlakyTest(message = "crbug.com/855219")
     public void testDeleteFileFromMenu() throws Exception {
         SnackbarManager.setDurationForTesting(1);
 
@@ -521,6 +525,7 @@
     @Test
     @MediumTest
     @DisableFeatures("OfflinePagesSharing")
+    @FlakyTest(message = "crbug.com/855167")
     public void testShareFiles() throws Exception {
         // Adapter positions:
         // 0 = space display
diff --git a/chrome/android/monochrome/BUILD.gn b/chrome/android/monochrome/BUILD.gn
index 940f5d30..d403444f1d 100644
--- a/chrome/android/monochrome/BUILD.gn
+++ b/chrome/android/monochrome/BUILD.gn
@@ -29,6 +29,7 @@
 
   data = [
     "./scripts/monochrome_apk_checker.py",
-    "./scripts/monochrome_apk_checker_wrapper.py",
+    "//testing/scripts/monochrome_apk_checker_wrapper.py",
+    "//testing/scripts/common.py",
   ]
 }
diff --git a/chrome/android/monochrome/scripts/monochrome_apk_checker_wrapper.py b/chrome/android/monochrome/scripts/monochrome_apk_checker_wrapper.py
deleted file mode 100755
index eee7d2c..0000000
--- a/chrome/android/monochrome/scripts/monochrome_apk_checker_wrapper.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python2.7
-#
-# 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.
-
-# This is just a wrapper script around monochrome_apk_checker.py that
-# understands and uses the isolated-script arguments
-
-import argparse
-import json
-import sys
-import subprocess
-import time
-
-def main():
-  parser = argparse.ArgumentParser(prog='monochrome_apk_checker_wrapper')
-
-  parser.add_argument('--script',
-                      required=True,
-                      help='The path to the monochrome_apk_checker.py script')
-  parser.add_argument('--isolated-script-test-output',
-                      required=True)
-  # ignored, but required to satisfy the isolated_script interface.
-  parser.add_argument('--isolated-script-test-perf-output')
-  args, extra = parser.parse_known_args(sys.argv[1:])
-
-  cmd = [args.script] + extra
-
-  start_time = time.time()
-  ret = subprocess.call(cmd)
-  success = ret == 0
-
-  # Schema is at //docs/testing/json_test_results_format.md
-  with open(args.isolated_script_test_output, 'w') as fp:
-    json.dump({
-      'version': 3,
-      'interrupted': False,
-      'path_delimiter': '/',
-      'seconds_since_epoch': start_time,
-      'num_failures_by_type': {
-        'PASS': int(success),
-        'FAIL': int(not success),
-      },
-      'tests': {
-        'monochrome_apk_checker': {
-          'expected': 'PASS',
-          'actual': 'PASS' if success else 'FAIL',
-        }
-      }
-    }, fp)
-
-  return ret
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index b912837..81da29d9 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -170,9 +170,12 @@
   </message>
 
   <!-- File Manager -->
-  <message name="IDS_FILE_BROWSER_ANDROID_FILES_ROOT_LABEL" desc="A label for the 'Play Files' root which shows Android files.">
+  <message name="IDS_FILE_BROWSER_ANDROID_FILES_ROOT_LABEL" desc="A label for the 'Play Files' root which shows Android files. 'Play' in this label is an abbreviation of 'Google Play', so it should not be translated.">
     Play Files
   </message>
+  <message name="IDS_FILE_BROWSER_SHOW_ALL_ANDROID_FOLDERS_OPTION" desc="A label for an option menu item to show all Android folders. By default, only several folders are visible to users, and users will click this option menu item to show all folders. 'Play' in this label is an abbreviation of 'Google Play', so it should not be translated.">
+    Show all Play folders
+  </message>
   <message name="IDS_FILE_SYSTEM_PROVIDER_UNRESPONSIVE_WARNING" desc="A warning shown in a notification that an operation is taking longer than expected.">
     An operation is taking longer than expected. Do you want to abort it?
   </message>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_FILE_BROWSER_SHOW_ALL_ANDROID_FOLDERS_OPTION.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_FILE_BROWSER_SHOW_ALL_ANDROID_FOLDERS_OPTION.png.sha1
new file mode 100644
index 0000000..ed350982
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_FILE_BROWSER_SHOW_ALL_ANDROID_FOLDERS_OPTION.png.sha1
@@ -0,0 +1 @@
+0e88afa3756ce55542754a8801cf3d445bfc29a9
\ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index d19c0ff4..cc88bca 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -4345,6 +4345,9 @@
       <message name="IDS_PASSWORD_GENERATION_SUGGESTION" desc="Text shown next to a generated password describing it as a suggestion.">
         Use suggested password
       </message>
+       <message name="IDS_PASSWORD_GENERATION_EDITING_SUGGESTION" desc="Notification text next to the generated password assuring the user that the password has been saved.">
+        Saved password
+      </message>
       <message name="IDS_SAVE_PASSWORD" desc="The title of the save password bubble when a password can be saved.">
         Do you want <ph name="PASSWORD_MANAGER_BRAND">$1<ex>Google Chrome</ex></ph> to save your password for this site?
       </message>
@@ -4891,7 +4894,7 @@
         Select a Google Photo Album
       </message>
       <message name="IDS_NTP_CUSTOM_BG_DAILY_REFRESH" desc="The text label for the daily background randomization option.  (On the New Tab Page)">
-        Daily refresh
+        Refresh daily
       </message>
       <message name="IDS_NTP_CUSTOM_BG_SURPRISE_ME" desc="The text label for the random background option. (On the New Tab Page)">
         Surprise me
@@ -4899,6 +4902,27 @@
       <message name="IDS_NTP_CUSTOM_BG_RESTORE_DEFAULT" desc="The text label for the restore default option for background customization. (On the New Tab Page)">
         Restore default background
       </message>
+      <message name="IDS_NTP_CUSTOM_BG_CANCEL" desc="The text label for the cancel option for background customization. (On the New Tab Page)">
+        Cancel
+      </message>
+      <message name="IDS_NTP_CONNECTION_ERROR_NO_PERIOD" desc="Error message for when a connection cannot be established. (On the New Tab Page)">
+        Connection error
+      </message>
+      <message name="IDS_NTP_CONNECTION_ERROR" desc="Error message for when a connection cannot be established. (On the New Tab Page)">
+        Connection error.
+      </message>
+      <message name="IDS_NTP_ERROR_MORE_INFO" desc="Link to more detailed information when a connection cannot be established. (On the New Tab Page)">
+        More info
+      </message>
+      <message name="IDS_NTP_CUSTOM_BG_BACKGROUNDS_UNAVAILABLE" desc="Error message for when background customization is not available. (On the New Tab Page)">
+        Backgrounds are unavailable. Try again later.
+      </message>
+      <message name="IDS_NTP_CUSTOM_BG_IMAGE_UNAVAILABLE" desc="Error message for when the selected background image is not available. (On the New Tab Page)">
+        Image is unavailable. Try again later.
+      </message>
+      <message name="IDS_NTP_CUSTOM_BG_IMAGE_NOT_USABLE" desc="Error message for when an uploaded image is not usuable as a custom background. (On the New Tab Page)">
+        This image can't be used. Choose a different image.
+      </message>
 
       <!--Tooltip strings-->
       <message name="IDS_TOOLTIP_BACK" desc="The tooltip for back button">
@@ -5268,10 +5292,13 @@
           Password for <ph name="username">$1<ex>Alexander</ex></ph>
         </message>
         <message name="IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_EMPTY_MESSAGE" desc="Message indicating that the list of saved passwords for this site is empty.">
-          No saved passwords for this site.
+          No saved passwords for <ph name="domain">$1<ex>example.com</ex></ph>
         </message>
         <message name="IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_TITLE" desc="The title of a list of saved passwords for the currently visible site.">
-          Passwords
+          Saved passwords for <ph name="domain">$1<ex>example.com</ex></ph>
+        </message>
+        <message name="IDS_PASSWORD_MANAGER_ACCESSORY_ALL_PASSWORDS_LINK" desc="The text of the link in the password sheet that opens the password management section.">
+          Manage passwords...
         </message>
       </if>
 
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_CONNECTION_ERROR.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_CONNECTION_ERROR.png.sha1
new file mode 100644
index 0000000..53c06581
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_CONNECTION_ERROR.png.sha1
@@ -0,0 +1 @@
+9f9debb77d3d9d1a3c4efa7987ca86a11ec1b770
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_CONNECTION_ERROR_NO_PERIOD.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_CONNECTION_ERROR_NO_PERIOD.png.sha1
new file mode 100644
index 0000000..53c06581
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_CONNECTION_ERROR_NO_PERIOD.png.sha1
@@ -0,0 +1 @@
+9f9debb77d3d9d1a3c4efa7987ca86a11ec1b770
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_BACKGROUNDS_UNAVAILABLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_BACKGROUNDS_UNAVAILABLE.png.sha1
new file mode 100644
index 0000000..5016b1f
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_BACKGROUNDS_UNAVAILABLE.png.sha1
@@ -0,0 +1 @@
+3ec1335904c0ca540498d20802f84019996a7632
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_CANCEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_CANCEL.png.sha1
new file mode 100644
index 0000000..e90b391
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_CANCEL.png.sha1
@@ -0,0 +1 @@
+4a07423b8d67a8c64a09924d1c051f67a20f363c
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_DAILY_REFRESH.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_DAILY_REFRESH.png.sha1
index fde3daa..e90b391 100644
--- a/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_DAILY_REFRESH.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_DAILY_REFRESH.png.sha1
@@ -1 +1 @@
-03026243e9d04a43c3c10d6ceced3e1e16d884d7
\ No newline at end of file
+4a07423b8d67a8c64a09924d1c051f67a20f363c
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_IMAGE_NOT_USABLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_IMAGE_NOT_USABLE.png.sha1
new file mode 100644
index 0000000..452c5cd
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_IMAGE_NOT_USABLE.png.sha1
@@ -0,0 +1 @@
+a00ae14f0391125309431b19754e9dd98ec6a077
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_IMAGE_UNAVAILABLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_IMAGE_UNAVAILABLE.png.sha1
new file mode 100644
index 0000000..5af746b
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_CUSTOM_BG_IMAGE_UNAVAILABLE.png.sha1
@@ -0,0 +1 @@
+f44d352720276759cf0bca00f2e8ca535598ea0f
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_ERROR_MORE_INFO.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_ERROR_MORE_INFO.png.sha1
new file mode 100644
index 0000000..53c06581
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_ERROR_MORE_INFO.png.sha1
@@ -0,0 +1 @@
+9f9debb77d3d9d1a3c4efa7987ca86a11ec1b770
\ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 8e24253..4ccc447f 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -614,7 +614,7 @@
   </message>
   <!-- TODO(https://crbug.com/854562): Rename this to "IDS_SETTINGS_AUTOFILL" once Autofill Home is fully launched. -->
   <message name="IDS_SETTINGS_AUTOFILL_AUTOFILL_HOME" desc="Name for the addresses and payment methods section used for Autofill Home.">
-    Addresses &amp; Payment methods
+    Addresses &amp; payment methods
   </message>
   <message name="IDS_SETTINGS_GOOGLE_PAYMENTS" desc="Label used to differentiate when an address or credit card entry comes from Google Pay. This should follow the casing of the 'Google Pay' brand. 'Google Pay' should not be translated as it is the product name.">
     Google Pay
@@ -2981,6 +2981,12 @@
   <message name="IDS_SETTINGS_SITE_SETTINGS_SITE_CLEAR_STORAGE_CONFIRMATION" desc="Text for the dialog that warns about clearing storage used by a site (excluding cookies).">
     All data stored by <ph name="SITE">$1<ex>www.example.com</ex></ph> will be deleted, except for cookies.
   </message>
+  <message name="IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_RESET_DIALOG_TITLE" desc="Title of the dialog that warns about resetting all permissions for a group of sites.">
+    Reset site permissions?
+  </message>
+  <message name="IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_RESET_CONFIRMATION" desc="Text for the dialog that warns about resetting all permissions for a group of sites.">
+    Sites under <ph name="SITE_GROUP_NAME">$1<ex>google.co.uk</ex></ph> will also be reset.
+  </message>
   <message name="IDS_SETTINGS_SITE_SETTINGS_COOKIE_REMOVE_MULTIPLE" desc="Text for the dialog that warns about deleting all site data.">
     This will delete any data stored on your device for all the sites shown. Do you want to continue?
   </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index bb1a0e8..2649c91 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1029,6 +1029,8 @@
     "permissions/permission_uma_util.h",
     "permissions/permission_util.cc",
     "permissions/permission_util.h",
+    "picture_in_picture/picture_in_picture_window_manager.cc",
+    "picture_in_picture/picture_in_picture_window_manager.h",
     "platform_util.h",
     "platform_util_chromeos.cc",
     "platform_util_internal.h",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index c630f0c..3b5e9730 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -49,6 +49,7 @@
 #include "components/browser_sync/browser_sync_switches.h"
 #include "components/browsing_data/core/features.h"
 #include "components/cloud_devices/common/cloud_devices_switches.h"
+#include "components/content_settings/core/common/features.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
 #include "components/dom_distiller/core/dom_distiller_switches.h"
@@ -3935,7 +3936,8 @@
     {"enable-ephemeral-flash-permission",
      flag_descriptions::kEnableEphemeralFlashPermissionName,
      flag_descriptions::kEnableEphemeralFlashPermissionDescription, kOsDesktop,
-     SINGLE_VALUE_TYPE(switches::kEnableEphemeralFlashPermission)},
+     FEATURE_VALUE_TYPE(
+         content_settings::features::kEnableEphemeralFlashPermission)},
 
     // NOTE: Adding a new flag requires adding a corresponding entry to enum
     // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag
diff --git a/chrome/browser/android/password_manager/password_accessory_view_android.cc b/chrome/browser/android/password_manager/password_accessory_view_android.cc
index e5ded482..90c9b45 100644
--- a/chrome/browser/android/password_manager/password_accessory_view_android.cc
+++ b/chrome/browser/android/password_manager/password_accessory_view_android.cc
@@ -65,9 +65,10 @@
 void PasswordAccessoryViewAndroid::OnFillingTriggered(
     JNIEnv* env,
     const base::android::JavaParamRef<jobject>& obj,
+    jboolean isPassword,
     const base::android::JavaParamRef<_jstring*>& textToFill) {
   controller_->OnFillingTriggered(
-      base::android::ConvertJavaStringToUTF16(textToFill));
+      isPassword, base::android::ConvertJavaStringToUTF16(textToFill));
 }
 
 // static
diff --git a/chrome/browser/android/password_manager/password_accessory_view_android.h b/chrome/browser/android/password_manager/password_accessory_view_android.h
index 67cb47b09..a626896 100644
--- a/chrome/browser/android/password_manager/password_accessory_view_android.h
+++ b/chrome/browser/android/password_manager/password_accessory_view_android.h
@@ -30,6 +30,7 @@
   void OnFillingTriggered(
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& obj,
+      jboolean isPassword,
       const base::android::JavaParamRef<jstring>& textToFill);
 
  private:
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index c92cf0b..2958490 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -74,6 +74,7 @@
 #include "chrome/browser/permissions/permission_request_manager.h"
 #include "chrome/browser/platform_util.h"
 #include "chrome/browser/plugins/pdf_iframe_navigation_throttle.h"
+#include "chrome/browser/policy/cloud/policy_header_service_factory.h"
 #include "chrome/browser/predictors/loading_predictor.h"
 #include "chrome/browser/predictors/loading_predictor_factory.h"
 #include "chrome/browser/prerender/prerender_final_status.h"
@@ -180,6 +181,7 @@
 #include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
 #include "components/payments/content/payment_request_display_manager.h"
 #include "components/policy/content/policy_blacklist_navigation_throttle.h"
+#include "components/policy/core/common/cloud/policy_header_service.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
@@ -2160,9 +2162,10 @@
     int* extra_load_flags) {
   WebContents* web_contents =
       WebContents::FromFrameTreeNodeId(frame_tree_node_id);
+  content::BrowserContext* browser_context = web_contents->GetBrowserContext();
   *extra_headers =
       client_hints::GetAdditionalNavigationRequestClientHintsHeaders(
-          web_contents->GetBrowserContext(), url);
+          browser_context, url);
   prerender::PrerenderContents* prerender_contents =
       prerender::PrerenderContents::FromWebContents(web_contents);
   if (prerender_contents &&
@@ -2173,6 +2176,37 @@
     extra_headers->get()->SetHeader(prerender::kPurposeHeaderName,
                                     prerender::kPurposeHeaderValue);
   }
+
+  if (!browser_context->IsOffTheRecord()) {
+    // Add policy headers for non-incognito requests.
+    policy::PolicyHeaderService* policy_header_service =
+        policy::PolicyHeaderServiceFactory::GetForBrowserContext(
+            browser_context);
+    if (policy_header_service)
+      policy_header_service->AddPolicyHeaders(url, extra_headers);
+  }
+}
+
+void ChromeContentBrowserClient::NavigationRequestRedirected(
+    int frame_tree_node_id,
+    const GURL& url,
+    base::Optional<net::HttpRequestHeaders>* modified_request_headers) {
+  WebContents* web_contents =
+      WebContents::FromFrameTreeNodeId(frame_tree_node_id);
+  content::BrowserContext* browser_context = web_contents->GetBrowserContext();
+
+  if (!browser_context->IsOffTheRecord()) {
+    // Add policy headers for non-incognito requests.
+    policy::PolicyHeaderService* policy_header_service =
+        policy::PolicyHeaderServiceFactory::GetForBrowserContext(
+            browser_context);
+    if (policy_header_service) {
+      std::unique_ptr<net::HttpRequestHeaders> extra_headers;
+      policy_header_service->AddPolicyHeaders(url, &extra_headers);
+      if (extra_headers)
+        *modified_request_headers = std::move(*extra_headers);
+    }
+  }
 }
 
 bool ChromeContentBrowserClient::AllowAppCache(
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index db48375..53fe6f8 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -171,6 +171,10 @@
       const GURL& url,
       std::unique_ptr<net::HttpRequestHeaders>* extra_headers,
       int* extra_load_flags) override;
+  void NavigationRequestRedirected(int frame_tree_node_id,
+                                   const GURL& url,
+                                   base::Optional<net::HttpRequestHeaders>*
+                                       modified_request_headers) override;
   bool AllowAppCache(const GURL& manifest_url,
                      const GURL& first_party,
                      content::ResourceContext* context) override;
diff --git a/chrome/browser/chrome_content_browser_client_browsertest.cc b/chrome/browser/chrome_content_browser_client_browsertest.cc
index 6b35511..600725b 100644
--- a/chrome/browser/chrome_content_browser_client_browsertest.cc
+++ b/chrome/browser/chrome_content_browser_client_browsertest.cc
@@ -8,6 +8,7 @@
 #include "base/command_line.h"
 #include "base/macros.h"
 #include "base/sys_info.h"
+#include "chrome/browser/policy/cloud/policy_header_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/instant_service.h"
 #include "chrome/browser/search/instant_service_factory.h"
@@ -21,6 +22,8 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/network_session_configurator/common/network_switches.h"
+#include "components/policy/core/common/cloud/cloud_policy_constants.h"
+#include "components/policy/core/common/cloud/policy_header_service.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/render_frame_host.h"
@@ -30,11 +33,26 @@
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
 #include "net/dns/mock_host_resolver.h"
+#include "net/http/http_status_code.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 "url/gurl.h"
 
 namespace content {
 
+namespace {
+
+const char kTestPolicyHeader[] = "test_header";
+const char kServerRedirectUrl[] = "/server-redirect";
+
+enum class NetworkServiceState {
+  kDisabled,
+  kEnabled,
+};
+
+}  // namespace
+
 // Use a test class with SetUpCommandLine to ensure the flag is sent to the
 // first renderer process.
 class ChromeContentBrowserClientBrowserTest : public InProcessBrowserTest {
@@ -281,4 +299,104 @@
       content::SiteIsolationPolicy::UseDedicatedProcessesForAllSites());
 }
 
+class PolicyHeaderServiceBrowserTest : public InProcessBrowserTest {
+ public:
+  PolicyHeaderServiceBrowserTest() = default;
+
+  void SetUpOnMainThread() override {
+    embedded_test_server()->RegisterRequestHandler(
+        base::BindRepeating(&PolicyHeaderServiceBrowserTest::HandleTestRequest,
+                            base::Unretained(this)));
+    ASSERT_TRUE(embedded_test_server()->Start());
+
+    // Forge a dummy DMServer URL.
+    dm_url_ = embedded_test_server()->GetURL("/DeviceManagement");
+
+    // At this point, the Profile is already initialized and it's too
+    // late to set the DMServer URL via command line flags, so directly
+    // inject it to the PolicyHeaderService.
+    policy::PolicyHeaderService* policy_header_service =
+        policy::PolicyHeaderServiceFactory::GetForBrowserContext(
+            browser()->profile());
+    policy_header_service->SetServerURLForTest(dm_url_.spec());
+    policy_header_service->SetHeaderForTest(kTestPolicyHeader);
+  }
+
+  std::unique_ptr<net::test_server::HttpResponse> HandleTestRequest(
+      const net::test_server::HttpRequest& request) {
+    last_request_headers_ = request.headers;
+
+    if (base::StartsWith(request.relative_url, kServerRedirectUrl,
+                         base::CompareCase::SENSITIVE)) {
+      // Extract the target URL and redirect there.
+      size_t query_string_pos = request.relative_url.find('?');
+      std::string redirect_target =
+          request.relative_url.substr(query_string_pos + 1);
+
+      std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
+          new net::test_server::BasicHttpResponse);
+      http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
+      http_response->AddCustomHeader("Location", redirect_target);
+      return std::move(http_response);
+    } else if (request.relative_url == "/") {
+      std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
+          new net::test_server::BasicHttpResponse);
+      http_response->set_code(net::HTTP_OK);
+      http_response->set_content("Success");
+      return std::move(http_response);
+    }
+    return nullptr;
+  }
+
+  const GURL& dm_url() const { return dm_url_; }
+
+  const net::test_server::HttpRequest::HeaderMap& last_request_headers() const {
+    return last_request_headers_;
+  }
+
+ private:
+  // The dummy URL for DMServer.
+  GURL dm_url_;
+
+  // List of request headers received by the embedded server.
+  net::test_server::HttpRequest::HeaderMap last_request_headers_;
+
+  DISALLOW_COPY_AND_ASSIGN(PolicyHeaderServiceBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(PolicyHeaderServiceBrowserTest, NoPolicyHeader) {
+  // When fetching non-DMServer URLs, we should not add a policy header to the
+  // request.
+  DCHECK(!embedded_test_server()->base_url().spec().empty());
+  ui_test_utils::NavigateToURL(browser(), embedded_test_server()->base_url());
+  auto iter = last_request_headers().find(policy::kChromePolicyHeader);
+  EXPECT_EQ(iter, last_request_headers().end());
+}
+
+IN_PROC_BROWSER_TEST_F(PolicyHeaderServiceBrowserTest, PolicyHeader) {
+  // When fetching a DMServer URL, we should add a policy header to the
+  // request.
+  ui_test_utils::NavigateToURL(browser(), dm_url());
+
+  auto iter = last_request_headers().find(policy::kChromePolicyHeader);
+  ASSERT_NE(iter, last_request_headers().end());
+  EXPECT_EQ(iter->second, kTestPolicyHeader);
+}
+
+IN_PROC_BROWSER_TEST_F(PolicyHeaderServiceBrowserTest,
+                       PolicyHeaderForRedirect) {
+  // Build up a URL that results in a redirect to the DMServer URL to make
+  // sure the policy header is still added.
+  std::string redirect_url;
+  redirect_url += kServerRedirectUrl;
+  redirect_url += "?";
+  redirect_url += dm_url().spec();
+  ui_test_utils::NavigateToURL(browser(),
+                               embedded_test_server()->GetURL(redirect_url));
+
+  auto iter = last_request_headers().find(policy::kChromePolicyHeader);
+  ASSERT_NE(iter, last_request_headers().end());
+  EXPECT_EQ(iter->second, kTestPolicyHeader);
+}
+
 }  // namespace content
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 601f66f..849e981 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -504,6 +504,10 @@
     "certificate_provider/sign_requests.h",
     "certificate_provider/thread_safe_certificate_map.cc",
     "certificate_provider/thread_safe_certificate_map.h",
+    "child_accounts/consumer_status_reporting_service.cc",
+    "child_accounts/consumer_status_reporting_service.h",
+    "child_accounts/consumer_status_reporting_service_factory.cc",
+    "child_accounts/consumer_status_reporting_service_factory.h",
     "child_accounts/screen_time_controller.cc",
     "child_accounts/screen_time_controller.h",
     "child_accounts/screen_time_controller_factory.cc",
diff --git a/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service.cc b/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service.cc
new file mode 100644
index 0000000..6ec3699
--- /dev/null
+++ b/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service.cc
@@ -0,0 +1,61 @@
+// 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/chromeos/child_accounts/consumer_status_reporting_service.h"
+
+#include "base/logging.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
+#include "chrome/browser/chromeos/policy/device_status_collector.h"
+#include "chrome/browser/chromeos/policy/status_uploader.h"
+#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
+#include "chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chromeos/system/statistics_provider.h"
+#include "components/policy/core/common/cloud/cloud_policy_core.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/browser/browser_context.h"
+
+namespace chromeos {
+
+namespace {
+
+// Default frequency for uploading status reports.
+constexpr base::TimeDelta kStatusUploadFrequency =
+    base::TimeDelta::FromMinutes(10);
+
+}  // namespace
+
+ConsumerStatusReportingService::ConsumerStatusReportingService(
+    content::BrowserContext* context) {
+  // If child user is registered with DMServer and has User Policy applied, it
+  // should upload device status to the server.
+  policy::UserCloudPolicyManagerChromeOS* user_cloud_policy_manager =
+      policy::UserPolicyManagerFactoryChromeOS::GetCloudPolicyManagerForProfile(
+          Profile::FromBrowserContext(context));
+  if (!user_cloud_policy_manager) {
+    LOG(WARNING) << "Child user is not managed by User Policy - status reports "
+                    "cannot be uploaded to the server. ";
+    return;
+  }
+
+  PrefService* pref_service = Profile::FromBrowserContext(context)->GetPrefs();
+  DCHECK(pref_service->GetInitializationStatus() !=
+         PrefService::INITIALIZATION_STATUS_WAITING);
+
+  status_uploader_ = std::make_unique<policy::StatusUploader>(
+      user_cloud_policy_manager->core()->client(),
+      std::make_unique<policy::DeviceStatusCollector>(
+          pref_service, system::StatisticsProvider::GetInstance(),
+          policy::DeviceStatusCollector::VolumeInfoFetcher(),
+          policy::DeviceStatusCollector::CPUStatisticsFetcher(),
+          policy::DeviceStatusCollector::CPUTempFetcher(),
+          policy::DeviceStatusCollector::AndroidStatusFetcher(),
+          false /* is_enterprise_reporting */),
+      base::ThreadTaskRunnerHandle::Get(), kStatusUploadFrequency);
+}
+
+ConsumerStatusReportingService::~ConsumerStatusReportingService() = default;
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service.h b/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service.h
new file mode 100644
index 0000000..e4b5c878
--- /dev/null
+++ b/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service.h
@@ -0,0 +1,43 @@
+// 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_CHROMEOS_CHILD_ACCOUNTS_CONSUMER_STATUS_REPORTING_SERVICE_H_
+#define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_CONSUMER_STATUS_REPORTING_SERVICE_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace policy {
+class StatusUploader;
+}
+
+namespace chromeos {
+
+// Controls consumer reporting for child user.
+// Child user should be registered with DMServer and periodically upload the
+// information about the device usage. The reports are only sent during user's
+// session and they do not interfere with enterprise reporting that is
+// controlled by DeviceCloudPolicyManagerChromeOS.
+class ConsumerStatusReportingService : public KeyedService {
+ public:
+  explicit ConsumerStatusReportingService(content::BrowserContext* context);
+  ~ConsumerStatusReportingService() override;
+
+ private:
+  // Helper object that controls device status collection/storage and uploads
+  // gathered reports to the server.
+  std::unique_ptr<policy::StatusUploader> status_uploader_;
+
+  DISALLOW_COPY_AND_ASSIGN(ConsumerStatusReportingService);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_CONSUMER_STATUS_REPORTING_SERVICE_H_
diff --git a/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service_factory.cc b/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service_factory.cc
new file mode 100644
index 0000000..6e4074c
--- /dev/null
+++ b/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service_factory.cc
@@ -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.
+
+#include "chrome/browser/chromeos/child_accounts/consumer_status_reporting_service_factory.h"
+
+#include "base/macros.h"
+#include "chrome/browser/chromeos/child_accounts/consumer_status_reporting_service.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+namespace chromeos {
+
+// static
+ConsumerStatusReportingService*
+ConsumerStatusReportingServiceFactory::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return static_cast<ConsumerStatusReportingService*>(
+      GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+// static
+ConsumerStatusReportingServiceFactory*
+ConsumerStatusReportingServiceFactory::GetInstance() {
+  static base::NoDestructor<ConsumerStatusReportingServiceFactory> factory;
+  return factory.get();
+}
+
+ConsumerStatusReportingServiceFactory::ConsumerStatusReportingServiceFactory()
+    : BrowserContextKeyedServiceFactory(
+          "ConsumerStatusReportingServiceFactory",
+          BrowserContextDependencyManager::GetInstance()) {}
+
+ConsumerStatusReportingServiceFactory::
+    ~ConsumerStatusReportingServiceFactory() = default;
+
+KeyedService* ConsumerStatusReportingServiceFactory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  return new ConsumerStatusReportingService(context);
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service_factory.h b/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service_factory.h
new file mode 100644
index 0000000..36a977b
--- /dev/null
+++ b/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service_factory.h
@@ -0,0 +1,45 @@
+// 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_CHROMEOS_CHILD_ACCOUNTS_CONSUMER_STATUS_REPORTING_SERVICE_FACTORY_H_
+#define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_CONSUMER_STATUS_REPORTING_SERVICE_FACTORY_H_
+
+#include "base/no_destructor.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace chromeos {
+class ConsumerStatusReportingService;
+
+// Singleton that owns all ConsumerStatusReportingService objects and associates
+// them with corresponding BrowserContexts. Listens for the BrowserContext's
+// destruction notification and cleans up the associated
+// ConsumerStatusReportingService.
+class ConsumerStatusReportingServiceFactory
+    : public BrowserContextKeyedServiceFactory {
+ public:
+  static ConsumerStatusReportingService* GetForBrowserContext(
+      content::BrowserContext* context);
+
+  static ConsumerStatusReportingServiceFactory* GetInstance();
+
+ private:
+  friend class base::NoDestructor<ConsumerStatusReportingServiceFactory>;
+
+  ConsumerStatusReportingServiceFactory();
+  ~ConsumerStatusReportingServiceFactory() override;
+
+  // BrowserContextKeyedServiceFactory:
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* context) const override;
+
+  DISALLOW_COPY_AND_ASSIGN(ConsumerStatusReportingServiceFactory);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_CONSUMER_STATUS_REPORTING_SERVICE_FACTORY_H_
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
index deb2929..fde9b79 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
@@ -734,6 +734,8 @@
              IDS_FILE_BROWSER_IMAGE_RESOLUTION_COLUMN_LABEL);
   SET_STRING("ANDROID_FILES_ROOT_LABEL",
              IDS_FILE_BROWSER_ANDROID_FILES_ROOT_LABEL);
+  SET_STRING("SHOW_ALL_ANDROID_FOLDERS_OPTION",
+             IDS_FILE_BROWSER_SHOW_ALL_ANDROID_FOLDERS_OPTION);
   SET_STRING("LINUX_FILES_ROOT_LABEL", IDS_FILE_BROWSER_LINUX_FILES_ROOT_LABEL);
   SET_STRING("MEDIA_ARTIST_COLUMN_LABEL",
              IDS_FILE_BROWSER_MEDIA_ARTIST_COLUMN_LABEL);
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
index 9063194..c34f7c8 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -124,10 +124,10 @@
   // Maps |value| to TargetVolume. Returns true on success.
   static bool MapStringToTargetVolume(base::StringPiece value,
                                       TargetVolume* volume) {
-    if (value == "drive")
-      *volume = DRIVE_VOLUME;
-    else if (value == "local")
+    if (value == "local")
       *volume = LOCAL_VOLUME;
+    else if (value == "drive")
+      *volume = DRIVE_VOLUME;
     else if (value == "usb")
       *volume = USB_VOLUME;
     else
@@ -158,7 +158,7 @@
 
     bool can_copy;    // Whether the user can copy this file or directory.
     bool can_delete;  // Whether the user can delete this file or directory.
-    bool can_rename;  // Whether the user can rename thie file or directory.
+    bool can_rename;  // Whether the user can rename this file or directory.
     bool can_add_children;  // For directories, whether the user can add
                             // children to this directory.
     bool can_share;  // Whether the user can share this file or directory.
@@ -204,7 +204,7 @@
     std::string name_text;           // Display file name.
     std::string mime_type;           // File entry content mime type.
     base::Time last_modified_time;   // Entry last modified time.
-    EntryCapabilities capabilities;  // Permissions of this file or directory.
+    EntryCapabilities capabilities;  // Entry permissions.
 
     // Registers the member information to the given converter.
     static void RegisterJSONConverter(
@@ -396,16 +396,17 @@
   }
 
  private:
-  // Updates ModifiedTime of the entry and its parents by referring
-  // TestEntryInfo. Returns true on success.
+  // Updates the ModifiedTime of the entry, and its parent directories if
+  // needed. Returns true on success.
   bool UpdateModifiedTime(const AddEntriesMessage::TestEntryInfo& entry) {
     const base::FilePath path = root_path().AppendASCII(entry.target_path);
     if (!base::TouchFile(path, entry.last_modified_time,
-                         entry.last_modified_time))
+                         entry.last_modified_time)) {
       return false;
+    }
 
-    // Update the modified time of parent directories because it may be also
-    // affected by the update of child items.
+    // Update the modified time of parent directories because they may be
+    // also affected by the update of child items.
     if (path.DirName() != root_path()) {
       const auto& it = entries_.find(path.DirName());
       if (it == entries_.end())
@@ -530,6 +531,7 @@
     capabilities.set_can_add_children(entry.capabilities.can_add_children);
     capabilities.set_can_share(entry.capabilities.can_share);
 
+    // Add the file or directory entry.
     switch (entry.type) {
       case AddEntriesMessage::FILE:
         CreateFile(entry.source_file_name, parent_entry->resource_id(),
@@ -543,8 +545,8 @@
         break;
     }
 
-    // Files and directories in drive will only appear after CheckUpdates
-    // has completed.
+    // Any file or directory created above, will only appear in Drive after
+    // CheckForUpdates() has completed.
     CheckForUpdates();
     content::RunAllTasksUntilIdle();
   }
@@ -738,8 +740,8 @@
         profile_));
   }
 
-  // Updates ModifiedTime of the entry and its parents by referring
-  // TestEntryInfo. Returns true on success.
+  // Updates the ModifiedTime of the entry, and its parent directories if
+  // needed. Returns true on success.
   bool UpdateModifiedTime(const AddEntriesMessage::TestEntryInfo& entry) {
     const auto path = GetTargetPathForTestEntry(entry);
     if (!base::TouchFile(path, entry.last_modified_time,
@@ -747,8 +749,8 @@
       return false;
     }
 
-    // Update the modified time of parent directories because it may be also
-    // affected by the update of child items.
+    // Update the modified time of parent directories because they may be
+    // also affected by the update of child items.
     if (path.DirName() != GetDriveRoot()) {
       const auto it = entries_.find(path.DirName());
       if (it == entries_.end())
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
index e30e41e..3950b8f 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
@@ -128,25 +128,19 @@
 class KeyEventDoneCallback {
  public:
   explicit KeyEventDoneCallback(bool expected_argument)
-      : expected_argument_(expected_argument),
-        is_called_(false) {}
+      : expected_argument_(expected_argument) {}
   ~KeyEventDoneCallback() {}
 
   void Run(bool consumed) {
-    if (consumed == expected_argument_) {
-      base::RunLoop::QuitCurrentWhenIdleDeprecated();
-      is_called_ = true;
-    }
+    if (consumed == expected_argument_)
+      run_loop_.Quit();
   }
 
-  void WaitUntilCalled() {
-    while (!is_called_)
-      content::RunMessageLoop();
-  }
+  void WaitUntilCalled() { run_loop_.Run(); }
 
  private:
   bool expected_argument_;
-  bool is_called_;
+  base::RunLoop run_loop_;
 
   DISALLOW_COPY_AND_ASSIGN(KeyEventDoneCallback);
 };
diff --git a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
index 5ea8be3..f04254c 100644
--- a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
+++ b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
@@ -197,6 +197,7 @@
         user_manager_(new chromeos::FakeChromeUserManager()),
         user_manager_enabler_(base::WrapUnique(user_manager_)),
         mock_caller_(NULL),
+        consumer_(run_loop_.QuitClosure()),
         owner_key_util_(new ownership::MockOwnerKeyUtil()) {
     // Testing profile must be initialized after user_manager_ +
     // user_manager_enabler_, because it will create another UserManager
@@ -267,45 +268,48 @@
   // wasn't supposed to happen.
   void FailOnLoginFailure() {
     ON_CALL(consumer_, OnAuthFailure(_))
-        .WillByDefault(Invoke(MockAuthStatusConsumer::OnFailQuitAndFail));
+        .WillByDefault(
+            Invoke(&consumer_, &MockAuthStatusConsumer::OnFailQuitAndFail));
   }
 
   // Allow test to fail and exit gracefully, even if OnAuthSuccess()
   // wasn't supposed to happen.
   void FailOnLoginSuccess() {
     ON_CALL(consumer_, OnAuthSuccess(_))
-        .WillByDefault(Invoke(MockAuthStatusConsumer::OnSuccessQuitAndFail));
+        .WillByDefault(
+            Invoke(&consumer_, &MockAuthStatusConsumer::OnSuccessQuitAndFail));
   }
 
   // Allow test to fail and exit gracefully, even if
   // OnOffTheRecordAuthSuccess() wasn't supposed to happen.
   void FailOnGuestLoginSuccess() {
     ON_CALL(consumer_, OnOffTheRecordAuthSuccess())
-        .WillByDefault(
-            Invoke(MockAuthStatusConsumer::OnGuestSuccessQuitAndFail));
+        .WillByDefault(Invoke(
+            &consumer_, &MockAuthStatusConsumer::OnGuestSuccessQuitAndFail));
   }
 
   void ExpectLoginFailure(const AuthFailure& failure) {
     EXPECT_CALL(consumer_, OnAuthFailure(failure))
-        .WillOnce(Invoke(MockAuthStatusConsumer::OnFailQuit))
+        .WillOnce(Invoke(&consumer_, &MockAuthStatusConsumer::OnFailQuit))
         .RetiresOnSaturation();
   }
 
   void ExpectLoginSuccess(const UserContext& user_context) {
     EXPECT_CALL(consumer_, OnAuthSuccess(user_context))
-        .WillOnce(Invoke(MockAuthStatusConsumer::OnSuccessQuit))
+        .WillOnce(Invoke(&consumer_, &MockAuthStatusConsumer::OnSuccessQuit))
         .RetiresOnSaturation();
   }
 
   void ExpectGuestLoginSuccess() {
     EXPECT_CALL(consumer_, OnOffTheRecordAuthSuccess())
-        .WillOnce(Invoke(MockAuthStatusConsumer::OnGuestSuccessQuit))
+        .WillOnce(
+            Invoke(&consumer_, &MockAuthStatusConsumer::OnGuestSuccessQuit))
         .RetiresOnSaturation();
   }
 
   void ExpectPasswordChange() {
     EXPECT_CALL(consumer_, OnPasswordChangeDetected())
-        .WillOnce(Invoke(MockAuthStatusConsumer::OnMigrateQuit))
+        .WillOnce(Invoke(&consumer_, &MockAuthStatusConsumer::OnMigrateQuit))
         .RetiresOnSaturation();
   }
 
@@ -390,6 +394,7 @@
 
   cryptohome::MockAsyncMethodCaller* mock_caller_;
 
+  base::RunLoop run_loop_;
   MockAuthStatusConsumer consumer_;
 
   scoped_refptr<CryptohomeAuthenticator> auth_;
@@ -586,7 +591,7 @@
   EXPECT_CALL(*mock_caller_, AsyncMountGuest(_)).Times(1).RetiresOnSaturation();
 
   auth_->LoginOffTheRecord();
-  base::RunLoop().Run();
+  run_loop_.Run();
 }
 
 TEST_F(CryptohomeAuthenticatorTest, DriveGuestLoginButFail) {
@@ -599,7 +604,7 @@
   EXPECT_CALL(*mock_caller_, AsyncMountGuest(_)).Times(1).RetiresOnSaturation();
 
   auth_->LoginOffTheRecord();
-  base::RunLoop().Run();
+  run_loop_.Run();
 }
 
 TEST_F(CryptohomeAuthenticatorTest, DriveDataResync) {
@@ -628,7 +633,7 @@
   SetAttemptState(auth_.get(), state_.release());
 
   auth_->ResyncEncryptedData();
-  base::RunLoop().Run();
+  run_loop_.Run();
 }
 
 TEST_F(CryptohomeAuthenticatorTest, DriveResyncFail) {
@@ -646,7 +651,7 @@
   SetAttemptState(auth_.get(), state_.release());
 
   auth_->ResyncEncryptedData();
-  base::RunLoop().Run();
+  run_loop_.Run();
 }
 
 TEST_F(CryptohomeAuthenticatorTest, DriveRequestOldPassword) {
@@ -686,7 +691,7 @@
   SetAttemptState(auth_.get(), state_.release());
 
   auth_->RecoverEncryptedData(std::string());
-  base::RunLoop().Run();
+  run_loop_.Run();
 }
 
 TEST_F(CryptohomeAuthenticatorTest, DriveDataRecoverButFail) {
@@ -706,7 +711,7 @@
   SetAttemptState(auth_.get(), state_.release());
 
   auth_->RecoverEncryptedData(std::string());
-  base::RunLoop().Run();
+  run_loop_.Run();
 }
 
 TEST_F(CryptohomeAuthenticatorTest, ResolveOfflineNoMount) {
@@ -791,7 +796,7 @@
   ExpectCheckKeyExCall();
 
   auth_->AuthenticateToUnlock(user_context_);
-  base::RunLoop().Run();
+  run_loop_.Run();
 }
 
 TEST_F(CryptohomeAuthenticatorTest, DriveLoginWithPreHashedPassword) {
@@ -812,7 +817,7 @@
   ExpectMountExCall(false /* expect_create_attempt */);
 
   auth_->AuthenticateToLogin(NULL, user_context_);
-  base::RunLoop().Run();
+  run_loop_.Run();
 }
 
 TEST_F(CryptohomeAuthenticatorTest, FailLoginWithMissingSalt) {
@@ -828,7 +833,7 @@
                          std::unique_ptr<std::string>());
 
   auth_->AuthenticateToLogin(NULL, user_context_);
-  base::RunLoop().Run();
+  run_loop_.Run();
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc
index 446da6ec..f7c64bd4 100644
--- a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc
+++ b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc
@@ -47,7 +47,7 @@
 // An object that wait for lock state and fullscreen state.
 class Waiter : public content::NotificationObserver {
  public:
-  explicit Waiter(Browser* browser) : browser_(browser), running_(false) {
+  explicit Waiter(Browser* browser) : browser_(browser) {
     registrar_.Add(this, chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
                    content::NotificationService::AllSources());
     registrar_.Add(this, chrome::NOTIFICATION_FULLSCREEN_CHANGED,
@@ -61,30 +61,29 @@
                const content::NotificationDetails& details) override {
     DCHECK(type == chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED ||
            type == chrome::NOTIFICATION_FULLSCREEN_CHANGED);
-    if (running_)
-      base::RunLoop::QuitCurrentWhenIdleDeprecated();
+    if (quit_loop_)
+      std::move(quit_loop_).Run();
   }
 
   // Wait until the two conditions are met.
   void Wait(bool locker_state, bool fullscreen) {
-    running_ = true;
     std::unique_ptr<chromeos::test::ScreenLockerTester> tester(
         chromeos::ScreenLocker::GetTester());
     while (tester->IsLocked() != locker_state ||
            browser_->window()->IsFullscreen() != fullscreen) {
-      content::RunMessageLoop();
+      base::RunLoop run_loop;
+      quit_loop_ = run_loop.QuitClosure();
+      run_loop.Run();
     }
     // Make sure all pending tasks are executed.
     content::RunAllPendingInMessageLoop();
-    running_ = false;
   }
 
  private:
   Browser* browser_;
   content::NotificationRegistrar registrar_;
 
-  // Are we currently running the message loop?
-  bool running_;
+  base::OnceClosure quit_loop_;
 
   DISALLOW_COPY_AND_ASSIGN(Waiter);
 };
diff --git a/chrome/browser/chromeos/login/session/chrome_session_manager.cc b/chrome/browser/chromeos/login/session/chrome_session_manager.cc
index aa315f8eb..df5e6a6 100644
--- a/chrome/browser/chromeos/login/session/chrome_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/chrome_session_manager.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/chromeos/arc/arc_service_launcher.h"
 #include "chrome/browser/chromeos/boot_times_recorder.h"
+#include "chrome/browser/chromeos/child_accounts/consumer_status_reporting_service_factory.h"
 #include "chrome/browser/chromeos/child_accounts/screen_time_controller_factory.h"
 #include "chrome/browser/chromeos/lock_screen_apps/state_controller.h"
 #include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
@@ -143,8 +144,10 @@
     }
     arc::ArcServiceLauncher::Get()->OnPrimaryUserProfilePrepared(user_profile);
 
-    if (user->GetType() == user_manager::USER_TYPE_CHILD)
+    if (user->GetType() == user_manager::USER_TYPE_CHILD) {
       ScreenTimeControllerFactory::GetForBrowserContext(user_profile);
+      ConsumerStatusReportingServiceFactory::GetForBrowserContext(user_profile);
+    }
 
     // Send the PROFILE_PREPARED notification and call SessionStarted()
     // so that the Launcher and other Profile dependent classes are created.
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index 2807235..a597361 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -37,6 +37,7 @@
 #include "chrome/browser/chromeos/arc/arc_util.h"
 #include "chrome/browser/chromeos/base/locale_util.h"
 #include "chrome/browser/chromeos/boot_times_recorder.h"
+#include "chrome/browser/chromeos/child_accounts/consumer_status_reporting_service_factory.h"
 #include "chrome/browser/chromeos/child_accounts/screen_time_controller_factory.h"
 #include "chrome/browser/chromeos/first_run/first_run.h"
 #include "chrome/browser/chromeos/first_run/goodies_displayer.h"
@@ -1417,8 +1418,10 @@
     if (tether_service)
       tether_service->StartTetherIfPossible();
 
-    if (user->GetType() == user_manager::USER_TYPE_CHILD)
+    if (user->GetType() == user_manager::USER_TYPE_CHILD) {
       ScreenTimeControllerFactory::GetForBrowserContext(profile);
+      ConsumerStatusReportingServiceFactory::GetForBrowserContext(profile);
+    }
   }
 
   UpdateEasyUnlockKeys(user_context_);
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
index bae7ff9..e9ebc49a 100644
--- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -2090,7 +2090,8 @@
   // Set up an observer that will quit the message loop when login has succeeded
   // and the first wizard screen, if any, is being shown.
   base::RunLoop login_wait_run_loop;
-  chromeos::MockAuthStatusConsumer login_status_consumer;
+  chromeos::MockAuthStatusConsumer login_status_consumer(
+      login_wait_run_loop.QuitClosure());
   EXPECT_CALL(login_status_consumer, OnAuthSuccess(_)).Times(1).WillOnce(
       InvokeWithoutArgs(&login_wait_run_loop, &base::RunLoop::Quit));
   chromeos::ExistingUserController* controller =
@@ -2308,7 +2309,8 @@
   // Set up an observer that will quit the message loop when login has succeeded
   // and the first wizard screen, if any, is being shown.
   base::RunLoop login_wait_run_loop;
-  chromeos::MockAuthStatusConsumer login_status_consumer;
+  chromeos::MockAuthStatusConsumer login_status_consumer(
+      login_wait_run_loop.QuitClosure());
   EXPECT_CALL(login_status_consumer, OnAuthSuccess(_)).Times(1).WillOnce(
       InvokeWithoutArgs(&login_wait_run_loop, &base::RunLoop::Quit));
 
diff --git a/chrome/browser/chromeos/policy/device_status_collector.cc b/chrome/browser/chromeos/policy/device_status_collector.cc
index a3d19295..45ba693 100644
--- a/chrome/browser/chromeos/policy/device_status_collector.cc
+++ b/chrome/browser/chromeos/policy/device_status_collector.cc
@@ -779,18 +779,11 @@
                             weak_factory_.GetWeakPtr()));
   }
 
-  // User |pref_service| might not be initialized yet. This can be removed once
-  // creation of DeviceStatusCollector for non-enterprise reporting guarantees
-  // that pref service is ready.
-  if (pref_service_->GetInitializationStatus() ==
-      PrefService::INITIALIZATION_STATUS_WAITING) {
-    pref_service->AddPrefInitObserver(
-        base::BindOnce(&DeviceStatusCollector::OnPrefServiceInitialized,
-                       weak_factory_.GetWeakPtr()));
-    return;
-  }
-  OnPrefServiceInitialized(pref_service_->GetInitializationStatus() !=
-                           PrefService::INITIALIZATION_STATUS_ERROR);
+  DCHECK(pref_service_->GetInitializationStatus() !=
+         PrefService::INITIALIZATION_STATUS_WAITING);
+  activity_storage_ = std::make_unique<ActivityStorage>(
+      pref_service_, (is_enterprise_reporting_ ? prefs::kDeviceActivityTimes
+                                               : prefs::kUserActivityTimes));
 }
 
 DeviceStatusCollector::~DeviceStatusCollector() {
@@ -893,9 +886,8 @@
 }
 
 void DeviceStatusCollector::IdleStateCallback(ui::IdleState state) {
-  // Do nothing if |activity_storage_| is not ready or device activity reporting
-  // is disabled.
-  if (!activity_storage_ || !report_activity_times_)
+  // Do nothing if device activity reporting is disabled.
+  if (!report_activity_times_)
     return;
 
   Time now = GetCurrentTime();
@@ -1020,10 +1012,6 @@
 }
 
 void DeviceStatusCollector::ReportingUsersChanged() {
-  // Do nothing if |activity_storage_| is not ready.
-  if (!activity_storage_)
-    return;
-
   std::vector<std::string> reporting_users;
   for (auto& value :
        pref_service_->GetList(prefs::kReportingUsers)->GetList()) {
@@ -1059,25 +1047,8 @@
   return !is_enterprise_reporting_ || report_users_;
 }
 
-void DeviceStatusCollector::OnPrefServiceInitialized(bool succeeded) {
-  if (!succeeded) {
-    LOG(ERROR) << "Pref service was not initialized successfully - activity "
-                  "for device status reporting cannot be stored.";
-    return;
-  }
-
-  DCHECK(!activity_storage_);
-  activity_storage_ = std::make_unique<ActivityStorage>(
-      pref_service_, (is_enterprise_reporting_ ? prefs::kDeviceActivityTimes
-                                               : prefs::kUserActivityTimes));
-}
-
 bool DeviceStatusCollector::GetActivityTimes(
     em::DeviceStatusReportRequest* status) {
-  // Do nothing if |activity_storage_| is not ready.
-  if (!activity_storage_)
-    return false;
-
   // If user reporting is off, data should be aggregated per day.
   // Signed-in user is reported in non-enterprise reporting.
   std::vector<ActivityStorage::ActivityPeriod> activity_times =
@@ -1590,10 +1561,6 @@
 }
 
 void DeviceStatusCollector::OnSubmittedSuccessfully() {
-  // Do nothing if |activity_storage_| is not ready.
-  if (!activity_storage_)
-    return;
-
   activity_storage_->TrimActivityPeriods(last_reported_day_,
                                          duration_for_last_reported_day_,
                                          std::numeric_limits<int64_t>::max());
diff --git a/chrome/browser/chromeos/policy/device_status_collector.h b/chrome/browser/chromeos/policy/device_status_collector.h
index 8d5cb34..9f41e0a 100644
--- a/chrome/browser/chromeos/policy/device_status_collector.h
+++ b/chrome/browser/chromeos/policy/device_status_collector.h
@@ -92,8 +92,9 @@
   // Constructor. Callers can inject their own *Fetcher callbacks, e.g. for unit
   // testing. A null callback can be passed for any *Fetcher parameter, to use
   // the default implementation. These callbacks are always executed on Blocking
-  // Pool. If |is_enterprise_device| additional enterprise relevant status data
-  // will be reported.
+  // Pool. Caller is responsible for passing already initialized |pref_service|.
+  // If |is_enterprise_device| additional enterprise relevant status data will
+  // be reported.
   DeviceStatusCollector(PrefService* pref_service,
                         chromeos::system::StatisticsProvider* provider,
                         const VolumeInfoFetcher& volume_info_fetcher,
@@ -221,9 +222,6 @@
   // reports.
   bool IncludeEmailsInActivityReports() const;
 
-  // Called when |pref_service_| is initialized.
-  void OnPrefServiceInitialized(bool succeeded);
-
   // Pref service that is mainly used to store activity periods for reporting.
   PrefService* const pref_service_;
 
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc
index 7c860b6..365147c 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc
@@ -25,13 +25,10 @@
 #include "chrome/browser/chromeos/login/users/chrome_user_manager_impl.h"
 #include "chrome/browser/chromeos/policy/app_install_event_log_uploader.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
-#include "chrome/browser/chromeos/policy/device_status_collector.h"
 #include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h"
 #include "chrome/browser/chromeos/policy/remote_commands/user_commands_factory_chromeos.h"
-#include "chrome/browser/chromeos/policy/status_uploader.h"
 #include "chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.h"
 #include "chrome/browser/chromeos/policy/wildcard_login_checker.h"
-#include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/invalidation/profile_invalidation_provider_factory.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/net/system_network_context_manager.h"
@@ -39,7 +36,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_content_client.h"
 #include "chromeos/chromeos_switches.h"
-#include "chromeos/system/statistics_provider.h"
 #include "components/crash/core/common/crash_key.h"
 #include "components/invalidation/impl/profile_invalidation_provider.h"
 #include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
@@ -84,10 +80,6 @@
 const char kUMAInitialFetchOAuth2NetworkError[] =
     "Enterprise.UserPolicyChromeOS.InitialFetch.OAuth2NetworkError";
 
-// Default frequency for uploading non-enterprise status reports.
-constexpr base::TimeDelta kDeviceStatusUploadFrequency =
-    base::TimeDelta::FromMinutes(10);
-
 // This class is used to subscribe for notifications that the current profile is
 // being shut down.
 class UserCloudPolicyManagerChromeOSNotifierFactory
@@ -139,7 +131,6 @@
                                     PolicyEnforcement::kServerCheckRequired ||
                                 !policy_refresh_timeout.is_zero()),
       enforcement_type_(enforcement_type),
-      task_runner_(task_runner),
       account_id_(account_id),
       fatal_error_callback_(std::move(fatal_error_callback)) {
   DCHECK(profile_);
@@ -327,7 +318,6 @@
   if (service())
     service()->RemoveObserver(this);
   token_fetcher_.reset();
-  status_uploader_.reset();
   external_data_manager_->Disconnect();
   CloudPolicyManager::Shutdown();
 }
@@ -415,22 +405,6 @@
       CancelWaitForPolicyFetch(true);
     }
   }
-
-  // TODO(agawronska): Move StatusUploader creation to profile keyed
-  // service, where profile pref service is fully initialized.
-
-  // If child is registered with DMServer and has User Policy applied, it
-  // should upload device status to the server. For enterprise reporting
-  // status upload is controlled by DeviceCloudPolicyManagerChromeOS.
-  const user_manager::User* const user =
-      chromeos::ProfileHelper::Get()->GetUserByProfile(profile_);
-  if (client()->is_registered() && user &&
-      user->GetType() == user_manager::USER_TYPE_CHILD) {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::BindOnce(&UserCloudPolicyManagerChromeOS::CreateStatusUploader,
-                       base::Unretained(this)));
-  }
 }
 
 void UserCloudPolicyManagerChromeOS::OnClientError(
@@ -727,22 +701,4 @@
   shutdown_notifier_.reset();
 }
 
-void UserCloudPolicyManagerChromeOS::CreateStatusUploader() {
-  // Do not recreate status uploader if this is called multiple times.
-  if (status_uploader_)
-    return;
-
-  status_uploader_ = std::make_unique<StatusUploader>(
-      client(),
-      std::make_unique<DeviceStatusCollector>(
-          profile_->GetPrefs(),
-          chromeos::system::StatisticsProvider::GetInstance(),
-          DeviceStatusCollector::VolumeInfoFetcher(),
-          DeviceStatusCollector::CPUStatisticsFetcher(),
-          DeviceStatusCollector::CPUTempFetcher(),
-          DeviceStatusCollector::AndroidStatusFetcher(),
-          false /* is_enterprise_device */),
-      task_runner_, kDeviceStatusUploadFrequency);
-}
-
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h
index 99508ed..7c04d89f 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h
@@ -50,7 +50,6 @@
 class DeviceManagementService;
 class PolicyOAuth2TokenFetcher;
 class RemoteCommandsInvalidator;
-class StatusUploader;
 
 // Implements logic for initializing user policy on Chrome OS.
 class UserCloudPolicyManagerChromeOS : public CloudPolicyManager,
@@ -164,10 +163,6 @@
   // Helper function to force a policy fetch timeout.
   void ForceTimeoutForTest();
 
-  // Return the StatusUploader used to communicate consumer device status to the
-  // policy server.
-  StatusUploader* GetStatusUploader() const { return status_uploader_.get(); }
-
   // Sets a SharedURLLoaderFactory that should be used for tests instead of
   // retrieving one from the BrowserProcess object in FetchPolicyOAuthToken().
   void SetSystemURLLoaderFactoryForTests(
@@ -225,8 +220,6 @@
   // Observer called on profile shutdown.
   void ProfileShutdown();
 
-  void CreateStatusUploader();
-
   // Profile associated with the current user.
   Profile* const profile_;
 
@@ -267,12 +260,6 @@
   // Keeps alive the wildcard checker while its running.
   std::unique_ptr<WildcardLoginChecker> wildcard_login_checker_;
 
-  // Task runner used for non-enterprise device status upload.
-  scoped_refptr<base::SequencedTaskRunner> task_runner_;
-
-  // Helper object for updating the server with consumer device state.
-  std::unique_ptr<StatusUploader> status_uploader_;
-
   // The access token passed to OnAccessTokenAvailable. It is stored here so
   // that it can be used if OnInitializationCompleted is called later.
   std::string access_token_;
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
index 04024e2f..3eeb2a37 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
@@ -845,36 +845,4 @@
   EXPECT_TRUE(manager_->GetAppInstallEventLogUploader());
 }
 
-class ConsumerDeviceStatusUploadingTest
-    : public UserCloudPolicyManagerChromeOSTest {
- protected:
-  ConsumerDeviceStatusUploadingTest() = default;
-
-  ~ConsumerDeviceStatusUploadingTest() override = default;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ConsumerDeviceStatusUploadingTest);
-};
-
-TEST_F(ConsumerDeviceStatusUploadingTest, RegularAccountShouldNotUploadStatus) {
-  ASSERT_NO_FATAL_FAILURE(MakeManagerWithPreloadedStore(base::TimeDelta()));
-
-  manager_->OnRegistrationStateChanged(manager_->core()->client());
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_TRUE(manager_->core()->client()->is_registered());
-  EXPECT_FALSE(manager_->GetStatusUploader());
-}
-
-TEST_F(ConsumerDeviceStatusUploadingTest, ChildAccountShouldUploadStatus) {
-  AddAndSwitchToChildAccountWithProfile();
-  ASSERT_NO_FATAL_FAILURE(MakeManagerWithPreloadedStore(base::TimeDelta()));
-
-  manager_->OnRegistrationStateChanged(manager_->core()->client());
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_TRUE(manager_->core()->client()->is_registered());
-  EXPECT_TRUE(manager_->GetStatusUploader());
-}
-
 }  // namespace policy
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
index 50ddca24..bdd4bbc3 100644
--- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
@@ -54,7 +54,6 @@
 #include "components/offline_pages/buildflags/buildflags.h"
 #include "components/offline_pages/core/request_header/offline_page_navigation_ui_data.h"
 #include "components/policy/content/policy_blacklist_navigation_throttle.h"
-#include "components/policy/core/common/cloud/policy_header_io_helper.h"
 #include "components/previews/content/previews_content_util.h"
 #include "components/previews/content/previews_io_data.h"
 #include "components/previews/core/previews_decider.h"
@@ -427,9 +426,6 @@
     request->SetExtraRequestHeaders(headers);
   }
 
-  if (io_data->policy_header_helper())
-    io_data->policy_header_helper()->AddPolicyHeaders(request->url(), request);
-
   signin::ChromeRequestAdapter signin_request_adapter(request);
   signin::FixAccountConsistencyRequestHeader(
       &signin_request_adapter, GURL() /* redirect_url */, io_data);
@@ -684,9 +680,6 @@
   signin::ResponseAdapter signin_response_adapter(request);
   signin::ProcessAccountConsistencyResponseHeaders(
       &signin_response_adapter, redirect_url, io_data->IsOffTheRecord());
-
-  if (io_data->policy_header_helper())
-    io_data->policy_header_helper()->AddPolicyHeaders(redirect_url, request);
 }
 
 // Notification that a request has completed.
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_browsertest.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_browsertest.cc
index 45fc776..b50a1c6 100644
--- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_browsertest.cc
+++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_browsertest.cc
@@ -35,7 +35,6 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
-#include "components/policy/core/common/cloud/policy_header_io_helper.h"
 #include "components/policy/core/common/cloud/policy_header_service.h"
 #include "components/policy/core/common/policy_switches.h"
 #include "components/prefs/pref_service.h"
@@ -67,24 +66,9 @@
 
 namespace {
 
-static const char kTestPolicyHeader[] = "test_header";
-static const char kServerRedirectUrl[] = "/server-redirect";
-
 std::unique_ptr<net::test_server::HttpResponse> HandleTestRequest(
     const net::test_server::HttpRequest& request) {
-  if (base::StartsWith(request.relative_url, kServerRedirectUrl,
-                       base::CompareCase::SENSITIVE)) {
-    // Extract the target URL and redirect there.
-    size_t query_string_pos = request.relative_url.find('?');
-    std::string redirect_target =
-        request.relative_url.substr(query_string_pos + 1);
-
-    std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
-        new net::test_server::BasicHttpResponse);
-    http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
-    http_response->AddCustomHeader("Location", redirect_target);
-    return std::move(http_response);
-  } else if (request.relative_url == "/") {
+  if (request.relative_url == "/") {
     std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
         new net::test_server::BasicHttpResponse);
     http_response->set_code(net::HTTP_OK);
@@ -220,23 +204,6 @@
     embedded_test_server()->RegisterRequestHandler(
         base::Bind(&HandleTestRequest));
     ASSERT_TRUE(embedded_test_server()->Start());
-    // Tell chrome that this is our DM server.
-    dm_url_ = embedded_test_server()->GetURL("/DeviceManagement");
-
-    // At this point, the Profile is already initialized and it's too
-    // late to set the DMServer URL via command line flags, so directly
-    // inject it to the PolicyHeaderIOHelper.
-    policy::PolicyHeaderService* policy_header_service =
-        policy::PolicyHeaderServiceFactory::GetForBrowserContext(
-            browser()->profile());
-    std::vector<policy::PolicyHeaderIOHelper*> helpers =
-        policy_header_service->GetHelpersForTest();
-    for (std::vector<policy::PolicyHeaderIOHelper*>::const_iterator it =
-             helpers.begin();
-         it != helpers.end(); ++it) {
-      (*it)->SetServerURLForTest(dm_url_.spec());
-      (*it)->UpdateHeader(kTestPolicyHeader);
-    }
   }
 
   void TearDownOnMainThread() override {
@@ -263,52 +230,12 @@
   }
 
  protected:
-  // The fake URL for DMServer we are using.
-  GURL dm_url_;
   std::unique_ptr<TestDispatcherHostDelegate> dispatcher_host_delegate_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ChromeResourceDispatcherHostDelegateBrowserTest);
 };
 
-
-IN_PROC_BROWSER_TEST_F(ChromeResourceDispatcherHostDelegateBrowserTest,
-                       NoPolicyHeader) {
-  // When fetching non-DMServer URLs, we should not add a policy header to the
-  // request.
-  DCHECK(!embedded_test_server()->base_url().spec().empty());
-  ui_test_utils::NavigateToURL(browser(), embedded_test_server()->base_url());
-  ASSERT_FALSE(dispatcher_host_delegate_->request_headers().HasHeader(
-      policy::kChromePolicyHeader));
-}
-
-IN_PROC_BROWSER_TEST_F(ChromeResourceDispatcherHostDelegateBrowserTest,
-                       PolicyHeader) {
-  // When fetching a DMServer URL, we should add a policy header to the
-  // request.
-  ui_test_utils::NavigateToURL(browser(), dm_url_);
-  std::string value;
-  ASSERT_TRUE(dispatcher_host_delegate_->request_headers().GetHeader(
-      policy::kChromePolicyHeader, &value));
-  ASSERT_EQ(kTestPolicyHeader, value);
-}
-
-IN_PROC_BROWSER_TEST_F(ChromeResourceDispatcherHostDelegateBrowserTest,
-                       PolicyHeaderForRedirect) {
-  // Build up a URL that results in a redirect to the DMServer URL to make
-  // sure the policy header is still added.
-  std::string redirect_url;
-  redirect_url += kServerRedirectUrl;
-  redirect_url += "?";
-  redirect_url += dm_url_.spec();
-  ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL(
-      redirect_url));
-  std::string value;
-  ASSERT_TRUE(dispatcher_host_delegate_->request_headers().GetHeader(
-      policy::kChromePolicyHeader, &value));
-  ASSERT_EQ(kTestPolicyHeader, value);
-}
-
 IN_PROC_BROWSER_TEST_F(ChromeResourceDispatcherHostDelegateBrowserTest,
                        NavigationDataProcessed) {
   ui_test_utils::NavigateToURL(browser(), embedded_test_server()->base_url());
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index 96e1396..1dfb7a5 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -555,6 +555,13 @@
   web_contents()->GetRenderViewHost()->GetWidget()->RemoveInputEventObserver(
       this);
   web_contents()->GetRenderViewHost()->GetWidget()->AddInputEventObserver(this);
+#else
+  // Ensure that entries from old origins are properly cleaned up.
+  PasswordAccessoryController* password_accessory =
+      PasswordAccessoryController::FromWebContents(web_contents());
+  if (password_accessory) {
+    password_accessory->DidNavigateMainFrame();
+  }
 #endif
 }
 
@@ -654,7 +661,7 @@
 }
 
 void ChromePasswordManagerClient::SetTestObserver(
-    autofill::PasswordGenerationPopupObserver* observer) {
+    PasswordGenerationPopupObserver* observer) {
   observer_ = observer;
 }
 
@@ -704,14 +711,16 @@
       password_manager_client_bindings_.GetCurrentTargetFrame());
   DCHECK(driver);
   gfx::RectF element_bounds_in_screen_space = GetBoundsInScreenSpace(bounds);
-  popup_controller_ =
-      autofill::PasswordGenerationPopupControllerImpl::GetOrCreate(
-          popup_controller_, element_bounds_in_screen_space, form,
-          base::string16(),  // No generation_element needed for editing.
-          0,                 // Unspecified max length.
-          &password_manager_, driver->AsWeakPtr(), observer_, web_contents(),
-          web_contents()->GetNativeView());
-  popup_controller_->Show(false /* display_password */);
+  popup_controller_ = PasswordGenerationPopupControllerImpl::GetOrCreate(
+      popup_controller_, element_bounds_in_screen_space, form,
+      base::string16(),  // No generation_element needed for editing.
+      0,                 // Unspecified max length.
+      &password_manager_, driver->AsWeakPtr(), observer_, web_contents(),
+      web_contents()->GetNativeView());
+  DCHECK(!form.password_value.empty());
+  popup_controller_->UpdatePassword(form.password_value);
+  popup_controller_->Show(
+      PasswordGenerationPopupController::kEditGeneratedPassword);
 }
 
 void ChromePasswordManagerClient::GenerationAvailableForForm(
@@ -727,6 +736,9 @@
 
 void ChromePasswordManagerClient::PresaveGeneratedPassword(
     const autofill::PasswordForm& password_form) {
+  if (popup_controller_)
+    popup_controller_->UpdatePassword(password_form.password_value);
+
   password_manager_.OnPresaveGeneratedPassword(password_form);
 }
 
@@ -874,13 +886,12 @@
   gfx::RectF element_bounds_in_screen_space =
       GetBoundsInScreenSpace(ui_data.bounds);
 
-  popup_controller_ =
-      autofill::PasswordGenerationPopupControllerImpl::GetOrCreate(
-          popup_controller_, element_bounds_in_screen_space,
-          ui_data.password_form, ui_data.generation_element, ui_data.max_length,
-          &password_manager_, driver->AsWeakPtr(), observer_, web_contents(),
-          web_contents()->GetNativeView());
-  popup_controller_->Show(true /* display_password */);
+  popup_controller_ = PasswordGenerationPopupControllerImpl::GetOrCreate(
+      popup_controller_, element_bounds_in_screen_space, ui_data.password_form,
+      ui_data.generation_element, ui_data.max_length, &password_manager_,
+      driver->AsWeakPtr(), observer_, web_contents(),
+      web_contents()->GetNativeView());
+  popup_controller_->Show(PasswordGenerationPopupController::kOfferGeneration);
 }
 
 password_manager::PasswordManager*
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index d04d904e..3941e94 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -29,16 +29,15 @@
 #include "content/public/browser/web_contents_user_data.h"
 #include "ui/gfx/geometry/rect.h"
 
+class PasswordGenerationPopupObserver;
+class PasswordGenerationPopupControllerImpl;
 class Profile;
 
 namespace autofill {
-class PasswordGenerationPopupObserver;
-class PasswordGenerationPopupControllerImpl;
-
 namespace password_generation {
 struct PasswordGenerationUIData;
-}
-}
+}  // namespace password_generation
+}  // namespace autofill
 
 namespace content {
 class WebContents;
@@ -155,7 +154,7 @@
       autofill::AutofillClient* autofill_client);
 
   // Observer for PasswordGenerationPopup events. Used for testing.
-  void SetTestObserver(autofill::PasswordGenerationPopupObserver* observer);
+  void SetTestObserver(PasswordGenerationPopupObserver* observer);
 
   static void BindCredentialManager(
       password_manager::mojom::CredentialManagerRequest request,
@@ -234,11 +233,10 @@
       password_manager_client_bindings_;
 
   // Observer for password generation popup.
-  autofill::PasswordGenerationPopupObserver* observer_;
+  PasswordGenerationPopupObserver* observer_;
 
   // Controls the popup
-  base::WeakPtr<
-    autofill::PasswordGenerationPopupControllerImpl> popup_controller_;
+  base::WeakPtr<PasswordGenerationPopupControllerImpl> popup_controller_;
 
   // Set to false to disable password saving (will no longer ask if you
   // want to save passwords and also won't fill the passwords).
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index 86fc105..242b1da 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -149,6 +149,9 @@
       int key,
       const autofill::PasswordFormFillData& form_data) override {}
 
+  void FillIntoFocusedField(bool is_password,
+                            const base::string16& credential) override {}
+
   void SetLoggingState(bool active) override {
     called_set_logging_state_ = true;
     logging_state_active_ = active;
diff --git a/chrome/browser/password_manager/password_accessory_controller.cc b/chrome/browser/password_manager/password_accessory_controller.cc
index 9ea24e4..5af6fcd8 100644
--- a/chrome/browser/password_manager/password_accessory_controller.cc
+++ b/chrome/browser/password_manager/password_accessory_controller.cc
@@ -6,13 +6,20 @@
 
 #include <vector>
 
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/password_manager/password_accessory_view_interface.h"
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/autofill/content/browser/content_autofill_driver.h"
+#include "components/autofill/content/browser/content_autofill_driver_factory.h"
 #include "components/autofill/core/common/password_form.h"
+#include "components/password_manager/content/browser/content_password_manager_driver.h"
+#include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
 #include "components/strings/grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 
+#include "chrome/browser/android/preferences/preferences_launcher.h"
+
 using autofill::PasswordForm;
 using Item = PasswordAccessoryViewInterface::AccessoryItem;
 
@@ -20,14 +27,14 @@
 
 PasswordAccessoryController::PasswordAccessoryController(
     content::WebContents* web_contents)
-    : container_view_(web_contents->GetNativeView()),
+    : web_contents_(web_contents),
       view_(PasswordAccessoryViewInterface::Create(this)) {}
 
 // Additional creation functions in unit tests only:
 PasswordAccessoryController::PasswordAccessoryController(
     content::WebContents* web_contents,
     std::unique_ptr<PasswordAccessoryViewInterface> view)
-    : container_view_(web_contents->GetNativeView()), view_(std::move(view)) {}
+    : web_contents_(web_contents), view_(std::move(view)) {}
 
 PasswordAccessoryController::~PasswordAccessoryController() = default;
 
@@ -45,18 +52,22 @@
 void PasswordAccessoryController::OnPasswordsAvailable(
     const std::map<base::string16, const PasswordForm*>& best_matches,
     const GURL& origin) {
+  const url::Origin& tab_origin =
+      web_contents_->GetMainFrame()->GetLastCommittedOrigin();
+  if (!tab_origin.IsSameOriginWith(url::Origin::Create(origin))) {
+    // TODO(fhorschig): Support iframes: https://crbug.com/854150.
+    return;
+  }
   DCHECK(view_);
   std::vector<Item> items;
-  base::string16 passwords_title_str = l10n_util::GetStringUTF16(
-      IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_TITLE);
+  base::string16 passwords_title_str;
+  passwords_title_str = l10n_util::GetStringFUTF16(
+      best_matches.empty()
+          ? IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_EMPTY_MESSAGE
+          : IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_TITLE,
+      base::ASCIIToUTF16(origin.host()));
   items.emplace_back(passwords_title_str, passwords_title_str,
                      /*is_password=*/false, Item::Type::LABEL);
-  if (best_matches.empty()) {
-    base::string16 passwords_empty_str = l10n_util::GetStringUTF16(
-        IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_EMPTY_MESSAGE);
-    items.emplace_back(passwords_empty_str, passwords_empty_str,
-                       /*is_password=*/false, Item::Type::LABEL);
-  }
   for (const auto& pair : best_matches) {
     const PasswordForm* form = pair.second;
     base::string16 username = GetDisplayUsername(*form);
@@ -71,11 +82,38 @@
   view_->OnItemsAvailable(origin, items);
 }
 
+void PasswordAccessoryController::DidNavigateMainFrame() {
+  // Sending no passwords removes stale stuggestions and sends default options.
+  OnPasswordsAvailable(
+      /*best_matches=*/{},
+      web_contents_->GetMainFrame()->GetLastCommittedOrigin().GetURL());
+}
+
 void PasswordAccessoryController::OnFillingTriggered(
+    bool is_password,
     const base::string16& textToFill) const {
-  // TODO(fhorschig): Actually fill |textToFill| into focused field.
+  password_manager::ContentPasswordManagerDriverFactory* factory =
+      password_manager::ContentPasswordManagerDriverFactory::FromWebContents(
+          web_contents_);
+  DCHECK(factory);
+  // TODO(fhorschig): Consider allowing filling on non-main frames.
+  password_manager::ContentPasswordManagerDriver* driver =
+      factory->GetDriverForFrame(web_contents_->GetMainFrame());
+  if (!driver) {
+    return;
+  }  // |driver| can be NULL if the tab is being closed.
+  driver->FillIntoFocusedField(is_password, textToFill);
+}
+
+void PasswordAccessoryController::OnOptionSelected(
+    const base::string16& selectedOption) const {
+  if (selectedOption ==
+      l10n_util::GetStringUTF16(
+          IDS_PASSWORD_MANAGER_ACCESSORY_ALL_PASSWORDS_LINK)) {
+    chrome::android::PreferencesLauncher::ShowPasswordSettings();
+  }
 }
 
 gfx::NativeView PasswordAccessoryController::container_view() const {
-  return container_view_;
+  return web_contents_->GetNativeView();
 }
diff --git a/chrome/browser/password_manager/password_accessory_controller.h b/chrome/browser/password_manager/password_accessory_controller.h
index fe8963b..0a10a9af 100644
--- a/chrome/browser/password_manager/password_accessory_controller.h
+++ b/chrome/browser/password_manager/password_accessory_controller.h
@@ -32,6 +32,9 @@
 // by calling:
 //     PasswordAccessoryController::FromWebContents(web_contents);
 // Any further calls to |CreateForWebContents| will be a noop.
+//
+// TODO(fhorschig): This class currently only supports credentials originating
+// from the main frame. Supporting iframes is intended: https://crbug.com/854150
 class PasswordAccessoryController
     : public content::WebContentsUserData<PasswordAccessoryController> {
  public:
@@ -43,9 +46,16 @@
           best_matches,
       const GURL& origin);
 
+  // Send empty suggestions and default options to the view.
+  void DidNavigateMainFrame();
+
   // Called by the UI code to request that |textToFill| is to be filled into the
   // currently focused field.
-  void OnFillingTriggered(const base::string16& textToFill) const;
+  void OnFillingTriggered(bool is_password,
+                          const base::string16& textToFill) const;
+
+  // Called by the UI code because a user triggered the |selectedOption|.
+  void OnOptionSelected(const base::string16& selectedOption) const;
 
   // The web page view containing the focused field.
   gfx::NativeView container_view() const;
@@ -71,8 +81,8 @@
       content::WebContents* web_contents,
       std::unique_ptr<PasswordAccessoryViewInterface> view);
 
-  // The web page view this accessory sheet and the focused field live in.
-  const gfx::NativeView container_view_;
+  // The tab for which this class is scoped.
+  content::WebContents* web_contents_;
 
   // Hold the native instance of the view. Must be last declared and initialized
   // member so the view can be created in the constructor with a fully set up
diff --git a/chrome/browser/password_manager/password_accessory_controller_unittest.cc b/chrome/browser/password_manager/password_accessory_controller_unittest.cc
index eb195af..7dfe15f 100644
--- a/chrome/browser/password_manager/password_accessory_controller_unittest.cc
+++ b/chrome/browser/password_manager/password_accessory_controller_unittest.cc
@@ -22,6 +22,7 @@
 using base::ASCIIToUTF16;
 using base::UTF16ToASCII;
 using base::UTF16ToWide;
+using testing::_;
 using testing::ElementsAre;
 using testing::Eq;
 using testing::Mock;
@@ -31,6 +32,9 @@
 using AccessoryItem = PasswordAccessoryViewInterface::AccessoryItem;
 using ItemType = AccessoryItem::Type;
 
+constexpr char kExampleSite[] = "https://example.com";
+constexpr char kExampleDomain[] = "example.com";
+
 // The mock view mocks the platform-specific implementation. That also means
 // that we have to care about the lifespan of the Controller because that would
 // usually be responsibility of the view.
@@ -61,6 +65,12 @@
          PrintToString(static_cast<int>(type));
 }
 
+// Compares whether a given AccessoryItem is a label with the given text.
+MATCHER_P(MatchesLabel, text, PrintItem(text, text, false, ItemType::LABEL)) {
+  return arg.text == text && arg.is_password == false &&
+         arg.content_description == text && arg.itemType == ItemType::LABEL;
+}
+
 // Compares whether a given AccessoryItem had the given properties.
 MATCHER_P4(MatchesItem,
            text,
@@ -97,14 +107,15 @@
   return password_for_str(ASCIIToUTF16(user));
 }
 
-base::string16 passwords_empty_str() {
-  return l10n_util::GetStringUTF16(
-      IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_EMPTY_MESSAGE);
+base::string16 passwords_empty_str(const std::string& domain) {
+  return l10n_util::GetStringFUTF16(
+      IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_EMPTY_MESSAGE,
+      ASCIIToUTF16(domain));
 }
 
-base::string16 passwords_title_str() {
-  return l10n_util::GetStringUTF16(
-      IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_TITLE);
+base::string16 passwords_title_str(const std::string& domain) {
+  return l10n_util::GetStringFUTF16(
+      IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_TITLE, ASCIIToUTF16(domain));
 }
 
 base::string16 no_user_str() {
@@ -135,9 +146,11 @@
  public:
   void SetUp() override {
     ChromeRenderViewHostTestHarness::SetUp();
+    NavigateAndCommit(GURL(kExampleSite));
     PasswordAccessoryController::CreateForWebContentsForTesting(
         web_contents(),
         std::make_unique<StrictMock<MockPasswordAccessoryView>>());
+    NavigateAndCommit(GURL("https://example.com"));
   }
 
   PasswordAccessoryController* controller() {
@@ -162,44 +175,40 @@
   EXPECT_CALL(
       *view(),
       OnItemsAvailable(
-          GURL("https://example.com"),
+          GURL(kExampleSite),
           ElementsAre(
-              MatchesItem(ASCIIToUTF16("Passwords"), ASCIIToUTF16("Passwords"),
-                          false, ItemType::LABEL),
+              MatchesLabel(passwords_title_str(kExampleDomain)),
               MatchesItem(ASCIIToUTF16("Ben"), ASCIIToUTF16("Ben"), false,
                           ItemType::SUGGESTION),
               MatchesItem(ASCIIToUTF16("S3cur3"), password_for_str("Ben"), true,
                           ItemType::SUGGESTION))));
 
   controller()->OnPasswordsAvailable({CreateEntry("Ben", "S3cur3").first},
-                                     GURL("https://example.com"));
+                                     GURL(kExampleSite));
 }
 
 TEST_F(PasswordAccessoryControllerTest, HintsToEmptyUserNames) {
-  EXPECT_CALL(
-      *view(),
-      OnItemsAvailable(GURL("https://example.com"),
-                       ElementsAre(MatchesItem(ASCIIToUTF16("Passwords"),
-                                               ASCIIToUTF16("Passwords"), false,
-                                               ItemType::LABEL),
-                                   MatchesItem(no_user_str(), no_user_str(),
-                                               false, ItemType::SUGGESTION),
-                                   MatchesItem(ASCIIToUTF16("S3cur3"),
-                                               password_for_str(no_user_str()),
-                                               true, ItemType::SUGGESTION))));
+  EXPECT_CALL(*view(),
+              OnItemsAvailable(
+                  GURL(kExampleSite),
+                  ElementsAre(MatchesLabel(passwords_title_str(kExampleDomain)),
+                              MatchesItem(no_user_str(), no_user_str(), false,
+                                          ItemType::SUGGESTION),
+                              MatchesItem(ASCIIToUTF16("S3cur3"),
+                                          password_for_str(no_user_str()), true,
+                                          ItemType::SUGGESTION))));
 
   controller()->OnPasswordsAvailable({CreateEntry("", "S3cur3").first},
-                                     GURL("https://example.com"));
+                                     GURL(kExampleSite));
 }
 
 TEST_F(PasswordAccessoryControllerTest, SortsAlphabeticalDuringTransform) {
   EXPECT_CALL(
       *view(),
       OnItemsAvailable(
-          GURL("https://example.com"),
+          GURL(kExampleSite),
           ElementsAre(
-              MatchesItem(passwords_title_str(), passwords_title_str(), false,
-                          ItemType::LABEL),
+              MatchesLabel(passwords_title_str(kExampleDomain)),
 
               MatchesItem(ASCIIToUTF16("Alf"), ASCIIToUTF16("Alf"), false,
                           ItemType::SUGGESTION),
@@ -224,18 +233,38 @@
   controller()->OnPasswordsAvailable(
       {CreateEntry("Ben", "S3cur3").first, CreateEntry("Zebra", "M3h").first,
        CreateEntry("Alf", "PWD").first, CreateEntry("Cat", "M1@u").first},
-      GURL("https://example.com"));
+      GURL(kExampleSite));
+}
+
+TEST_F(PasswordAccessoryControllerTest, ClearsSuggestionsOnFrameNavigation) {
+  // Set any, non-empty password list.
+  EXPECT_CALL(*view(), OnItemsAvailable(GURL(kExampleSite), _));
+  controller()->OnPasswordsAvailable({CreateEntry("Ben", "S3cur3").first},
+                                     GURL(kExampleSite));
+
+  // Pretend that a navigation happened.
+  EXPECT_CALL(
+      *view(),
+      OnItemsAvailable(
+          GURL(kExampleSite),
+          ElementsAre(MatchesLabel(passwords_empty_str(kExampleDomain)))));
+
+  controller()->DidNavigateMainFrame();
 }
 
 TEST_F(PasswordAccessoryControllerTest, ProvidesEmptySuggestionsMessage) {
-  EXPECT_CALL(*view(), OnItemsAvailable(
-                           GURL("https://example.com"),
-                           ElementsAre(MatchesItem(ASCIIToUTF16("Passwords"),
-                                                   ASCIIToUTF16("Passwords"),
-                                                   false, ItemType::LABEL),
-                                       MatchesItem(passwords_empty_str(),
-                                                   passwords_empty_str(), false,
-                                                   ItemType::LABEL))));
+  EXPECT_CALL(
+      *view(),
+      OnItemsAvailable(
+          GURL(kExampleSite),
+          ElementsAre(MatchesLabel(passwords_empty_str(kExampleDomain)))));
 
-  controller()->OnPasswordsAvailable({}, GURL("https://example.com"));
+  controller()->OnPasswordsAvailable({}, GURL(kExampleSite));
+}
+
+TEST_F(PasswordAccessoryControllerTest, IgnoresCrossOriginCalls) {
+  // Don't expect any call to |OnItemsAvailable|. (https://crbug.com/854150)
+  EXPECT_CALL(*view(), OnItemsAvailable(_, _)).Times(0);
+  controller()->OnPasswordsAvailable({CreateEntry("Ben", "S3cur3").first},
+                                     GURL("https://other-domain.com"));
 }
diff --git a/chrome/browser/password_manager/password_generation_interactive_uitest.cc b/chrome/browser/password_manager/password_generation_interactive_uitest.cc
index b803f32..99ce4fb 100644
--- a/chrome/browser/password_manager/password_generation_interactive_uitest.cc
+++ b/chrome/browser/password_manager/password_generation_interactive_uitest.cc
@@ -29,26 +29,25 @@
 
 namespace {
 
-class TestPopupObserver : public autofill::PasswordGenerationPopupObserver {
+class TestPopupObserver : public PasswordGenerationPopupObserver {
  public:
-  TestPopupObserver()
-      : popup_showing_(false),
-        password_visible_(false) {}
-  virtual ~TestPopupObserver() {}
-
-  void OnPopupShown(bool password_visible) override {
+  void OnPopupShown(
+      PasswordGenerationPopupController::GenerationState state) override {
     popup_showing_ = true;
-    password_visible_ = password_visible;
+    state_ = state;
   }
 
   void OnPopupHidden() override { popup_showing_ = false; }
 
-  bool popup_showing() { return popup_showing_; }
-  bool password_visible() { return password_visible_; }
+  bool popup_showing() const { return popup_showing_; }
+  PasswordGenerationPopupController::GenerationState state() const {
+    return state_;
+  }
 
  private:
-  bool popup_showing_;
-  bool password_visible_;
+  bool popup_showing_ = false;
+  PasswordGenerationPopupController::GenerationState state_ =
+      PasswordGenerationPopupController::kOfferGeneration;
 };
 
 }  // namespace
@@ -130,11 +129,15 @@
   }
 
   bool GenerationPopupShowing() {
-    return observer_.popup_showing() && observer_.password_visible();
+    return observer_.popup_showing() &&
+           observer_.state() ==
+               PasswordGenerationPopupController::kOfferGeneration;
   }
 
   bool EditingPopupShowing() {
-    return observer_.popup_showing() && !observer_.password_visible();
+    return observer_.popup_showing() &&
+           observer_.state() ==
+               PasswordGenerationPopupController::kEditGeneratedPassword;
   }
 
  private:
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 09c3f29..e877532 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
@@ -54,6 +54,29 @@
     return pip_window_controller_;
   }
 
+  void LoadTabAndEnterPictureInPicture(Browser* browser) {
+    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_NE(nullptr, active_web_contents);
+
+    SetUpWindowController(active_web_contents);
+
+    ASSERT_TRUE(content::ExecuteScript(active_web_contents,
+                                       "enterPictureInPicture();"));
+
+    // Wait for confirmation that the window was created.
+    base::string16 expected_title = base::ASCIIToUTF16("1");
+    EXPECT_EQ(expected_title,
+              content::TitleWatcher(active_web_contents, expected_title)
+                  .WaitAndGetTitle());
+  }
+
  private:
   content::PictureInPictureWindowController* pip_window_controller_ = nullptr;
   base::test::ScopedFeatureList feature_list_;
@@ -598,6 +621,12 @@
           ? render_frame_hosts[1]
           : render_frame_hosts[0];
 
+  // Wait for video metadata to load.
+  base::string16 expected_title = base::ASCIIToUTF16("loadedmetadata");
+  EXPECT_EQ(expected_title,
+            content::TitleWatcher(active_web_contents, expected_title)
+                .WaitAndGetTitle());
+
   std::string result;
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(
       iframe, "enterPictureInPicture();", &result));
@@ -611,17 +640,8 @@
   EXPECT_FALSE(window_controller()->GetWindowForTesting()->IsVisible());
 }
 
-// Same as above for a cross-origin iframe.
-// Flaky on windows and Linux: crbug/854349
-#if defined(OS_WIN) || defined(OS_LINUX)
-#define MAYBE_CrossOriginFrameEnterLeaveCloseWindow \
-  DISABLED_CrossOriginFrameEnterLeaveCloseWindow
-#else
-#define MAYBE_CrossOriginFrameEnterLeaveCloseWindow \
-  CrossOriginFrameEnterLeaveCloseWindow
-#endif
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
-                       MAYBE_CrossOriginFrameEnterLeaveCloseWindow) {
+                       CrossOriginFrameEnterLeaveCloseWindow) {
   GURL embed_url = embedded_test_server()->GetURL(
       "a.com", "/media/picture-in-picture/iframe-content.html");
   GURL main_url = embedded_test_server()->GetURL(
@@ -645,6 +665,12 @@
           ? render_frame_hosts[1]
           : render_frame_hosts[0];
 
+  // Wait for video metadata to load.
+  base::string16 expected_title = base::ASCIIToUTF16("loadedmetadata");
+  EXPECT_EQ(expected_title,
+            content::TitleWatcher(active_web_contents, expected_title)
+                .WaitAndGetTitle());
+
   std::string result;
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(
       iframe, "enterPictureInPicture();", &result));
@@ -657,3 +683,20 @@
   EXPECT_EQ(1u, active_web_contents->GetAllFrames().size());
   EXPECT_FALSE(window_controller()->GetWindowForTesting()->IsVisible());
 }
+
+IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
+                       MultipleBrowserWindowOnePIPWindow) {
+  LoadTabAndEnterPictureInPicture(browser());
+
+  content::PictureInPictureWindowController* first_controller =
+      window_controller();
+  EXPECT_TRUE(first_controller->GetWindowForTesting()->IsVisible());
+
+  Browser* second_browser = CreateBrowser(browser()->profile());
+  LoadTabAndEnterPictureInPicture(second_browser);
+
+  content::PictureInPictureWindowController* second_controller =
+      window_controller();
+  EXPECT_FALSE(first_controller->GetWindowForTesting()->IsVisible());
+  EXPECT_TRUE(second_controller->GetWindowForTesting()->IsVisible());
+}
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc
new file mode 100644
index 0000000..b4a2701
--- /dev/null
+++ b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc
@@ -0,0 +1,76 @@
+// 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/picture_in_picture/picture_in_picture_window_manager.h"
+
+#include "content/public/browser/picture_in_picture_window_controller.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "ui/gfx/geometry/size.h"
+
+class PictureInPictureWindowManager::WebContentsDestroyedObserver
+    : public content::WebContentsObserver {
+ public:
+  WebContentsDestroyedObserver(PictureInPictureWindowManager* owner,
+                               content::WebContents* web_contents)
+      : content::WebContentsObserver(web_contents), owner_(owner) {}
+
+  ~WebContentsDestroyedObserver() final = default;
+
+  void WebContentsDestroyed() final { owner_->CloseWindowInternal(); }
+
+ private:
+  // Owns |this|.
+  PictureInPictureWindowManager* owner_ = nullptr;
+};
+
+PictureInPictureWindowManager* PictureInPictureWindowManager::GetInstance() {
+  return base::Singleton<PictureInPictureWindowManager>::get();
+}
+
+gfx::Size PictureInPictureWindowManager::EnterPictureInPicture(
+    content::WebContents* web_contents,
+    const viz::SurfaceId& surface_id,
+    const gfx::Size& natural_size) {
+  // If there was already a controller, close the existing window before
+  // creating the next one.
+  if (pip_window_controller_)
+    CloseWindowInternal();
+
+  // Create or update |pip_window_controller_| for the current WebContents.
+  if (!pip_window_controller_ ||
+      pip_window_controller_->GetInitiatorWebContents() != web_contents) {
+    CreateWindowInternal(web_contents);
+  }
+
+  pip_window_controller_->EmbedSurface(surface_id, natural_size);
+  return pip_window_controller_->Show();
+}
+
+void PictureInPictureWindowManager::ExitPictureInPicture() {
+  if (pip_window_controller_)
+    CloseWindowInternal();
+}
+
+void PictureInPictureWindowManager::CreateWindowInternal(
+    content::WebContents* web_contents) {
+  destroyed_observer_ =
+      std::make_unique<WebContentsDestroyedObserver>(this, web_contents);
+  pip_window_controller_ =
+      content::PictureInPictureWindowController::GetOrCreateForWebContents(
+          web_contents);
+}
+
+void PictureInPictureWindowManager::CloseWindowInternal() {
+  DCHECK(destroyed_observer_);
+  DCHECK(pip_window_controller_);
+
+  destroyed_observer_.reset();
+  pip_window_controller_->Close(false /* should_pause_video */);
+  pip_window_controller_ = nullptr;
+}
+
+PictureInPictureWindowManager::PictureInPictureWindowManager() = default;
+
+PictureInPictureWindowManager::~PictureInPictureWindowManager() = default;
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_manager.h b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.h
new file mode 100644
index 0000000..2d396c6
--- /dev/null
+++ b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.h
@@ -0,0 +1,61 @@
+// 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_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_WINDOW_MANAGER_H_
+#define CHROME_BROWSER_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_WINDOW_MANAGER_H_
+
+#include "base/memory/singleton.h"
+
+namespace content {
+class PictureInPictureWindowController;
+class WebContents;
+}  // namespace content
+
+namespace gfx {
+class Size;
+}  // namespace gfx
+
+namespace viz {
+class SurfaceId;
+}  // namespace viz
+
+// PictureInPictureWindowManager is a singleton that handles the lifetime of the
+// current Picture-in-Picture window and its PictureInPictureWindowController.
+// The class also guarantees that only one window will be present per Chrome
+// instances regardless of the number of windows, tabs, profiles, etc.
+class PictureInPictureWindowManager {
+ public:
+  // Returns the singleton instance.
+  static PictureInPictureWindowManager* GetInstance();
+
+  gfx::Size EnterPictureInPicture(content::WebContents*,
+                                  const viz::SurfaceId&,
+                                  const gfx::Size&);
+  void ExitPictureInPicture();
+
+ private:
+  friend struct base::DefaultSingletonTraits<PictureInPictureWindowManager>;
+  class WebContentsDestroyedObserver;
+
+  // Create a Picture-in-Picture window and register it in order to be closed
+  // when needed.
+  // This is suffixed with "Internal" because `CreateWindow` is part of the
+  // Windows API.
+  void CreateWindowInternal(content::WebContents*);
+
+  // Closes the active Picture-in-Picture window.
+  // There MUST be a window open.
+  // This is suffixed with "Internal" to keep consistency with the method above.
+  void CloseWindowInternal();
+
+  PictureInPictureWindowManager();
+  ~PictureInPictureWindowManager();
+
+  std::unique_ptr<WebContentsDestroyedObserver> destroyed_observer_;
+  content::PictureInPictureWindowController* pip_window_controller_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(PictureInPictureWindowManager);
+};
+
+#endif  // CHROME_BROWSER_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_WINDOW_MANAGER_H_
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 41dca0e7..5ccafc1 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -59,7 +59,6 @@
 #include "components/metrics/metrics_pref_names.h"
 #include "components/metrics/metrics_service.h"
 #include "components/net_log/chrome_net_log.h"
-#include "components/policy/core/common/cloud/policy_header_io_helper.h"
 #include "components/policy/core/common/cloud/policy_header_service.h"
 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
 #include "components/prefs/pref_service.h"
@@ -534,16 +533,6 @@
   }
 #endif
 
-  if (!IsOffTheRecord()) {
-    // Add policy headers for non-incognito requests.
-    policy::PolicyHeaderService* policy_header_service =
-        policy::PolicyHeaderServiceFactory::GetForBrowserContext(profile);
-    if (policy_header_service) {
-      policy_header_helper_ =
-          policy_header_service->CreatePolicyHeaderIOHelper(io_task_runner);
-    }
-  }
-
   incognito_availibility_pref_.Init(
       prefs::kIncognitoModeAvailability, pref_service);
   incognito_availibility_pref_.MoveToThread(io_task_runner);
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h
index d151eb60..1962574 100644
--- a/chrome/browser/profiles/profile_io_data.h
+++ b/chrome/browser/profiles/profile_io_data.h
@@ -82,7 +82,6 @@
 
 namespace policy {
 class PolicyCertVerifier;
-class PolicyHeaderIOHelper;
 }  // namespace policy
 
 namespace previews {
@@ -216,10 +215,6 @@
   }
 #endif
 
-  policy::PolicyHeaderIOHelper* policy_header_helper() const {
-    return policy_header_helper_.get();
-  }
-
   // Initialize the member needed to track the metrics enabled state. This is
   // only to be called on the UI thread.
   void InitializeMetricsEnabledStateOnUIThread();
@@ -577,9 +572,6 @@
 
   BooleanPrefMember enable_metrics_;
 
-  // Pointed to by NetworkDelegate.
-  mutable std::unique_ptr<policy::PolicyHeaderIOHelper> policy_header_helper_;
-
   // Pointed to by URLRequestContext.
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   mutable scoped_refptr<extensions::InfoMap> extension_info_map_;
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h
index a56683b2..5a81685d 100644
--- a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h
+++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h
@@ -101,6 +101,8 @@
     return site_characteristics_;
   }
 
+  size_t loaded_tabs_count_for_testing() const { return loaded_tabs_count_; }
+
   size_t loaded_tabs_in_background_count_for_testing() const {
     return loaded_tabs_in_background_count_;
   }
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.cc
index ae6c95d..7f7808e 100644
--- a/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.cc
+++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.cc
@@ -66,6 +66,8 @@
 void LocalSiteCharacteristicsDataWriter::NotifyUsesAudioInBackground() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK_EQ(TabVisibility::kBackground, tab_visibility_);
+  // TODO(sebmarchand): Do not advance the background audio observation time
+  // when the WebContents has never played audio.
   impl_->NotifyUsesAudioInBackground();
 }
 
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_database_browsertest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_database_browsertest.cc
new file mode 100644
index 0000000..0e6ce3da
--- /dev/null
+++ b/chrome/browser/resource_coordinator/local_site_characteristics_database_browsertest.cc
@@ -0,0 +1,551 @@
+// 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 <algorithm>
+
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "base/path_service.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/simple_test_tick_clock.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/history/history_service_factory.h"
+#include "chrome/browser/notifications/notification_permission_context.h"
+#include "chrome/browser/permissions/permission_request_manager.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h"
+#include "chrome/browser/resource_coordinator/local_site_characteristics_data_reader.h"
+#include "chrome/browser/resource_coordinator/local_site_characteristics_data_store_factory.h"
+#include "chrome/browser/resource_coordinator/site_characteristics_data_reader.h"
+#include "chrome/browser/resource_coordinator/tab_load_tracker.h"
+#include "chrome/browser/resource_coordinator/tab_manager_features.h"
+#include "chrome/browser/resource_coordinator/time.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/network_session_configurator/common/network_switches.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/public/test/web_contents_tester.h"
+#include "media/base/media_switches.h"
+#include "net/dns/mock_host_resolver.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/origin.h"
+
+#if defined(OS_CHROMEOS)
+#include "chromeos/chromeos_switches.h"
+#endif
+
+namespace resource_coordinator {
+
+namespace {
+
+using WebContents = content::WebContents;
+using WebContentsTester = content::WebContentsTester;
+
+constexpr char kTestPage[] =
+    "/resource_coordinator/site_characteristics_test_page.html";
+
+// Returns the longest feature observation window.
+base::TimeDelta GetLongestObservationWindow() {
+  const SiteCharacteristicsDatabaseParams& params =
+      GetStaticSiteCharacteristicsDatabaseParams();
+  return std::max({params.favicon_update_observation_window,
+                   params.title_update_observation_window,
+                   params.audio_usage_observation_window,
+                   params.notifications_usage_observation_window});
+}
+
+}  // namespace
+
+class LocalSiteCharacteristicsDatabaseTest : public InProcessBrowserTest {
+ public:
+  LocalSiteCharacteristicsDatabaseTest()
+      : scoped_set_tick_clock_for_testing_(&test_clock_),
+        test_server_(net::test_server::EmbeddedTestServer::TYPE_HTTPS) {}
+  ~LocalSiteCharacteristicsDatabaseTest() override = default;
+
+  void SetUp() override {
+    test_clock_.Advance(base::TimeDelta::FromSeconds(1));
+    scoped_feature_list_.InitAndEnableFeature(
+        features::kSiteCharacteristicsDatabase);
+    InProcessBrowserTest::SetUp();
+  }
+
+  void SetUpOnMainThread() override {
+    InProcessBrowserTest::SetUpOnMainThread();
+
+    // Setup the test server.
+    base::FilePath test_data_dir;
+    ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir));
+    test_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
+    test_server_.ServeFilesFromDirectory(
+        test_data_dir.AppendASCII("chrome/test/data/"));
+    ASSERT_TRUE(test_server_.InitializeAndListen());
+    test_server_.StartAcceptingConnections();
+    const std::string real_host = test_server_.host_port_pair().host();
+    host_resolver()->AddRule("*", real_host);
+  }
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    command_line->AppendSwitchASCII(
+        switches::kAutoplayPolicy,
+        switches::autoplay::kNoUserGestureRequiredPolicy);
+
+    // HTTPS server only serves a valid cert for localhost, so this is needed
+    // to load pages from other origins without an interstitial.
+    command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
+
+#if defined(OS_CHROMEOS)
+    command_line->AppendSwitch(
+        chromeos::switches::kIgnoreUserProfileMappingForTests);
+#endif
+    InProcessBrowserTest::SetUpCommandLine(command_line);
+  }
+
+  WebContents* GetActiveWebContents() {
+    return browser()->tab_strip_model()->GetActiveWebContents();
+  }
+
+  std::unique_ptr<SiteCharacteristicsDataReader> GetReaderForOrigin(
+      Profile* profile,
+      const url::Origin& origin) {
+    SiteCharacteristicsDataStore* data_store =
+        LocalSiteCharacteristicsDataStoreFactory::GetForProfile(profile);
+    EXPECT_TRUE(data_store);
+    std::unique_ptr<SiteCharacteristicsDataReader> reader =
+        data_store->GetReaderForOrigin(origin);
+
+    internal::LocalSiteCharacteristicsDataImpl* impl =
+        static_cast<LocalSiteCharacteristicsDataReader*>(reader.get())
+            ->impl_for_testing()
+            .get();
+    while (!impl->site_characteristics_for_testing().IsInitialized())
+      base::RunLoop().RunUntilIdle();
+    return reader;
+  }
+
+  // Test that feature usage is tracked correctly:
+  //   - kSiteFeatureUsageUnknown if never observed and observation window
+  //     hasn't expired.
+  //   - kSiteFeatureNotInUse if never observed and observation window has
+  //     expired.
+  //   - kSiteFeatureInUse if observed.
+  // |feature_detection_method| is the SiteCharacteristicsDataReader method that
+  // will be called to query the status of this feature. |triggering_closure| is
+  // the closure to run to cause this feature to be used (this will get called
+  // while the tab is in background) and |allowing_closure| is an optional
+  // closure that should run before testing the feature usage (to allow it to
+  // be used).
+  void TestFeatureUsageDetection(
+      SiteFeatureUsage (
+          SiteCharacteristicsDataReader::*feature_detection_method)() const,
+      base::RepeatingClosure triggering_closure,
+      base::RepeatingClosure allowing_closure = base::DoNothing::Repeatedly()) {
+    // Test that feature usage is tracked correctly before the expiration of its
+    // observation window.
+    TestFeatureUsageDetectionImpl(feature_detection_method, allowing_closure,
+                                  triggering_closure, false);
+    // Test that feature usage is tracked correctly after the expiration of its
+    // observation window.
+    TestFeatureUsageDetectionImpl(feature_detection_method,
+                                  std::move(allowing_closure),
+                                  std::move(triggering_closure), true);
+  }
+
+  void ExecuteScriptInMainFrame(const char* script) {
+    content::RenderFrameHost* main_frame =
+        GetActiveWebContents()->GetMainFrame();
+    EXPECT_TRUE(content::ExecuteScript(main_frame, script));
+  }
+
+  void PlayAudioInActiveWebContents() {
+    ExecuteScriptInMainFrame("PlayAudio();");
+  }
+
+  void ChangeTitleOfActiveWebContents() {
+    ExecuteScriptInMainFrame("ChangeTitle('new_title')");
+  }
+
+  void ChangeFaviconOfActiveWebContents() {
+    ExecuteScriptInMainFrame("ChangeFavicon()");
+  }
+
+  void TriggerNonPersistentNotificationInActiveWebContents() {
+    ExecuteScriptInMainFrame(
+        "DisplayAndCloseNonPersistentNotification('foo');");
+  }
+
+  // By default a tab has to play audio while being visible if it wants to be
+  // able to play audio in background (see
+  // ChromeContentRendererClient::DeferMediaLoad). This makes the current active
+  // WebContents visible, play some audio and background it. After calling
+  // this the background tab is allowed play audio.
+  void AllowBackgroundAudioInActiveTab() {
+    content::WebContents* active_webcontents = GetActiveWebContents();
+    active_webcontents->WasShown();
+    PlayAudioInActiveWebContents();
+
+    // Wait for the audio to start playing.
+    while (!active_webcontents->WasEverAudible())
+      base::RunLoop().RunUntilIdle();
+
+    active_webcontents->GetController().Reload(content::ReloadType::NORMAL,
+                                               false);
+    content::WaitForLoadStop(GetActiveWebContents());
+    // Background the tab and reload it so the audio will stop playing if it's
+    // still playing.
+    GetActiveWebContents()->WasHidden();
+  }
+
+  // Ensure that the current tab is allowed to display non-persistent
+  // notifications.
+  void AllowBackgroundNotificationInActiveTab() {
+    content::WebContents* web_contents = GetActiveWebContents();
+    NotificationPermissionContext::UpdatePermission(
+        browser()->profile(), web_contents->GetLastCommittedURL(),
+        CONTENT_SETTING_ALLOW);
+
+    ExecuteScriptInMainFrame("RequestNotificationsPermission();");
+  }
+
+  base::SimpleTestTickClock& test_clock() { return test_clock_; }
+  net::test_server::EmbeddedTestServer& test_server() { return test_server_; }
+
+ private:
+  void TestFeatureUsageDetectionImpl(
+      SiteFeatureUsage (
+          SiteCharacteristicsDataReader::*feature_detection_method)() const,
+      base::OnceClosure allowing_closure,
+      base::RepeatingClosure triggering_closure,
+      bool wait_for_observation_window_to_expire);
+
+  base::SimpleTestTickClock test_clock_;
+  ScopedSetTickClockForTesting scoped_set_tick_clock_for_testing_;
+  base::test::ScopedFeatureList scoped_feature_list_;
+  net::test_server::EmbeddedTestServer test_server_;
+
+  DISALLOW_COPY_AND_ASSIGN(LocalSiteCharacteristicsDatabaseTest);
+};
+
+void LocalSiteCharacteristicsDatabaseTest::TestFeatureUsageDetectionImpl(
+    SiteFeatureUsage (
+        SiteCharacteristicsDataReader::*feature_detection_method)() const,
+    base::OnceClosure allowing_closure,
+    base::RepeatingClosure triggering_closure,
+    bool wait_for_observation_window_to_expire) {
+  // Use a different origin depending on the type of test to make sure that
+  // previous observations don't get re-used.
+  const char* kOrigin =
+      wait_for_observation_window_to_expire ? "foo.com" : "bar.com";
+  GURL test_url(test_server_.GetURL(kOrigin, kTestPage));
+
+  // Get the reader for this origin.
+  auto reader =
+      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            (reader.get()->*feature_detection_method)());
+
+  // Navigate to the test url and background it.
+  ui_test_utils::NavigateToURLWithDisposition(
+      browser(), test_url, WindowOpenDisposition::CURRENT_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
+  GetActiveWebContents()->WasHidden();
+
+  // If needed, wait for all feature observation windows to expire.
+  if (wait_for_observation_window_to_expire) {
+    test_clock_.Advance(GetLongestObservationWindow());
+    EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse,
+              (reader.get()->*feature_detection_method)());
+  }
+
+  // Call the allowing closure.
+  std::move(allowing_closure).Run();
+
+  // Ensure that the closure hasn't caused the feature usage status to
+  // change.
+  if (wait_for_observation_window_to_expire) {
+    EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse,
+              (reader.get()->*feature_detection_method)());
+  } else {
+    EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+              (reader.get()->*feature_detection_method)());
+  }
+
+  // Cause the feature to be used.
+  triggering_closure.Run();
+
+  while ((reader.get()->*feature_detection_method)() !=
+         SiteFeatureUsage::kSiteFeatureInUse) {
+    base::RunLoop().RunUntilIdle();
+  }
+
+  // Advance the clock, make sure that the feature usage status doesn't
+  // change.
+  test_clock_.Advance(GetLongestObservationWindow());
+
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse,
+            (reader.get()->*feature_detection_method)());
+}
+
+// Test that doesn't use any feature.
+IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest, NoFeatureUsed) {
+  GURL test_url(test_server().GetURL("foo.com", kTestPage));
+
+  ui_test_utils::NavigateToURLWithDisposition(
+      browser(), test_url, WindowOpenDisposition::NEW_BACKGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
+
+  auto reader =
+      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            reader->UpdatesFaviconInBackground());
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            reader->UpdatesTitleInBackground());
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            reader->UsesAudioInBackground());
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            reader->UsesNotificationsInBackground());
+
+  test_clock().Advance(GetLongestObservationWindow());
+
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse,
+            reader->UpdatesFaviconInBackground());
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse,
+            reader->UpdatesTitleInBackground());
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse,
+            reader->UsesAudioInBackground());
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse,
+            reader->UsesNotificationsInBackground());
+}
+
+// Test that use features while in foreground, this shouldn't be recorded.
+IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
+                       FeatureUsedInForegroundOnly) {
+  GURL test_url(test_server().GetURL("foo.com", kTestPage));
+
+  ui_test_utils::NavigateToURLWithDisposition(
+      browser(), test_url, WindowOpenDisposition::CURRENT_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
+
+  GetActiveWebContents()->WasShown();
+
+  ChangeTitleOfActiveWebContents();
+  ChangeFaviconOfActiveWebContents();
+  PlayAudioInActiveWebContents();
+  // TODO(sebmarchand): Also trigger a background notification once.
+
+  auto reader =
+      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            reader->UpdatesFaviconInBackground());
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            reader->UpdatesTitleInBackground());
+
+  // Advance the clock while the tab is still in foreground and make sure that
+  // the state hasn't changed.
+  test_clock().Advance(GetLongestObservationWindow());
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            reader->UpdatesFaviconInBackground());
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            reader->UpdatesTitleInBackground());
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            reader->UsesAudioInBackground());
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            reader->UsesNotificationsInBackground());
+}
+
+// Test that the audio feature usage in background gets detected properly.
+IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
+                       AudioFeatureUsage) {
+  TestFeatureUsageDetection(
+      &SiteCharacteristicsDataReader::UsesAudioInBackground,
+      base::BindRepeating(
+          &LocalSiteCharacteristicsDatabaseTest::PlayAudioInActiveWebContents,
+          base::Unretained(this)),
+      base::BindRepeating(&LocalSiteCharacteristicsDatabaseTest::
+                              AllowBackgroundAudioInActiveTab,
+                          base::Unretained(this)));
+}
+
+// Test that the notification feature usage in background gets detected
+// properly.
+// TODO(sebmarchand): Figure out how to trigger a non-persistent notification in
+// this test.
+IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
+                       DISABLED_NotificationFeatureUsage) {
+  TestFeatureUsageDetection(
+      &SiteCharacteristicsDataReader::UsesNotificationsInBackground,
+      base::BindRepeating(
+          &LocalSiteCharacteristicsDatabaseTest::
+              TriggerNonPersistentNotificationInActiveWebContents,
+          base::Unretained(this)),
+      base::BindRepeating(&LocalSiteCharacteristicsDatabaseTest::
+                              AllowBackgroundNotificationInActiveTab,
+                          base::Unretained(this)));
+}
+
+IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
+                       TitleUpdateFeatureUsage) {
+  TestFeatureUsageDetection(
+      &SiteCharacteristicsDataReader::UpdatesTitleInBackground,
+      base::BindRepeating(
+          &LocalSiteCharacteristicsDatabaseTest::ChangeTitleOfActiveWebContents,
+          base::Unretained(this)));
+}
+
+// Test that the favicon update feature usage in background gets detected
+// properly.
+IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
+                       FaviconUpdateFeatureUsage) {
+  TestFeatureUsageDetection(
+      &SiteCharacteristicsDataReader::UpdatesFaviconInBackground,
+      base::BindRepeating(&LocalSiteCharacteristicsDatabaseTest::
+                              ChangeFaviconOfActiveWebContents,
+                          base::Unretained(this)));
+}
+
+// Test that loads the same origin into multiple tabs and ensure that they get
+// tracked properly.
+IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
+                       LoadedStateGetsTrackedProperly) {
+  GURL test_url(test_server().GetURL("foo.com", kTestPage));
+  auto test_reader =
+      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
+
+  const size_t kTabCount = 3;
+
+  // Load all the tabs and background them.
+  for (size_t i = 0; i < kTabCount; ++i) {
+    ui_test_utils::NavigateToURLWithDisposition(
+        browser(), test_url,
+        i == 0 ? WindowOpenDisposition::CURRENT_TAB
+               : WindowOpenDisposition::NEW_FOREGROUND_TAB,
+        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
+    EXPECT_EQ(TabLoadTracker::LoadingState::LOADED,
+              TabLoadTracker::Get()->GetLoadingState(
+                  browser()->tab_strip_model()->GetWebContentsAt(i)));
+    browser()->tab_strip_model()->GetWebContentsAt(i)->WasHidden();
+  }
+
+  internal::LocalSiteCharacteristicsDataImpl* impl =
+      static_cast<LocalSiteCharacteristicsDataReader*>(test_reader.get())
+          ->impl_for_testing()
+          .get();
+  EXPECT_TRUE(impl);
+  EXPECT_EQ(3U, impl->loaded_tabs_count_for_testing());
+  EXPECT_EQ(3U, impl->loaded_tabs_in_background_count_for_testing());
+
+  // Change the visibility of the tabs.
+  for (size_t i = 0; i < kTabCount; ++i) {
+    browser()->tab_strip_model()->GetWebContentsAt(i)->WasShown();
+
+    EXPECT_EQ(kTabCount, impl->loaded_tabs_count_for_testing());
+    EXPECT_EQ(kTabCount - (i + 1),
+              impl->loaded_tabs_in_background_count_for_testing());
+  }
+
+  for (size_t i = 0; i < kTabCount; ++i)
+    browser()->tab_strip_model()->GetWebContentsAt(i)->WasHidden();
+
+  EXPECT_EQ(3U, impl->loaded_tabs_in_background_count_for_testing());
+
+  // Close the tabs.
+  for (size_t i = 0; i < kTabCount; ++i) {
+    EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt(0, 0));
+    EXPECT_EQ(kTabCount - (i + 1), impl->loaded_tabs_count_for_testing());
+    EXPECT_EQ(kTabCount - (i + 1),
+              impl->loaded_tabs_in_background_count_for_testing());
+  }
+}
+
+// Ensure that the observations gets persisted on disk.
+IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
+                       PRE_DatabaseGetsPersisted) {
+  GURL test_url(test_server().GetURL("foo.com", kTestPage));
+
+  // Get the reader for this origin.
+  auto reader =
+      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            reader->UpdatesTitleInBackground());
+
+  // Navigate to the test url and background it.
+  ui_test_utils::NavigateToURLWithDisposition(
+      browser(), test_url, WindowOpenDisposition::CURRENT_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
+  GetActiveWebContents()->WasHidden();
+
+  // Cause the "title update in background" feature to be used.
+  ChangeTitleOfActiveWebContents();
+
+  while (reader->UpdatesTitleInBackground() !=
+         SiteFeatureUsage::kSiteFeatureInUse) {
+    base::RunLoop().RunUntilIdle();
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest,
+                       DatabaseGetsPersisted) {
+  GURL test_url(test_server().GetURL("foo.com", kTestPage));
+
+  // Get the reader for this origin.
+  auto reader =
+      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
+
+  // We should remember the observation made previously.
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse,
+            reader->UpdatesTitleInBackground());
+}
+
+// Ensure that clearing the history removes the observations from disk.
+IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest, PRE_ClearHistory) {
+  GURL test_url(test_server().GetURL("foo.com", kTestPage));
+
+  // Get the reader for this origin.
+  auto reader =
+      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            reader->UpdatesTitleInBackground());
+
+  // Navigate to the test url and background it.
+  ui_test_utils::NavigateToURLWithDisposition(
+      browser(), test_url, WindowOpenDisposition::CURRENT_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
+  GetActiveWebContents()->WasHidden();
+
+  // Cause the "title update in background" feature to be used.
+  ChangeTitleOfActiveWebContents();
+
+  while (reader->UpdatesTitleInBackground() !=
+         SiteFeatureUsage::kSiteFeatureInUse) {
+    base::RunLoop().RunUntilIdle();
+  }
+
+  HistoryServiceFactory::GetForProfile(browser()->profile(),
+                                       ServiceAccessType::IMPLICIT_ACCESS)
+      ->DeleteURL(test_url);
+  // The history gets cleared asynchronously.
+  while (reader->UpdatesTitleInBackground() !=
+         SiteFeatureUsage::kSiteFeatureUsageUnknown) {
+    base::RunLoop().RunUntilIdle();
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(LocalSiteCharacteristicsDatabaseTest, ClearHistory) {
+  GURL test_url(test_server().GetURL("foo.com", kTestPage));
+
+  // Get the reader for this origin.
+  auto reader =
+      GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url));
+
+  // The history has been cleared, we shouldn't know if this feature is used.
+  EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown,
+            reader->UpdatesTitleInBackground());
+}
+
+}  // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/page_signal_receiver.cc b/chrome/browser/resource_coordinator/page_signal_receiver.cc
index 9e663f9..a671edd4 100644
--- a/chrome/browser/resource_coordinator/page_signal_receiver.cc
+++ b/chrome/browser/resource_coordinator/page_signal_receiver.cc
@@ -84,7 +84,7 @@
 void PageSignalReceiver::AddObserver(PageSignalObserver* observer) {
   // When PageSignalReceiver starts to have observer, construct the mojo
   // channel.
-  if (!observers_.might_have_observers()) {
+  if (!binding_.is_bound()) {
     content::ServiceManagerConnection* service_manager_connection =
         content::ServiceManagerConnection::GetForProcess();
     // Ensure service_manager is active before trying to connect to it.
diff --git a/chrome/browser/resource_coordinator/page_signal_receiver_unittest.cc b/chrome/browser/resource_coordinator/page_signal_receiver_unittest.cc
index b974fde0..cf586c8a 100644
--- a/chrome/browser/resource_coordinator/page_signal_receiver_unittest.cc
+++ b/chrome/browser/resource_coordinator/page_signal_receiver_unittest.cc
@@ -5,6 +5,8 @@
 #include "chrome/browser/resource_coordinator/page_signal_receiver.h"
 
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/service_manager_connection.h"
 #include "content/public/test/web_contents_tester.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -79,4 +81,27 @@
       mojom::LifecycleState::kDiscarded);
 }
 
+// Regression test for crbug.com/855114.
+TEST_F(PageSignalReceiverUnitTest, ConstructMojoChannelOnce) {
+  // Create a dummy service manager.
+  service_manager::mojom::ServicePtr service;
+  content::ServiceManagerConnection::SetForProcess(
+      content::ServiceManagerConnection::Create(
+          mojo::MakeRequest(&service),
+          content::BrowserThread::GetTaskRunnerForThread(
+              content::BrowserThread::IO)));
+  // Add and remove an observer.
+  {
+    TestPageSignalObserver observer1(Action::kObserve, page_cu_id_,
+                                     page_signal_receiver_.get());
+  }
+  // Add and remove another observer. This causes the page signal receiver to
+  // construct the mojo channel again because the observer list is empty.
+  {
+    TestPageSignalObserver observer2(Action::kObserve, page_cu_id_,
+                                     page_signal_receiver_.get());
+  }
+  content::ServiceManagerConnection::DestroyForProcess();
+}
+
 }  // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/tab_helper.cc b/chrome/browser/resource_coordinator/tab_helper.cc
index 43b931e..1537f3b 100644
--- a/chrome/browser/resource_coordinator/tab_helper.cc
+++ b/chrome/browser/resource_coordinator/tab_helper.cc
@@ -27,6 +27,10 @@
 #include "services/resource_coordinator/public/mojom/service_constants.mojom.h"
 #include "services/service_manager/public/cpp/connector.h"
 
+#if !defined(OS_ANDROID)
+#include "chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.h"
+#endif
+
 DEFINE_WEB_CONTENTS_USER_DATA_KEY(
     resource_coordinator::ResourceCoordinatorTabHelper);
 
@@ -62,6 +66,14 @@
 
     TabMemoryMetricsReporter::Get()->StartReporting(TabLoadTracker::Get());
   }
+
+#if !defined(OS_ANDROID)
+  if (base::FeatureList::IsEnabled(features::kSiteCharacteristicsDatabase)) {
+    local_site_characteristics_wc_observer_ =
+        std::make_unique<LocalSiteCharacteristicsWebContentsObserver>(
+            web_contents);
+  }
+#endif
 }
 
 ResourceCoordinatorTabHelper::~ResourceCoordinatorTabHelper() = default;
diff --git a/chrome/browser/resource_coordinator/tab_helper.h b/chrome/browser/resource_coordinator/tab_helper.h
index 16bebcd6..6bcdb20 100644
--- a/chrome/browser/resource_coordinator/tab_helper.h
+++ b/chrome/browser/resource_coordinator/tab_helper.h
@@ -9,6 +9,7 @@
 
 #include "base/macros.h"
 #include "base/time/time.h"
+#include "build/build_config.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
 #include "services/metrics/public/cpp/ukm_source_id.h"
@@ -17,6 +18,7 @@
 namespace resource_coordinator {
 
 class PageResourceCoordinator;
+class LocalSiteCharacteristicsWebContentsObserver;
 
 class ResourceCoordinatorTabHelper
     : public content::WebContentsObserver,
@@ -63,6 +65,11 @@
       page_resource_coordinator_;
   ukm::SourceId ukm_source_id_ = ukm::kInvalidSourceId;
 
+#if !defined(OS_ANDROID)
+  std::unique_ptr<LocalSiteCharacteristicsWebContentsObserver>
+      local_site_characteristics_wc_observer_;
+#endif
+
   // Favicon and title are set when a page is loaded, we only want to send
   // signals to GRC about title and favicon update from the previous title and
   // favicon, thus we want to ignore the very first update since it is always
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc
index ac2b4d61..8075180 100644
--- a/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc
+++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc
@@ -142,19 +142,6 @@
   }
 }
 
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused.
-enum class BloatedRendererHandlingInBrowser {
-  kReloaded = 0,
-  kCannotReload = 1,
-  kCannotShutdown = 2,
-  kMaxValue = kCannotShutdown
-};
-
-void RecordBloatedRendererHandling(BloatedRendererHandlingInBrowser handling) {
-  UMA_HISTOGRAM_ENUMERATION("BloatedRenderer.HandlingInBrowser", handling);
-}
-
 }  // namespace
 
 TabLifecycleUnitSource::TabLifecycleUnit::TabLifecycleUnit(
@@ -677,54 +664,6 @@
   return Discard(DiscardReason::kExternal);
 }
 
-bool TabLifecycleUnitSource::TabLifecycleUnit::CanReloadBloatedTab() {
-  // Can't reload a tab that isn't in a TabStripModel, which is needed for
-  // showing an infobar.
-  if (!tab_strip_model_)
-    return false;
-
-  if (GetWebContents()->IsCrashed())
-    return false;
-
-  // Do not reload tabs that don't have a valid URL (most probably they have
-  // just been opened and discarding them would lose the URL).
-  if (!GetWebContents()->GetLastCommittedURL().is_valid() ||
-      GetWebContents()->GetLastCommittedURL().is_empty()) {
-    return false;
-  }
-
-  // Do not reload tabs in which the user has entered text in a form.
-  if (GetWebContents()->GetPageImportanceSignals().had_form_interaction)
-    return false;
-
-  // TODO(ulan): Check if the navigation controller has POST data.
-
-  return true;
-}
-
-void TabLifecycleUnitSource::TabLifecycleUnit::ReloadBloatedTab() {
-  if (CanReloadBloatedTab()) {
-    const size_t expected_page_count = 1u;
-    const bool skip_unload_handlers = true;
-    if (GetRenderProcessHost()->FastShutdownIfPossible(expected_page_count,
-                                                       skip_unload_handlers)) {
-      // TODO(ulan): Notify the WebContents that the page is bloated to give
-      // it a chance to show the infobar after the reload.
-      const bool check_for_repost = true;
-      GetWebContents()->GetController().Reload(content::ReloadType::NORMAL,
-                                               check_for_repost);
-      RecordBloatedRendererHandling(
-          BloatedRendererHandlingInBrowser::kReloaded);
-    } else {
-      RecordBloatedRendererHandling(
-          BloatedRendererHandlingInBrowser::kCannotShutdown);
-    }
-  } else {
-    RecordBloatedRendererHandling(
-        BloatedRendererHandlingInBrowser::kCannotReload);
-  }
-}
-
 bool TabLifecycleUnitSource::TabLifecycleUnit::IsDiscarded() const {
   // External code does not need to know about the intermediary PENDING_DISCARD
   // state. To external callers, the tab is discarded while in the
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit.h b/chrome/browser/resource_coordinator/tab_lifecycle_unit.h
index 3639fe1..58180ff 100644
--- a/chrome/browser/resource_coordinator/tab_lifecycle_unit.h
+++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit.h
@@ -5,7 +5,6 @@
 #ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_LIFECYCLE_UNIT_H_
 #define CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_LIFECYCLE_UNIT_H_
 
-#include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/observer_list.h"
 #include "base/time/time.h"
@@ -78,10 +77,6 @@
   // unit.
   void UpdateLifecycleState(mojom::LifecycleState state);
 
-  // Reloads the tab because its renderer is bloated and shows an infobar
-  // explaining that it was reloaded because it ran out of memory.
-  void ReloadBloatedTab();
-
   // LifecycleUnit:
   TabLifecycleUnitExternal* AsTabLifecycleUnitExternal() override;
   base::string16 GetTitle() const override;
@@ -118,13 +113,6 @@
   friend class TabLifecycleUnitSource;
 
  private:
-  FRIEND_TEST_ALL_PREFIXES(TabLifecycleUnitTest, CanReloadBloatedTab);
-  FRIEND_TEST_ALL_PREFIXES(TabLifecycleUnitTest, CannotReloadBloatedTabCrashed);
-  FRIEND_TEST_ALL_PREFIXES(TabLifecycleUnitTest,
-                           CannotReloadBloatedTabInvalidURL);
-  FRIEND_TEST_ALL_PREFIXES(TabLifecycleUnitTest,
-                           CannotReloadBloatedTabPendingUserInteraction);
-
   // Determines if the tab is a media tab, and populates an optional
   // |decision_details| with full details.
   bool IsMediaTabImpl(DecisionDetails* decision_details) const;
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit_source.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit_source.cc
index fb88b208..a93468c8 100644
--- a/chrome/browser/resource_coordinator/tab_lifecycle_unit_source.cc
+++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit_source.cc
@@ -229,11 +229,6 @@
     lifecycle_unit->UpdateLifecycleState(state);
 }
 
-void TabLifecycleUnitSource::OnRendererIsBloated(
-    content::WebContents* web_contents) {
-  GetTabLifecycleUnit(web_contents)->ReloadBloatedTab();
-}
-
 }  // namespace resource_coordinator
 
 DEFINE_WEB_CONTENTS_USER_DATA_KEY(
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit_source.h b/chrome/browser/resource_coordinator/tab_lifecycle_unit_source.h
index d9ec07a..64952f29 100644
--- a/chrome/browser/resource_coordinator/tab_lifecycle_unit_source.h
+++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit_source.h
@@ -114,7 +114,6 @@
   // PageSignalObserver:
   void OnLifecycleStateChanged(content::WebContents* web_contents,
                                mojom::LifecycleState state) override;
-  void OnRendererIsBloated(content::WebContents* web_contents) override;
 
   // Tracks the BrowserList and all TabStripModels.
   BrowserTabStripTracker browser_tab_strip_tracker_;
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc
index 5e927d0..61a8fc92 100644
--- a/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc
+++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc
@@ -334,39 +334,4 @@
   tab_lifecycle_unit.RemoveObserver(&observer);
 }
 
-TEST_F(TabLifecycleUnitTest, CanReloadBloatedTab) {
-  TabLifecycleUnit tab_lifecycle_unit(&observers_, web_contents_,
-                                      tab_strip_model_.get());
-  EXPECT_TRUE(tab_lifecycle_unit.CanReloadBloatedTab());
-}
-
-TEST_F(TabLifecycleUnitTest, CannotReloadBloatedTabCrashed) {
-  TabLifecycleUnit tab_lifecycle_unit(&observers_, web_contents_,
-                                      tab_strip_model_.get());
-
-  web_contents_->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, 0);
-
-  EXPECT_FALSE(tab_lifecycle_unit.CanReloadBloatedTab());
-}
-
-TEST_F(TabLifecycleUnitTest, CannotReloadBloatedTabInvalidURL) {
-  TabLifecycleUnit tab_lifecycle_unit(&observers_, web_contents_,
-                                      tab_strip_model_.get());
-
-  content::WebContentsTester::For(web_contents_)
-      ->SetLastCommittedURL(GURL("invalid :)"));
-
-  EXPECT_FALSE(tab_lifecycle_unit.CanReloadBloatedTab());
-}
-
-TEST_F(TabLifecycleUnitTest, CannotReloadBloatedTabPendingUserInteraction) {
-  TabLifecycleUnit tab_lifecycle_unit(&observers_, web_contents_,
-                                      tab_strip_model_.get());
-  content::PageImportanceSignals signals;
-  signals.had_form_interaction = true;
-  content::WebContentsTester::For(web_contents_)
-      ->SetPageImportanceSignals(signals);
-  EXPECT_FALSE(tab_lifecycle_unit.CanReloadBloatedTab());
-}
-
 }  // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
index f5c527f..3bfff893 100644
--- a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
@@ -266,12 +266,6 @@
         ->UpdateLifecycleState(mojom::LifecycleState::kFrozen);
   }
 
-  void ReloadBloatedTab(content::WebContents* contents) {
-    static_cast<TabLifecycleUnitSource::TabLifecycleUnit*>(
-        TabLifecycleUnitExternal::FromWebContents(contents))
-        ->ReloadBloatedTab();
-  }
-
   TabManager* tab_manager() { return g_browser_process->GetTabManager(); }
   TabStripModel* tsm() { return browser()->tab_strip_model(); }
 
@@ -1311,24 +1305,6 @@
   EXPECT_TRUE(IsTabDiscarded(browser4->tab_strip_model()->GetWebContentsAt(1)));
 }
 
-// TODO(ulan): Enable the test after fixing crbug.com/850921.
-IN_PROC_BROWSER_TEST_F(TabManagerTest, DISABLED_ReloadBloatedTab) {
-  content::WindowedNotificationObserver load(
-      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
-      content::NotificationService::AllSources());
-  OpenURLParams url(GURL(chrome::kChromeUIAboutURL), content::Referrer(),
-                    WindowOpenDisposition::CURRENT_TAB,
-                    ui::PAGE_TRANSITION_TYPED, false);
-  browser()->OpenURL(url);
-  load.Wait();
-
-  content::WindowedNotificationObserver reload(
-      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
-      content::NotificationService::AllSources());
-  ReloadBloatedTab(GetWebContentsAt(0));
-  reload.Wait();
-}
-
 }  // namespace resource_coordinator
 
 #endif  // OS_WIN || OS_MAXOSX || OS_LINUX || defined(OS_CHROMEOS)
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js
index 41c560e..915a4c4 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js
@@ -972,6 +972,11 @@
   if (!textEditHandler)
     return true;
 
+  // Skip customized keys for read only text fields.
+  if (textEditHandler.node.restriction ==
+      chrome.automation.Restriction.READ_ONLY)
+    return true;
+
   var isMultiline = AutomationPredicate.multiline(current.start.node);
   switch (command) {
     case 'previousCharacter':
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
index 1f701b1..9a772ee 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
@@ -621,9 +621,6 @@
             !AutomationUtil.isDescendantOf(target, voxTarget))
       return false;
 
-    if (target.restriction == chrome.automation.Restriction.READ_ONLY)
-      return false;
-
     if (!this.textEditHandler_ || this.textEditHandler_.node !== target) {
       this.textEditHandler_ = editing.TextEditHandler.createForNode(target);
     }
diff --git a/chrome/browser/resources/settings/a11y_page/tts_subpage.html b/chrome/browser/resources/settings/a11y_page/tts_subpage.html
index 4c1dca4..565e224 100644
--- a/chrome/browser/resources/settings/a11y_page/tts_subpage.html
+++ b/chrome/browser/resources/settings/a11y_page/tts_subpage.html
@@ -54,7 +54,7 @@
           ticks="[[speechPitchTicks_()]]"
           min-label="$i18n{textToSpeechPitchMinimumLabel}"
           max-label="$i18n{textToSpeechPitchMaximumLabel}"
-          aria-describeby="pitch">
+          aria-describedby="pitch">
       </display-size-slider>
     </div>
     <div class="settings-box continuation">
diff --git a/chrome/browser/resources/settings/site_settings/BUILD.gn b/chrome/browser/resources/settings/site_settings/BUILD.gn
index c9332a9..b7d2dca 100644
--- a/chrome/browser/resources/settings/site_settings/BUILD.gn
+++ b/chrome/browser/resources/settings/site_settings/BUILD.gn
@@ -19,6 +19,7 @@
     ":site_data_details_subpage",
     ":site_details",
     ":site_details_permission",
+    ":site_entry",
     ":site_list",
     ":site_settings_behavior",
     ":site_settings_prefs_browser_proxy",
@@ -170,6 +171,20 @@
   ]
 }
 
+js_library("site_entry") {
+  deps = [
+    ":constants",
+    ":site_settings_behavior",
+    "..:route",
+    "//third_party/polymer/v1_0/components-chromium/iron-collapse:iron-collapse-extracted",
+    "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu",
+    "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render",
+    "//ui/webui/resources/js:assert",
+    "//ui/webui/resources/js:cr",
+    "//ui/webui/resources/js:load_time_data",
+  ]
+}
+
 js_library("site_list") {
   deps = [
     ":constants",
diff --git a/chrome/browser/resources/settings/site_settings/all_sites.js b/chrome/browser/resources/settings/site_settings/all_sites.js
index 2a395bcf..f3b611f6 100644
--- a/chrome/browser/resources/settings/site_settings/all_sites.js
+++ b/chrome/browser/resources/settings/site_settings/all_sites.js
@@ -40,42 +40,11 @@
    */
   populateList_: function() {
     /** @type {!Array<settings.ContentSettingsTypes>} */
-    let contentTypes = [];
-    const types = Object.values(settings.ContentSettingsTypes);
-    for (let i = 0; i < types.length; ++i) {
-      const type = types[i];
-      // <if expr="not chromeos">
-      if (type == settings.ContentSettingsTypes.PROTECTED_CONTENT)
-        continue;
-      // </if>
-      // Some categories store their data in a custom way.
-      if (type == settings.ContentSettingsTypes.PROTOCOL_HANDLERS ||
-          type == settings.ContentSettingsTypes.ZOOM_LEVELS) {
-        continue;
-      }
-      // These categories are gated behind flags.
-      if (type == settings.ContentSettingsTypes.SENSORS &&
-          !loadTimeData.getBoolean('enableSensorsContentSetting')) {
-        continue;
-      }
-      if (type == settings.ContentSettingsTypes.ADS &&
-          !loadTimeData.getBoolean('enableSafeBrowsingSubresourceFilter')) {
-        continue;
-      }
-      if (type == settings.ContentSettingsTypes.SOUND &&
-          !loadTimeData.getBoolean('enableSoundContentSetting')) {
-        continue;
-      }
-      if (type == settings.ContentSettingsTypes.CLIPBOARD &&
-          !loadTimeData.getBoolean('enableClipboardContentSetting')) {
-        continue;
-      }
-      if (type == settings.ContentSettingsTypes.PAYMENT_HANDLER &&
-          !loadTimeData.getBoolean('enablePaymentHandlerContentSetting')) {
-        continue;
-      }
-      contentTypes.push(type);
-    }
+    const contentTypes = this.getCategoryList();
+    // Make sure to include cookies, because All Sites handles data storage +
+    // cookies as well as regular settings.ContentSettingsTypes.
+    if (!contentTypes.includes(settings.ContentSettingsTypes.COOKIES))
+      contentTypes.push(settings.ContentSettingsTypes.COOKIES);
 
     this.browserProxy_.getAllSites(contentTypes).then((response) => {
       this.siteGroupList = response;
diff --git a/chrome/browser/resources/settings/site_settings/site_details.html b/chrome/browser/resources/settings/site_settings/site_details.html
index dfbb6fff..ab798c7 100644
--- a/chrome/browser/resources/settings/site_settings/site_details.html
+++ b/chrome/browser/resources/settings/site_settings/site_details.html
@@ -116,8 +116,7 @@
       <site-details-permission
           category="{{ContentSettingsTypes.SENSORS}}"
           icon="settings:sensors" id="sensors"
-          label="$i18n{siteSettingsSensors}"
-          hidden$="[[!enableSensorsContentSetting_]]">
+          label="$i18n{siteSettingsSensors}">
       </site-details-permission>
       <site-details-permission category="{{ContentSettingsTypes.NOTIFICATIONS}}"
           icon="settings:notifications" id="notifications"
@@ -139,8 +138,7 @@
       <site-details-permission
           category="{{ContentSettingsTypes.ADS}}"
           icon="settings:ads" id="ads"
-          label="$i18n{siteSettingsAds}"
-          hidden$="[[!enableSafeBrowsingSubresourceFilter_]]">
+          label="$i18n{siteSettingsAds}">
       </site-details-permission>
       <site-details-permission
           category="{{ContentSettingsTypes.BACKGROUND_SYNC}}"
@@ -149,8 +147,7 @@
       </site-details-permission>
       <site-details-permission category="{{ContentSettingsTypes.SOUND}}"
           icon="settings:volume-up" id="sound"
-          label="$i18n{siteSettingsSound}"
-          hidden$="[[!enableSoundContentSetting_]]">
+          label="$i18n{siteSettingsSound}">
       </site-details-permission>
       <site-details-permission
           category="{{ContentSettingsTypes.AUTOMATIC_DOWNLOADS}}"
@@ -180,14 +177,12 @@
       <site-details-permission
           category="{{ContentSettingsTypes.CLIPBOARD}}"
           icon="settings:clipboard" id="clipboard"
-          label="$i18n{siteSettingsClipboard}"
-          hidden$="[[!enableClipboardContentSetting_]]">
+          label="$i18n{siteSettingsClipboard}">
       </site-details-permission>
       <site-details-permission
           category="{{ContentSettingsTypes.PAYMENT_HANDLER}}"
           icon="settings:payment-handler" id="paymentHandler"
-          label="$i18n{siteSettingsPaymentHandler}"
-          hidden$="[[!enablePaymentHandlerContentSetting_]]">
+          label="$i18n{siteSettingsPaymentHandler}">
       </site-details-permission>
     </div>
 
diff --git a/chrome/browser/resources/settings/site_settings/site_details.js b/chrome/browser/resources/settings/site_settings/site_details.js
index a264b52..155cc28 100644
--- a/chrome/browser/resources/settings/site_settings/site_details.js
+++ b/chrome/browser/resources/settings/site_settings/site_details.js
@@ -51,47 +51,6 @@
       },
     },
 
-    /** @private */
-    enableSafeBrowsingSubresourceFilter_: {
-      type: Boolean,
-      value: function() {
-        return loadTimeData.getBoolean('enableSafeBrowsingSubresourceFilter');
-      },
-    },
-
-    /** @private */
-    enableSoundContentSetting_: {
-      type: Boolean,
-      value: function() {
-        return loadTimeData.getBoolean('enableSoundContentSetting');
-      },
-    },
-
-    /** @private */
-    enableClipboardContentSetting_: {
-      type: Boolean,
-      value: function() {
-        return loadTimeData.getBoolean('enableClipboardContentSetting');
-      },
-    },
-
-    /** @private */
-    enableSensorsContentSetting_: {
-      type: Boolean,
-      readOnly: true,
-      value: function() {
-        return loadTimeData.getBoolean('enableSensorsContentSetting');
-      },
-    },
-
-    /** @private */
-    enablePaymentHandlerContentSetting_: {
-      type: Boolean,
-      value: function() {
-        return loadTimeData.getBoolean('enablePaymentHandlerContentSetting');
-      },
-    },
-
     /**
      * The type of storage for the origin.
      * @private
@@ -144,7 +103,7 @@
         if (this.enableSiteSettings_)
           this.$.usageApi.fetchUsageTotal(this.toUrl(this.origin).hostname);
 
-        this.updatePermissions_(this.getCategoryList_());
+        this.updatePermissions_(this.getCategoryList());
       }
     });
   },
@@ -162,7 +121,7 @@
         origin === undefined || origin == '') {
       return;
     }
-    if (!this.getCategoryList_().includes(category))
+    if (!this.getCategoryList().includes(category))
       return;
 
     // Site details currently doesn't support embedded origins, so ignore it and
@@ -239,20 +198,20 @@
    * Resets all permissions for the current origin.
    * @private
    */
-  onResetSettings_: function() {
+  onResetSettings_: function(e) {
     this.browserProxy.setOriginPermissions(
-        this.origin, this.getCategoryList_(), settings.ContentSetting.DEFAULT);
-    if (this.getCategoryList_().includes(settings.ContentSettingsTypes.PLUGINS))
+        this.origin, this.getCategoryList(), settings.ContentSetting.DEFAULT);
+    if (this.getCategoryList().includes(settings.ContentSettingsTypes.PLUGINS))
       this.browserProxy.clearFlashPref(this.origin);
 
-    this.$.confirmResetSettings.close();
+    this.onCloseDialog_(e);
   },
 
   /**
    * Clears all data stored, except cookies, for the current origin.
    * @private
    */
-  onClearStorage_: function() {
+  onClearStorage_: function(e) {
     // Since usage is only shown when "Site Settings" is enabled, don't clear it
     // when it's not shown.
     if (this.enableSiteSettings_ && this.storedData_ != '') {
@@ -260,7 +219,7 @@
           this.toUrl(this.origin).href, this.storageType_);
     }
 
-    this.$.confirmClearStorage.close();
+    this.onCloseDialog_(e);
   },
 
   /**
@@ -275,20 +234,6 @@
   },
 
   /**
-   * Returns list of categories for each permission displayed in <site-details>.
-   * @return {!Array<!settings.ContentSettingsTypes>}
-   * @private
-   */
-  getCategoryList_: function() {
-    const categoryList = [];
-    this.root.querySelectorAll('site-details-permission').forEach((element) => {
-      if (!element.hidden)
-        categoryList.push(element.category);
-    });
-    return categoryList;
-  },
-
-  /**
    * Checks whether the permission list is standalone or has a heading.
    * @return {string} CSS class applied when the permission list has no heading.
    * @private
diff --git a/chrome/browser/resources/settings/site_settings/site_details_permission.html b/chrome/browser/resources/settings/site_settings/site_details_permission.html
index e2a3019..76881dc 100644
--- a/chrome/browser/resources/settings/site_settings/site_details_permission.html
+++ b/chrome/browser/resources/settings/site_settings/site_details_permission.html
@@ -12,7 +12,7 @@
 <dom-module id="site-details-permission">
   <template>
     <style include="settings-shared md-select"></style>
-    <div id="details">
+    <div id="details" hidden$="[[shouldHideCategory_(category)]]">
       <div id="permissionItem"
           class$="list-item [[permissionInfoStringClass_(site.source, category,
                                                          site.setting)]]">
diff --git a/chrome/browser/resources/settings/site_settings/site_details_permission.js b/chrome/browser/resources/settings/site_settings/site_details_permission.js
index ce339395..b40bd94 100644
--- a/chrome/browser/resources/settings/site_settings/site_details_permission.js
+++ b/chrome/browser/resources/settings/site_settings/site_details_permission.js
@@ -36,6 +36,10 @@
         this.onDefaultSettingChanged_.bind(this));
   },
 
+  shouldHideCategory_: function(category) {
+    return !this.getCategoryList().includes(category);
+  },
+
   /**
    * Updates the drop-down value after |site| has changed.
    * @param {!RawSiteException} site The site to display.
diff --git a/chrome/browser/resources/settings/site_settings/site_entry.html b/chrome/browser/resources/settings/site_settings/site_entry.html
index 3f9eb5d..f271018 100644
--- a/chrome/browser/resources/settings/site_settings/site_entry.html
+++ b/chrome/browser/resources/settings/site_settings/site_entry.html
@@ -7,20 +7,43 @@
 
 <dom-module id="site-entry">
   <template>
-    <style include="settings-shared"></style>
+    <style include="settings-shared">
+      .row-aligned {
+        display: flex;
+        flex-direction: row;
+      }
+    </style>
     <div id="collapseParent">
-      <div id="toggleButton" class="settings-box list-item"
-          on-click="toggleCollapsible_" actionable aria-expanded="false">
-        <div class="favicon-image"
-            style$="[[getSiteGroupIcon_(siteGroup)]]">
+      <div class="settings-box list-item">
+        <div id="toggleButton" class="start row-aligned"
+            on-click="toggleCollapsible_" actionable aria-expanded="false">
+          <div class="favicon-image"
+              style$="[[getSiteGroupIcon_(siteGroup)]]">
+          </div>
+          <div class="middle text-elide" id="displayName">
+            [[displayName_]]
+          </div>
+          <div hidden$="[[!grouped_(siteGroup)]]">
+            <paper-icon-button-light id="expandIcon" class="icon-expand-more">
+              <button aria-label$="[[displayName_]]"
+                  aria-describedby="displayName"></button>
+            </paper-icon-button-light>
+          </div>
+          <div hidden$="[[grouped_(siteGroup)]]">
+            <paper-icon-button-light class="subpage-arrow">
+              <button aria-label$="[[displayName_]]"
+                  aria-describedby="displayName"></button>
+            </paper-icon-button-light>
+          </div>
         </div>
-        <div class="middle text-elide" id="displayName">
-          [[displayName_(siteGroup)]]
+        <div class="row-aligned" hidden$="[[!grouped_(siteGroup)]]">
+          <div class="separator"></div>
+          <paper-icon-button-light class="icon-more-vert">
+            <button id="overflowMenuButton" title="$i18n{moreActions}"
+                on-click="showOverflowMenu_">
+            </button>
+          </paper-icon-button-light>
         </div>
-        <paper-icon-button-light class="subpage-arrow">
-          <button aria-label$="[[displayName_(siteGroup)]]"
-              aria-describedby="displayName"></button>
-        </paper-icon-button-light>
       </div>
 
       <iron-collapse id="collapseChild" no-animation>
@@ -31,7 +54,7 @@
               <div class="favicon-image"
                   style$="[[computeSiteIcon(item)]]">
               </div>
-              <div class="middle text-elide" data-index="[[index]]">
+              <div class="middle text-elide">
                 [[item]]
               </div>
             </div>
@@ -39,6 +62,38 @@
         </div>
       </iron-collapse>
     </div>
+
+    <!-- Overflow menu. -->
+    <cr-lazy-render id="menu">
+      <template>
+        <cr-action-menu>
+          <button slot="item" class="dropdown-item" role="menuitem"
+              on-click="onConfirmResetSettings_">
+            Reset permissions
+          </button>
+        </cr-action-menu>
+      </template>
+    </cr-lazy-render>
+
+    <!-- Confirm reset settings dialog. -->
+    <cr-dialog id="confirmResetSettings" close-text="$i18n{close}">
+      <div slot="title">
+        $i18n{siteSettingsSiteGroupResetDialogTitle}
+      </div>
+      <div slot="body">
+        [[getFormatString_(
+            '$i18nPolymer{siteSettingsSiteGroupResetConfirmation}',
+            displayName_)]]
+      </div>
+      <div slot="button-container">
+        <paper-button class="cancel-button" on-click="onCloseDialog_">
+          $i18n{cancel}
+        </paper-button>
+        <paper-button class="action-button" on-click="onResetSettings_">
+          $i18n{siteSettingsSiteResetAll}
+        </paper-button>
+      </div>
+    </cr-dialog>
   </template>
   <script src="site_entry.js"></script>
 </dom-module>
diff --git a/chrome/browser/resources/settings/site_settings/site_entry.js b/chrome/browser/resources/settings/site_settings/site_entry.js
index 9ba76a6..868e218 100644
--- a/chrome/browser/resources/settings/site_settings/site_entry.js
+++ b/chrome/browser/resources/settings/site_settings/site_entry.js
@@ -17,13 +17,25 @@
      * An object representing a group of sites with the same eTLD+1.
      * @typedef {!SiteGroup}
      */
-    siteGroup: Object,
+    siteGroup: {
+      type: Object,
+      observer: 'onSiteGroupChanged_',
+    },
+
+    /**
+     * The name to display beside the icon. If grouped_() is true, it will be
+     * the eTLD+1 for all the origins, otherwise, it will match the origin more
+     * closely in an appropriate site representation.
+     * @typedef {!string}
+     * @private
+     */
+    displayName_: String,
   },
 
   /**
    * Whether the list of origins displayed in this site-entry is a group of
    * eTLD+1 origins or not.
-   * @param {Array<Object>} siteGroup The eTLD+1 group of origins.
+   * @param {SiteGroup} siteGroup The eTLD+1 group of origins.
    * @return {boolean}
    * @private
    */
@@ -32,25 +44,20 @@
   },
 
   /**
-   * The name to display beside the icon. If grouped_() is true, it will return
-   * the eTLD+1 for all the origins, otherwise, it will return the origin in an
-   * appropriate site representation.
-   * @param {Array<Object>} siteGroup The eTLD+1 group of origins.
-   * @return {string} The name to display.
+   * @param {SiteGroup} siteGroup The eTLD+1 group of origins.
    * @private
    */
-  displayName_: function(siteGroup) {
-    if (this.grouped_(siteGroup))
-      return siteGroup.etldPlus1;
-    // TODO(https://crbug.com/835712): Return the origin in a user-friendly site
-    // representation.
-    return siteGroup.origins[0];
+  onSiteGroupChanged_: function(siteGroup) {
+    // TODO(https://crbug.com/835712): Present the origin in a user-friendly
+    // site representation when ungrouped.
+    this.displayName_ =
+        this.grouped_(siteGroup) ? siteGroup.etldPlus1 : siteGroup.origins[0];
   },
 
   /**
    * Get an appropriate favicon that represents this group of eTLD+1 sites as a
    * whole.
-   * @param {Array<Object>} siteGroup The eTLD+1 group of origins.
+   * @param {SiteGroup} siteGroup The eTLD+1 group of origins.
    * @return {string} CSS to apply to show the appropriate favicon.
    * @private
    */
@@ -74,28 +81,95 @@
 
   /**
    * A handler for selecting a site (by clicking on the origin).
-   * @param {!{model: !{index: !number}}} event
+   * @param {!{model: !{index: !number}}} e
    * @private
    */
-  onOriginTap_: function(event) {
-    this.navigateToSiteDetails_(this.siteGroup.origins[event.model.index]);
+  onOriginTap_: function(e) {
+    this.navigateToSiteDetails_(this.siteGroup.origins[e.model.index]);
   },
 
   /**
    * Toggles open and closed the list of origins if there is more than one, and
    * directly navigates to Site Details if there is only one site.
-   * @param {!Object} event
+   * @param {!Object} e
    * @private
    */
-  toggleCollapsible_: function(event) {
+  toggleCollapsible_: function(e) {
     // Individual origins don't expand - just go straight to Site Details.
     if (!this.grouped_(this.siteGroup)) {
       this.navigateToSiteDetails_(this.siteGroup.origins[0]);
       return;
     }
 
-    let collapseChild = this.$.collapseChild;
+    let collapseChild =
+        /** @type {IronCollapseElement} */ (this.$.collapseChild);
     collapseChild.toggle();
     this.$.toggleButton.setAttribute('aria-expanded', collapseChild.opened);
+    this.$.expandIcon.toggleClass('icon-expand-more');
+    this.$.expandIcon.toggleClass('icon-expand-less');
+  },
+
+  /**
+   * Retrieves the overflow menu.
+   * @private
+   */
+  getOverflowMenu_: function() {
+    let menu = /** @type {?CrActionMenuElement} */ (this.$.menu.getIfExists());
+    if (!menu)
+      menu = /** @type {!CrActionMenuElement} */ (this.$.menu.get());
+    return menu;
+  },
+
+  /**
+   * Opens the overflow menu at event target.
+   * @param {!{target: Element}} e
+   * @private
+   */
+  showOverflowMenu_: function(e) {
+    this.getOverflowMenu_().showAt(e.target);
+  },
+
+  /** @private */
+  onCloseDialog_: function(e) {
+    e.target.closest('cr-dialog').close();
+    this.getOverflowMenu_().close();
+  },
+
+  /**
+   * Confirms the resetting of all content settings for an origin.
+   * @param {!{target: !Element}} e
+   * @private
+   */
+  onConfirmResetSettings_: function(e) {
+    e.preventDefault();
+    this.$.confirmResetSettings.showModal();
+  },
+
+  /**
+   * Resets all permissions for all origins listed in |siteGroup.origins|.
+   * @param {!Event} e
+   * @private
+   */
+  onResetSettings_: function(e) {
+    const contentSettingsTypes = this.getCategoryList();
+    for (let i = 0; i < this.siteGroup.origins.length; ++i) {
+      const origin = this.siteGroup.origins[i];
+      this.browserProxy.setOriginPermissions(
+          origin, contentSettingsTypes, settings.ContentSetting.DEFAULT);
+      if (contentSettingsTypes.includes(settings.ContentSettingsTypes.PLUGINS))
+        this.browserProxy.clearFlashPref(origin);
+    }
+    this.onCloseDialog_(e);
+  },
+
+  /**
+   * Formats the |label| string with |name|, using $<num> as markers.
+   * @param {string} label
+   * @param {string} name
+   * @return {string}
+   * @private
+   */
+  getFormatString_: function(label, name) {
+    return loadTimeData.substituteString(label, name);
   },
 });
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
index 1c244c0b..99315be 100644
--- a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
+++ b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
@@ -32,6 +32,18 @@
     category: String,
 
     /**
+     * A cached list of ContentSettingsTypes with a standard allow-block-ask
+     * pattern that are currently enabled for use. This property is the same
+     * across all elements with SiteSettingsBehavior ('static').
+     * @type {Array<settings.ContentSettingsTypes>}
+     * @private
+     */
+    contentTypes_: {
+      type: Array,
+      value: [],
+    },
+
+    /**
      * The browser proxy used to retrieve and change information about site
      * settings categories and the sites within.
      * @type {settings.SiteSettingsPrefsBrowserProxy}
@@ -98,7 +110,6 @@
    * Returns the icon to use for a given site.
    * @param {string} site The url of the site to fetch the icon for.
    * @return {string} The background-image style with the favicon.
-   * @private
    */
   computeSiteIcon: function(site) {
     site = this.removePatternWildcard(site);
@@ -170,6 +181,56 @@
     };
   },
 
+  /**
+   * Returns list of categories for each setting.ContentSettingsTypes that are
+   * currently enabled.
+   * @return {!Array<!settings.ContentSettingsTypes>}
+   */
+  getCategoryList: function() {
+    if (this.contentTypes_.length == 0) {
+      /** @type {!Array<settings.ContentSettingsTypes>} */
+      for (let typeName in settings.ContentSettingsTypes) {
+        const contentType = settings.ContentSettingsTypes[typeName];
+        // <if expr="not chromeos">
+        if (contentType == settings.ContentSettingsTypes.PROTECTED_CONTENT)
+          continue;
+        // </if>
+        // Some categories store their data in a custom way.
+        if (contentType == settings.ContentSettingsTypes.COOKIES ||
+            contentType == settings.ContentSettingsTypes.PROTOCOL_HANDLERS ||
+            contentType == settings.ContentSettingsTypes.ZOOM_LEVELS) {
+          continue;
+        }
+        this.contentTypes_.push(contentType);
+      }
+    }
+
+    const addOrRemoveSettingWithFlag = (type, flag) => {
+      if (loadTimeData.getBoolean(flag)) {
+        if (!this.contentTypes_.includes(type))
+          this.contentTypes_.push(type);
+      } else {
+        if (this.contentTypes_.includes(type))
+          this.contentTypes_.splice(this.contentTypes_.indexOf(type), 1);
+      }
+    };
+    // These categories are gated behind flags.
+    addOrRemoveSettingWithFlag(
+        settings.ContentSettingsTypes.SENSORS, 'enableSensorsContentSetting');
+    addOrRemoveSettingWithFlag(
+        settings.ContentSettingsTypes.ADS,
+        'enableSafeBrowsingSubresourceFilter');
+    addOrRemoveSettingWithFlag(
+        settings.ContentSettingsTypes.SOUND, 'enableSoundContentSetting');
+    addOrRemoveSettingWithFlag(
+        settings.ContentSettingsTypes.CLIPBOARD,
+        'enableClipboardContentSetting');
+    addOrRemoveSettingWithFlag(
+        settings.ContentSettingsTypes.PAYMENT_HANDLER,
+        'enablePaymentHandlerContentSetting');
+    return this.contentTypes_.slice(0);
+  },
+
 };
 
 /** @polymerBehavior */
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
index a8a7dc5fc..35fca8a 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
@@ -880,12 +880,6 @@
   base::string16 warning_text_with_org_name = l10n_util::GetStringFUTF16(
       IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS_ENTERPRISE_WITH_ORG_NAME,
       base::UTF8ToUTF16("example.com"));
-  EXPECT_EQ(PasswordReuseEvent::NOT_SIGNED_IN, service_->GetSyncAccountType());
-  EXPECT_TRUE(service_->GetOrganizationName().empty());
-  EXPECT_EQ(default_warning_text, service_->GetWarningDetailText(
-                                      PasswordReuseEvent::SIGN_IN_PASSWORD));
-  EXPECT_EQ(default_warning_text, service_->GetWarningDetailText(
-                                      PasswordReuseEvent::ENTERPRISE_PASSWORD));
 
   // Enables kEnterprisePasswordProtectionV1 feature.
   base::test::ScopedFeatureList scoped_features;
@@ -916,10 +910,6 @@
       l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS);
   base::string16 generic_enterprise_warning_text = l10n_util::GetStringUTF16(
       IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS_ENTERPRISE);
-  EXPECT_EQ(default_warning_text, service_->GetWarningDetailText(
-                                      PasswordReuseEvent::SIGN_IN_PASSWORD));
-  EXPECT_EQ(default_warning_text, service_->GetWarningDetailText(
-                                      PasswordReuseEvent::ENTERPRISE_PASSWORD));
 
   // Enables kEnterprisePasswordProtectionV1 feature.
   base::test::ScopedFeatureList scoped_features;
diff --git a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
index 97e4d4df..f35f89d 100644
--- a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
@@ -22,6 +22,8 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/layout.h"
 
+namespace {
+
 using bookmarks::BookmarkModel;
 using bookmarks::BookmarkNode;
 using bookmarks::UrlAndTitle;
@@ -487,3 +489,5 @@
 INSTANTIATE_TEST_CASE_P(USS,
                         SingleClientBookmarksSyncTestIncludingUssTests,
                         ::testing::Values(false, true));
+
+}  // namespace
diff --git a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc
index ff2a813..471a48bf 100644
--- a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc
@@ -32,6 +32,8 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "ui/base/layout.h"
 
+namespace {
+
 using bookmarks::BookmarkNode;
 using bookmarks_helper::AddFolder;
 using bookmarks_helper::AddURL;
@@ -67,16 +69,12 @@
 using bookmarks_helper::SetURL;
 using bookmarks_helper::SortChildren;
 
-namespace {
-
 const char kGenericURL[] = "http://www.host.ext:1234/path/filename";
 const char kGenericURLTitle[] = "URL Title";
 const char kGenericFolderName[] = "Folder Name";
 const char kGenericSubfolderName[] = "Subfolder Name";
 const char kValidPassphrase[] = "passphrase!";
 
-}  // namespace
-
 class TwoClientBookmarksSyncTest : public SyncTest {
  public:
   TwoClientBookmarksSyncTest() : SyncTest(TWO_CLIENT) {}
@@ -2173,3 +2171,5 @@
   ASSERT_EQ(initial_count + 2, CountAllBookmarks(0));
   ASSERT_EQ(initial_count + 2, CountAllBookmarks(1));
 }
+
+}  // namespace
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 9451d7a9..936d7b7 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -145,8 +145,6 @@
       "cocoa/browser_window_fullscreen_transition.mm",
       "cocoa/browser_window_layout.h",
       "cocoa/browser_window_layout.mm",
-      "cocoa/browser_window_touch_bar.h",
-      "cocoa/browser_window_touch_bar.mm",
       "cocoa/browser_window_utils.h",
       "cocoa/browser_window_utils.mm",
       "cocoa/bubble_anchor_helper.h",
@@ -2344,6 +2342,8 @@
       "browser_commands_mac.h",
       "browser_mac.cc",
       "browser_mac.h",
+      "browser_window_touch_bar_mac.h",
+      "browser_window_touch_bar_mac.mm",
       "certificate_viewer_mac.h",
       "certificate_viewer_mac.mm",
       "cocoa/accelerator_utils_cocoa.mm",
diff --git a/chrome/browser/ui/android/autofill/password_generation_popup_view_android.cc b/chrome/browser/ui/android/autofill/password_generation_popup_view_android.cc
index 622084e..6b414ccc 100644
--- a/chrome/browser/ui/android/autofill/password_generation_popup_view_android.cc
+++ b/chrome/browser/ui/android/autofill/password_generation_popup_view_android.cc
@@ -21,8 +21,6 @@
 using base::android::JavaParamRef;
 using base::android::ScopedJavaLocalRef;
 
-namespace autofill {
-
 PasswordGenerationPopupViewAndroid::PasswordGenerationPopupViewAndroid(
     PasswordGenerationPopupController* controller)
     : controller_(controller) {}
@@ -62,7 +60,7 @@
   if (view.is_null())
     return;
   JNIEnv* env = base::android::AttachCurrentThread();
-  java_object_.Reset(Java_PasswordGenerationPopupBridge_create(
+  java_object_.Reset(autofill::Java_PasswordGenerationPopupBridge_create(
       env, view, reinterpret_cast<intptr_t>(this),
       view_android->GetWindowAndroid()->GetJavaObject()));
 
@@ -73,7 +71,7 @@
   controller_ = NULL;
   JNIEnv* env = base::android::AttachCurrentThread();
   if (!java_object_.is_null()) {
-    Java_PasswordGenerationPopupBridge_hide(env, java_object_);
+    autofill::Java_PasswordGenerationPopupBridge_hide(env, java_object_);
   } else {
     // Hide() should delete |this| either via Java dismiss or directly.
     delete this;
@@ -108,8 +106,10 @@
   ScopedJavaLocalRef<jstring> help =
       base::android::ConvertUTF16ToJavaString(env, controller_->HelpText());
 
-  Java_PasswordGenerationPopupBridge_show(
-      env, java_object_, controller_->IsRTL(), controller_->display_password(),
+  autofill::Java_PasswordGenerationPopupBridge_show(
+      env, java_object_, controller_->IsRTL(),
+      controller_->state() ==
+          PasswordGenerationPopupController::kOfferGeneration,
       password, suggestion, help, controller_->HelpTextLinkRange().start(),
       controller_->HelpTextLinkRange().end());
 }
@@ -127,5 +127,3 @@
     PasswordGenerationPopupController* controller) {
   return new PasswordGenerationPopupViewAndroid(controller);
 }
-
-}  // namespace autofill
diff --git a/chrome/browser/ui/android/autofill/password_generation_popup_view_android.h b/chrome/browser/ui/android/autofill/password_generation_popup_view_android.h
index 90933885..937e77b 100644
--- a/chrome/browser/ui/android/autofill/password_generation_popup_view_android.h
+++ b/chrome/browser/ui/android/autofill/password_generation_popup_view_android.h
@@ -13,8 +13,6 @@
 #include "chrome/browser/ui/passwords/password_generation_popup_view.h"
 #include "ui/android/view_android.h"
 
-namespace autofill {
-
 class PasswordGenerationPopupController;
 
 // The android implementation of the password generation UI.
@@ -61,6 +59,4 @@
   DISALLOW_COPY_AND_ASSIGN(PasswordGenerationPopupViewAndroid);
 };
 
-}  // namespace autofill
-
 #endif  // CHROME_BROWSER_UI_ANDROID_AUTOFILL_PASSWORD_GENERATION_POPUP_VIEW_ANDROID_H_
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc
index 0e81edf..202ba13 100644
--- a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc
+++ b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc
@@ -4,19 +4,41 @@
 
 #include "chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h"
 
+#include "base/metrics/histogram_macros.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/infobars/core/simple_alert_infobar_delegate.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/common/page_importance_signals.h"
 #include "ui/base/l10n/l10n_util.h"
 
 DEFINE_WEB_CONTENTS_USER_DATA_KEY(BloatedRendererTabHelper);
 
+namespace {
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class BloatedRendererHandlingInBrowser {
+  kReloaded = 0,
+  kCannotReload = 1,
+  kCannotShutdown = 2,
+  kMaxValue = kCannotShutdown
+};
+
+void RecordBloatedRendererHandling(BloatedRendererHandlingInBrowser handling) {
+  UMA_HISTOGRAM_ENUMERATION("BloatedRenderer.HandlingInBrowser", handling);
+}
+}  // anonymous namespace
+
 BloatedRendererTabHelper::BloatedRendererTabHelper(
     content::WebContents* contents)
-    : content::WebContentsObserver(contents) {}
-
-void BloatedRendererTabHelper::WillReloadPageWithBloatedRenderer() {
-  reloading_bloated_renderer_ = true;
+    : content::WebContentsObserver(contents) {
+  auto* page_signal_receiver =
+      resource_coordinator::PageSignalReceiver::GetInstance();
+  if (page_signal_receiver) {
+    // PageSignalReceiver is not available if the resource coordinator is not
+    // enabled.
+    page_signal_receiver->AddObserver(this);
+  }
 }
 
 void BloatedRendererTabHelper::DidFinishNavigation(
@@ -29,6 +51,16 @@
   }
 }
 
+void BloatedRendererTabHelper::WebContentsDestroyed() {
+  auto* page_signal_receiver =
+      resource_coordinator::PageSignalReceiver::GetInstance();
+  if (page_signal_receiver) {
+    // PageSignalReceiver is not available if the resource coordinator is not
+    // enabled.
+    page_signal_receiver->RemoveObserver(this);
+  }
+}
+
 void BloatedRendererTabHelper::ShowInfoBar(InfoBarService* infobar_service) {
   if (!infobar_service) {
     // No infobar service in unit-tests.
@@ -39,3 +71,52 @@
       infobars::InfoBarDelegate::BLOATED_RENDERER_INFOBAR_DELEGATE, nullptr,
       l10n_util::GetStringUTF16(IDS_BROWSER_BLOATED_RENDERER_INFOBAR), false);
 }
+
+bool BloatedRendererTabHelper::CanReloadBloatedTab() {
+  if (web_contents()->IsCrashed())
+    return false;
+
+  // Do not reload tabs that don't have a valid URL (most probably they have
+  // just been opened and discarding them would lose the URL).
+  if (!web_contents()->GetLastCommittedURL().is_valid() ||
+      web_contents()->GetLastCommittedURL().is_empty()) {
+    return false;
+  }
+
+  // Do not reload tabs in which the user has entered text in a form.
+  if (web_contents()->GetPageImportanceSignals().had_form_interaction)
+    return false;
+
+  // TODO(ulan): Check if the navigation controller has POST data.
+
+  return true;
+}
+
+void BloatedRendererTabHelper::OnRendererIsBloated(
+    content::WebContents* bloated_web_contents) {
+  if (web_contents() != bloated_web_contents) {
+    // Ignore if the notification is about a different tab.
+    return;
+  }
+  if (CanReloadBloatedTab()) {
+    const size_t expected_page_count = 1u;
+    const bool skip_unload_handlers = true;
+    content::RenderProcessHost* renderer =
+        web_contents()->GetMainFrame()->GetProcess();
+    if (renderer->FastShutdownIfPossible(expected_page_count,
+                                         skip_unload_handlers)) {
+      const bool check_for_repost = true;
+      reloading_bloated_renderer_ = true;
+      web_contents()->GetController().Reload(content::ReloadType::NORMAL,
+                                             check_for_repost);
+      RecordBloatedRendererHandling(
+          BloatedRendererHandlingInBrowser::kReloaded);
+    } else {
+      RecordBloatedRendererHandling(
+          BloatedRendererHandlingInBrowser::kCannotShutdown);
+    }
+  } else {
+    RecordBloatedRendererHandling(
+        BloatedRendererHandlingInBrowser::kCannotReload);
+  }
+}
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h
index 676e37ba..e5ec140e 100644
--- a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h
+++ b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h
@@ -7,42 +7,51 @@
 
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
+#include "chrome/browser/resource_coordinator/page_signal_receiver.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
 
 class InfoBarService;
 
-// This tab helper observes the WillReloadBloatedRenderer event. Upon
-// receiving the event, it activates the logic to show an infobar on the
+// This tab helper observes the OnRendererIsBloated event for its
+// WebContents. Upon receiving the event it reloads the bloated tab if
+// possible and activates the logic to show an infobar on the
 // subsequent DidFinishNavigation event.
 //
-// Assumptions around the WillReloadBloatedRenderer event:
-// - The renderer process was shutdown before it.
-// - Page reload will be performed immediately after it.
-// This ensures that the first DidFinishNavigation after it originates from
-// reloading the bloated page.
-//
 // Note that we need to show the infobar after NavigationEntryCommitted
 // because the infobar service removes existing infobars there.
 class BloatedRendererTabHelper
     : public content::WebContentsObserver,
-      public content::WebContentsUserData<BloatedRendererTabHelper> {
+      public content::WebContentsUserData<BloatedRendererTabHelper>,
+      public resource_coordinator::PageSignalObserver {
  public:
   ~BloatedRendererTabHelper() override = default;
 
   // content::WebContentsObserver:
   void DidFinishNavigation(
       content::NavigationHandle* navigation_handle) override;
+  void WebContentsDestroyed() override;
 
-  void WillReloadPageWithBloatedRenderer();
+  // resource_coordinator::PageSignalObserver:
+  void OnRendererIsBloated(content::WebContents* web_contents) override;
+
   static void ShowInfoBar(InfoBarService* infobar_service);
 
  private:
   friend class content::WebContentsUserData<BloatedRendererTabHelper>;
   FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest, DetectReload);
+  FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest, CanReloadBloatedTab);
+  FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest,
+                           CannotReloadBloatedTabCrashed);
+  FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest,
+                           CannotReloadBloatedTabInvalidURL);
+  FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest,
+                           CannotReloadBloatedTabPendingUserInteraction);
 
   explicit BloatedRendererTabHelper(content::WebContents* contents);
 
+  bool CanReloadBloatedTab();
+
   bool reloading_bloated_renderer_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(BloatedRendererTabHelper);
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_browsertest.cc b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_browsertest.cc
new file mode 100644
index 0000000..7d7445c
--- /dev/null
+++ b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_browsertest.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 "chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h"
+
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/infobars/infobar_service.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/test/test_navigation_observer.h"
+#include "content/public/test/test_utils.h"
+
+using BloatedRendererTabHelperBrowserTest = InProcessBrowserTest;
+
+// TODO(ulan): Enable the test after fixing crbug.com/850921.
+IN_PROC_BROWSER_TEST_F(BloatedRendererTabHelperBrowserTest,
+                       DISABLED_ReloadBloatedTab) {
+  content::WindowedNotificationObserver load(
+      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
+      content::NotificationService::AllSources());
+  content::OpenURLParams url(
+      GURL(chrome::kChromeUIAboutURL), content::Referrer(),
+      WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false);
+  browser()->OpenURL(url);
+  load.Wait();
+
+  content::WindowedNotificationObserver reload(
+      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
+      content::NotificationService::AllSources());
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetWebContentsAt(0);
+  InfoBarService* infobar_service =
+      InfoBarService::FromWebContents(web_contents);
+  EXPECT_EQ(0u, infobar_service->infobar_count());
+  BloatedRendererTabHelper::FromWebContents(web_contents)
+      ->OnRendererIsBloated(web_contents);
+  reload.Wait();
+  EXPECT_EQ(1u, infobar_service->infobar_count());
+}
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc
index 6545306..bea4fe3 100644
--- a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc
+++ b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc
@@ -4,17 +4,51 @@
 
 #include "chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "content/public/common/page_importance_signals.h"
+#include "content/public/test/web_contents_tester.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-class BloatedRendererTabHelperTest : public ChromeRenderViewHostTestHarness {};
+class BloatedRendererTabHelperTest : public ChromeRenderViewHostTestHarness {
+ protected:
+  void SetUp() override {
+    ChromeRenderViewHostTestHarness::SetUp();
+    BloatedRendererTabHelper::CreateForWebContents(web_contents());
+    tab_helper_ = BloatedRendererTabHelper::FromWebContents(web_contents());
+    content::WebContentsTester::For(web_contents())
+        ->SetLastCommittedURL(GURL("https://test.test"));
+  }
+  BloatedRendererTabHelper* tab_helper_;
+};
 
 TEST_F(BloatedRendererTabHelperTest, DetectReload) {
-  BloatedRendererTabHelper::CreateForWebContents(web_contents());
-  BloatedRendererTabHelper* helper =
-      BloatedRendererTabHelper::FromWebContents(web_contents());
-  EXPECT_FALSE(helper->reloading_bloated_renderer_);
-  helper->WillReloadPageWithBloatedRenderer();
-  EXPECT_TRUE(helper->reloading_bloated_renderer_);
-  helper->DidFinishNavigation(nullptr);
-  EXPECT_FALSE(helper->reloading_bloated_renderer_);
+  EXPECT_FALSE(tab_helper_->reloading_bloated_renderer_);
+  tab_helper_->reloading_bloated_renderer_ = true;
+  tab_helper_->DidFinishNavigation(nullptr);
+  EXPECT_FALSE(tab_helper_->reloading_bloated_renderer_);
+}
+
+TEST_F(BloatedRendererTabHelperTest, CanReloadBloatedTab) {
+  EXPECT_TRUE(tab_helper_->CanReloadBloatedTab());
+}
+
+TEST_F(BloatedRendererTabHelperTest, CannotReloadBloatedTabCrashed) {
+  web_contents()->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, 0);
+
+  EXPECT_FALSE(tab_helper_->CanReloadBloatedTab());
+}
+
+TEST_F(BloatedRendererTabHelperTest, CannotReloadBloatedTabInvalidURL) {
+  content::WebContentsTester::For(web_contents())
+      ->SetLastCommittedURL(GURL("invalid :)"));
+
+  EXPECT_FALSE(tab_helper_->CanReloadBloatedTab());
+}
+
+TEST_F(BloatedRendererTabHelperTest,
+       CannotReloadBloatedTabPendingUserInteraction) {
+  content::PageImportanceSignals signals;
+  signals.had_form_interaction = true;
+  content::WebContentsTester::For(web_contents())
+      ->SetPageImportanceSignals(signals);
+  EXPECT_FALSE(tab_helper_->CanReloadBloatedTab());
 }
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 9ebef3fb..bcfb798 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -67,6 +67,7 @@
 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h"
 #include "chrome/browser/pepper_broker_infobar_delegate.h"
 #include "chrome/browser/permissions/permission_request_manager.h"
+#include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h"
 #include "chrome/browser/plugins/plugin_finder.h"
 #include "chrome/browser/plugins/plugin_metadata.h"
 #include "chrome/browser/policy/developer_tools_policy_handler.h"
@@ -187,7 +188,6 @@
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/overscroll_configuration.h"
-#include "content/public/browser/picture_in_picture_window_controller.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
@@ -1009,13 +1009,6 @@
   // associated with their tab is still valid.
   WebContentsModalDialogManager::FromWebContents(contents)->CloseAllDialogs();
 
-  if (pip_window_controller_ &&
-      pip_window_controller_->GetInitiatorWebContents() == contents) {
-    // When |contents| is closed, the previously referred to
-    // |pip_window_controller_| will also be torn down.
-    pip_window_controller_ = nullptr;
-  }
-
   // Page load metrics need to be informed that the WebContents will soon be
   // destroyed, so that upcoming visiblity changes can be ignored.
   page_load_metrics::MetricsWebContentsObserver* metrics_observer =
@@ -1417,27 +1410,12 @@
 
 gfx::Size Browser::EnterPictureInPicture(const viz::SurfaceId& surface_id,
                                          const gfx::Size& natural_size) {
-  // If there was already a controller, close the existing window before
-  // creating the next one.
-  if (pip_window_controller_)
-    pip_window_controller_->Close(false /* should_pause_video */);
-
-  // Create or update |pip_window_controller_| for the current WebContents.
-  if (!pip_window_controller_ ||
-      pip_window_controller_->GetInitiatorWebContents() !=
-          tab_strip_model_->GetActiveWebContents()) {
-    pip_window_controller_ =
-        content::PictureInPictureWindowController::GetOrCreateForWebContents(
-            tab_strip_model_->GetActiveWebContents());
-  }
-
-  pip_window_controller_->EmbedSurface(surface_id, natural_size);
-  return pip_window_controller_->Show();
+  return PictureInPictureWindowManager::GetInstance()->EnterPictureInPicture(
+      tab_strip_model_->GetActiveWebContents(), surface_id, natural_size);
 }
 
 void Browser::ExitPictureInPicture() {
-  if (pip_window_controller_)
-    pip_window_controller_->Close(false /* should_pause_video */);
+  PictureInPictureWindowManager::GetInstance()->ExitPictureInPicture();
 }
 
 bool Browser::IsMouseLocked() const {
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index bc82cff..a5f73a5096 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -79,7 +79,6 @@
 }
 
 namespace content {
-class PictureInPictureWindowController;
 class SessionStorageNamespace;
 }
 
@@ -998,13 +997,6 @@
 
   std::unique_ptr<chrome::BrowserCommandController> command_controller_;
 
-  // |pip_window_controller_| is held as a SupportsUserData attachment on the
-  // content::WebContents, and thus scoped to the lifetime of the initiator
-  // content::WebContents.
-  // The current active Picture-in-Picture controller is held in case of
-  // updates to the relevant viz::SurfaceId.
-  content::PictureInPictureWindowController* pip_window_controller_ = nullptr;
-
   // True if the browser window has been shown at least once.
   bool window_has_shown_;
 
diff --git a/chrome/browser/ui/cocoa/browser_window_touch_bar.h b/chrome/browser/ui/browser_window_touch_bar_mac.h
similarity index 93%
rename from chrome/browser/ui/cocoa/browser_window_touch_bar.h
rename to chrome/browser/ui/browser_window_touch_bar_mac.h
index b7ff668..47f651fa 100644
--- a/chrome/browser/ui/cocoa/browser_window_touch_bar.h
+++ b/chrome/browser/ui/browser_window_touch_bar_mac.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_COCOA_BROWSER_WINDOW_TOUCH_BAR_H_
-#define CHROME_BROWSER_UI_COCOA_BROWSER_WINDOW_TOUCH_BAR_H_
+#ifndef CHROME_BROWSER_UI_BROWSER_WINDOW_TOUCH_BAR_MAC_H_
+#define CHROME_BROWSER_UI_BROWSER_WINDOW_TOUCH_BAR_MAC_H_
 
 #import <Cocoa/Cocoa.h>
 
diff --git a/chrome/browser/ui/cocoa/browser_window_touch_bar.mm b/chrome/browser/ui/browser_window_touch_bar_mac.mm
similarity index 98%
rename from chrome/browser/ui/cocoa/browser_window_touch_bar.mm
rename to chrome/browser/ui/browser_window_touch_bar_mac.mm
index d24ac90..585d5028 100644
--- a/chrome/browser/ui/cocoa/browser_window_touch_bar.mm
+++ b/chrome/browser/ui/browser_window_touch_bar_mac.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "chrome/browser/ui/cocoa/browser_window_touch_bar.h"
+#import "chrome/browser/ui/browser_window_touch_bar_mac.h"
 
 #include <memory>
 
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm
index e06ef00..ce288cfa 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -39,6 +39,7 @@
 #include "chrome/browser/ui/browser_instant_controller.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window_state.h"
+#import "chrome/browser/ui/browser_window_touch_bar_mac.h"
 #import "chrome/browser/ui/cocoa/background_gradient_view.h"
 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"
 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_observer_cocoa.h"
@@ -49,7 +50,6 @@
 #import "chrome/browser/ui/cocoa/browser_window_command_handler.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller_private.h"
 #import "chrome/browser/ui/cocoa/browser_window_layout.h"
-#import "chrome/browser/ui/cocoa/browser_window_touch_bar.h"
 #import "chrome/browser/ui/cocoa/browser_window_utils.h"
 #import "chrome/browser/ui/cocoa/dev_tools_controller.h"
 #import "chrome/browser/ui/cocoa/download/download_shelf_controller.h"
diff --git a/chrome/browser/ui/cocoa/browser_window_touch_bar_browsertest.mm b/chrome/browser/ui/cocoa/browser_window_touch_bar_browsertest.mm
index d2e64cf..e55dc05 100644
--- a/chrome/browser/ui/cocoa/browser_window_touch_bar_browsertest.mm
+++ b/chrome/browser/ui/cocoa/browser_window_touch_bar_browsertest.mm
@@ -7,8 +7,8 @@
 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper_observer.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
+#import "chrome/browser/ui/browser_window_touch_bar_mac.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
-#import "chrome/browser/ui/cocoa/browser_window_touch_bar.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/views/scoped_macviews_browser_mode.h"
diff --git a/chrome/browser/ui/cocoa/browser_window_touch_bar_unittest.mm b/chrome/browser/ui/cocoa/browser_window_touch_bar_unittest.mm
index 553a2fdd..31e81925 100644
--- a/chrome/browser/ui/cocoa/browser_window_touch_bar_unittest.mm
+++ b/chrome/browser/ui/cocoa/browser_window_touch_bar_unittest.mm
@@ -13,8 +13,8 @@
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_command_controller.h"
+#import "chrome/browser/ui/browser_window_touch_bar_mac.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
-#import "chrome/browser/ui/cocoa/browser_window_touch_bar.h"
 #include "chrome/browser/ui/cocoa/test/cocoa_profile_test.h"
 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
 #include "chrome/common/chrome_features.h"
diff --git a/chrome/browser/ui/cocoa/framed_browser_window.mm b/chrome/browser/ui/cocoa/framed_browser_window.mm
index d3b279f..1c71b9e 100644
--- a/chrome/browser/ui/cocoa/framed_browser_window.mm
+++ b/chrome/browser/ui/cocoa/framed_browser_window.mm
@@ -15,9 +15,9 @@
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/themes/theme_service.h"
+#import "chrome/browser/ui/browser_window_touch_bar_mac.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
 #import "chrome/browser/ui/cocoa/browser_window_layout.h"
-#import "chrome/browser/ui/cocoa/browser_window_touch_bar.h"
 #import "chrome/browser/ui/cocoa/browser_window_utils.h"
 #include "chrome/browser/ui/cocoa/l10n_util.h"
 #import "chrome/browser/ui/cocoa/themed_window.h"
diff --git a/chrome/browser/ui/passwords/password_generation_popup_controller.cc b/chrome/browser/ui/passwords/password_generation_popup_controller.cc
index eb84f25..35c70f5f 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_controller.cc
+++ b/chrome/browser/ui/passwords/password_generation_popup_controller.cc
@@ -4,16 +4,3 @@
 
 #include "chrome/browser/ui/passwords/password_generation_popup_controller.h"
 
-namespace autofill {
-
-// static
-constexpr int PasswordGenerationPopupController::kHelpVerticalPadding = 15;
-
-// static
-constexpr int PasswordGenerationPopupController::kHorizontalPadding = 16;
-
-// static
-constexpr int PasswordGenerationPopupController::kPopupPasswordSectionHeight =
-    62;
-
-}  // namespace autofill
diff --git a/chrome/browser/ui/passwords/password_generation_popup_controller.h b/chrome/browser/ui/passwords/password_generation_popup_controller.h
index 162e883..1f9d886 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_controller.h
+++ b/chrome/browser/ui/passwords/password_generation_popup_controller.h
@@ -12,18 +12,15 @@
 class Range;
 }
 
-namespace autofill {
-
-class PasswordGenerationPopupController : public AutofillPopupViewDelegate {
+class PasswordGenerationPopupController
+    : public autofill::AutofillPopupViewDelegate {
  public:
-  // Space above and below help section.
-  static const int kHelpVerticalPadding;
-
-  // Spacing between the border of the popup and any text.
-  static const int kHorizontalPadding;
-
-  // Desired height of the password section.
-  static const int kPopupPasswordSectionHeight;
+  enum GenerationState {
+    // Generated password is offered in the popup but not filled yet.
+    kOfferGeneration,
+    // The generated password was accepted.
+    kEditGeneratedPassword,
+  };
 
   // Called by the view when the password was accepted.
   virtual void PasswordAccepted() = 0;
@@ -35,9 +32,9 @@
   virtual int GetMinimumWidth() = 0;
 
   // Accessors
-  virtual bool display_password() const = 0;
+  virtual GenerationState state() const = 0;
   virtual bool password_selected() const = 0;
-  virtual base::string16 password() const = 0;
+  virtual const base::string16& password() const = 0;
 
   // Translated strings
   virtual base::string16 SuggestedText() = 0;
@@ -45,9 +42,7 @@
   virtual const gfx::Range& HelpTextLinkRange() = 0;
 
  protected:
-  ~PasswordGenerationPopupController() override {}
+  ~PasswordGenerationPopupController() override = default;
 };
 
-}  // namespace autofill
-
 #endif  // CHROME_BROWSER_UI_PASSWORDS_PASSWORD_GENERATION_POPUP_CONTROLLER_H_
diff --git a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc
index a8beca7..82cbf4f 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc
+++ b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc
@@ -44,13 +44,11 @@
 #include "chrome/browser/android/preferences/preferences_launcher.h"
 #endif
 
-namespace autofill {
-
 base::WeakPtr<PasswordGenerationPopupControllerImpl>
 PasswordGenerationPopupControllerImpl::GetOrCreate(
     base::WeakPtr<PasswordGenerationPopupControllerImpl> previous,
     const gfx::RectF& bounds,
-    const PasswordForm& form,
+    const autofill::PasswordForm& form,
     const base::string16& generation_element,
     uint32_t max_length,
     password_manager::PasswordManager* password_manager,
@@ -76,14 +74,14 @@
 
 PasswordGenerationPopupControllerImpl::PasswordGenerationPopupControllerImpl(
     const gfx::RectF& bounds,
-    const PasswordForm& form,
+    const autofill::PasswordForm& form,
     const base::string16& generation_element,
     uint32_t max_length,
     const base::WeakPtr<password_manager::PasswordManagerDriver>& driver,
     PasswordGenerationPopupObserver* observer,
     content::WebContents* web_contents,
     gfx::NativeView container_view)
-    : view_(NULL),
+    : view_(nullptr),
       form_(form),
       driver_(driver),
       observer_(observer),
@@ -95,7 +93,7 @@
       // TODO(estade): use correct text direction.
       controller_common_(bounds, base::i18n::LEFT_TO_RIGHT, container_view),
       password_selected_(false),
-      display_password_(false),
+      state_(kOfferGeneration),
       web_contents_(web_contents),
       weak_ptr_factory_(this) {
   base::string16 link =
@@ -144,7 +142,7 @@
 }
 
 void PasswordGenerationPopupControllerImpl::PasswordSelected(bool selected) {
-  if (!display_password_ || selected == password_selected_)
+  if (state_ == kEditGeneratedPassword || selected == password_selected_)
     return;
 
   password_selected_ = selected;
@@ -152,7 +150,7 @@
 }
 
 void PasswordGenerationPopupControllerImpl::PasswordAccepted() {
-  if (!display_password_)
+  if (state_ != kOfferGeneration)
     return;
 
   driver_->GeneratedPasswordAccepted(current_password_);
@@ -176,14 +174,16 @@
       container_view(), IsRTL());
 }
 
-void PasswordGenerationPopupControllerImpl::Show(bool display_password) {
-  display_password_ = display_password;
-  if (display_password_ && current_password_.empty()) {
+void PasswordGenerationPopupControllerImpl::Show(GenerationState state) {
+  // When switching from editing to generation state, regenerate the password.
+  if (state == kOfferGeneration &&
+      (state_ != state || current_password_.empty())) {
     current_password_ =
         driver_->GetPasswordGenerationManager()->GeneratePassword(
             web_contents_->GetLastCommittedURL().GetOrigin(), form_signature_,
             field_signature_, max_length_);
   }
+  state_ = state;
 
   if (!view_) {
     view_ = PasswordGenerationPopupView::Create(this);
@@ -202,13 +202,20 @@
     view_->UpdateBoundsAndRedrawPopup();
   }
 
-  static_cast<ContentAutofillDriver*>(driver_->GetAutofillDriver())
+  static_cast<autofill::ContentAutofillDriver*>(driver_->GetAutofillDriver())
       ->RegisterKeyPressHandler(base::BindRepeating(
           &PasswordGenerationPopupControllerImpl::HandleKeyPressEvent,
           base::Unretained(this)));
 
   if (observer_)
-    observer_->OnPopupShown(display_password_);
+    observer_->OnPopupShown(state_);
+}
+
+void PasswordGenerationPopupControllerImpl::UpdatePassword(
+    base::string16 new_password) {
+  current_password_ = std::move(new_password);
+  if (view_)
+    view_->UpdatePasswordValue();
 }
 
 void PasswordGenerationPopupControllerImpl::HideAndDestroy() {
@@ -217,7 +224,7 @@
 
 void PasswordGenerationPopupControllerImpl::Hide() {
   if (driver_) {
-    static_cast<ContentAutofillDriver*>(driver_->GetAutofillDriver())
+    static_cast<autofill::ContentAutofillDriver*>(driver_->GetAutofillDriver())
         ->RemoveKeyPressHandler();
   }
 
@@ -305,20 +312,23 @@
 }
 #endif
 
-bool PasswordGenerationPopupControllerImpl::display_password() const {
-  return display_password_;
+PasswordGenerationPopupController::GenerationState
+PasswordGenerationPopupControllerImpl::state() const {
+  return state_;
 }
 
 bool PasswordGenerationPopupControllerImpl::password_selected() const {
   return password_selected_;
 }
 
-base::string16 PasswordGenerationPopupControllerImpl::password() const {
+const base::string16& PasswordGenerationPopupControllerImpl::password() const {
   return current_password_;
 }
 
 base::string16 PasswordGenerationPopupControllerImpl::SuggestedText() {
-  return l10n_util::GetStringUTF16(IDS_PASSWORD_GENERATION_SUGGESTION);
+  return l10n_util::GetStringUTF16(
+      state_ == kOfferGeneration ? IDS_PASSWORD_GENERATION_SUGGESTION
+                                 : IDS_PASSWORD_GENERATION_EDITING_SUGGESTION);
 }
 
 const base::string16& PasswordGenerationPopupControllerImpl::HelpText() {
@@ -328,5 +338,3 @@
 const gfx::Range& PasswordGenerationPopupControllerImpl::HelpTextLinkRange() {
   return link_range_;
 }
-
-}  // namespace autofill
diff --git a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h
index b1913cb..43a1747 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h
+++ b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h
@@ -33,10 +33,12 @@
 }  // namespace password_manager
 
 namespace autofill {
+struct PasswordForm;
+struct Suggestion;
+}  // namespace autofill
 
 class PasswordGenerationPopupObserver;
 class PasswordGenerationPopupView;
-struct Suggestion;
 
 // This class controls a PasswordGenerationPopupView. It is responsible for
 // determining the location of the popup, handling keypress events while the
@@ -57,7 +59,7 @@
   static base::WeakPtr<PasswordGenerationPopupControllerImpl> GetOrCreate(
       base::WeakPtr<PasswordGenerationPopupControllerImpl> previous,
       const gfx::RectF& bounds,
-      const PasswordForm& form,
+      const autofill::PasswordForm& form,
       const base::string16& generation_element,
       uint32_t max_length,
       password_manager::PasswordManager* password_manager,
@@ -68,10 +70,10 @@
   ~PasswordGenerationPopupControllerImpl() override;
 
   // Create a PasswordGenerationPopupView if one doesn't already exist.
-  // If |display_password| is true, a generated password is shown that can be
-  // selected by the user. Otherwise just the text explaining generated
-  // passwords is shown. Idempotent.
-  void Show(bool display_password);
+  void Show(GenerationState state);
+
+  // Update the password to be displayed in the UI.
+  void UpdatePassword(base::string16 new_password);
 
   // Hides the popup and destroys |this|.
   void HideAndDestroy();
@@ -79,7 +81,7 @@
  protected:
   PasswordGenerationPopupControllerImpl(
       const gfx::RectF& bounds,
-      const PasswordForm& form,
+      const autofill::PasswordForm& form,
       const base::string16& generation_element,
       uint32_t max_length,
       const base::WeakPtr<password_manager::PasswordManagerDriver>& driver,
@@ -112,9 +114,9 @@
   int GetElidedLabelWidthForRow(int row) override;
 #endif
 
-  bool display_password() const override;
+  GenerationState state() const override;
   bool password_selected() const override;
-  base::string16 password() const override;
+  const base::string16& password() const override;
   base::string16 SuggestedText() override;
   const base::string16& HelpText() override;
   const gfx::Range& HelpTextLinkRange() override;
@@ -133,7 +135,8 @@
   // wrapping.
   void CalculateBounds();
 
-  PasswordForm form_;
+  autofill::PasswordForm form_;
+
   base::WeakPtr<password_manager::PasswordManagerDriver> driver_;
 
   // May be NULL.
@@ -150,23 +153,25 @@
   uint32_t max_length_;
 
   // Contains common popup data.
-  const PopupControllerCommon controller_common_;
+  const autofill::PopupControllerCommon controller_common_;
 
   // Help text and the range in the text that corresponds to the saved passwords
   // link.
   base::string16 help_text_;
   gfx::Range link_range_;
 
+  // The password value to be displayed in the UI.
   base::string16 current_password_;
+  // Whether the row with the password is currently selected/highlighted.
   bool password_selected_;
 
-  // If a password will be shown in this popup.
-  bool display_password_;
+  // The state of the generation popup.
+  GenerationState state_;
 
   // Bounds for all the elements of the popup.
   gfx::Rect popup_bounds_;
 
-  PopupViewCommon view_common_;
+  autofill::PopupViewCommon view_common_;
 
   content::WebContents* const web_contents_;
 
@@ -175,6 +180,4 @@
   DISALLOW_COPY_AND_ASSIGN(PasswordGenerationPopupControllerImpl);
 };
 
-}  // namespace autofill
-
 #endif  // CHROME_BROWSER_UI_PASSWORDS_PASSWORD_GENERATION_POPUP_CONTROLLER_IMPL_H_
diff --git a/chrome/browser/ui/passwords/password_generation_popup_observer.h b/chrome/browser/ui/passwords/password_generation_popup_observer.h
index 89caeea..9309d74 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_observer.h
+++ b/chrome/browser/ui/passwords/password_generation_popup_observer.h
@@ -5,15 +5,14 @@
 #ifndef CHROME_BROWSER_UI_PASSWORDS_PASSWORD_GENERATION_POPUP_OBSERVER_H_
 #define CHROME_BROWSER_UI_PASSWORDS_PASSWORD_GENERATION_POPUP_OBSERVER_H_
 
-namespace autofill {
+#include "chrome/browser/ui/passwords/password_generation_popup_controller.h"
 
 // Observer for PasswordGenerationPopup events. Currently only used for testing.
 class PasswordGenerationPopupObserver {
  public:
-  virtual void OnPopupShown(bool password_visible) = 0;
+  virtual void OnPopupShown(
+      PasswordGenerationPopupController::GenerationState state) = 0;
   virtual void OnPopupHidden() = 0;
 };
 
-}  // namespace autofill
-
 #endif  // CHROME_BROWSER_UI_PASSWORDS_PASSWORD_GENERATION_POPUP_OBSERVER_H_
diff --git a/chrome/browser/ui/passwords/password_generation_popup_view.cc b/chrome/browser/ui/passwords/password_generation_popup_view.cc
index 5a730a45..fefc7ae 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_view.cc
+++ b/chrome/browser/ui/passwords/password_generation_popup_view.cc
@@ -4,15 +4,3 @@
 
 #include "chrome/browser/ui/passwords/password_generation_popup_view.h"
 
-namespace autofill {
-
-const SkColor PasswordGenerationPopupView::kPasswordTextColor =
-    SkColorSetRGB(0x33, 0x33, 0x33);
-const SkColor PasswordGenerationPopupView::kExplanatoryTextBackgroundColor =
-    SkColorSetRGB(0xF5, 0xF5, 0xF5);
-const SkColor PasswordGenerationPopupView::kExplanatoryTextColor =
-    SkColorSetRGB(0x66, 0x66, 0x66);
-const SkColor PasswordGenerationPopupView::kDividerColor =
-    SkColorSetRGB(0xE9, 0xE9, 0xE9);
-
-}  // namespace autofill
diff --git a/chrome/browser/ui/passwords/password_generation_popup_view.h b/chrome/browser/ui/passwords/password_generation_popup_view.h
index cedf9dd..925ab2f6 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_view.h
+++ b/chrome/browser/ui/passwords/password_generation_popup_view.h
@@ -12,16 +12,11 @@
 class Size;
 }  // namespace gfx
 
-namespace autofill {
-
 class PasswordGenerationPopupController;
 
 // Interface for creating and controlling a platform dependent view.
 class PasswordGenerationPopupView {
  public:
-  // Number of pixels added in between lines of the help section.
-  static const int kHelpSectionAdditionalSpacing = 3;
-
   // Display the popup.
   virtual void Show() = 0;
 
@@ -35,6 +30,9 @@
   // The layout should be recreated.
   virtual void UpdateState() = 0;
 
+  // The password was edited, the popup should show the new value.
+  virtual void UpdatePasswordValue() {}
+
   // Updates layout information from the controller and performs the layout.
   virtual void UpdateBoundsAndRedrawPopup() = 0;
 
@@ -47,13 +45,6 @@
   // when Hide() is called.
   static PasswordGenerationPopupView* Create(
       PasswordGenerationPopupController* controller);
-
-  static const SkColor kPasswordTextColor;
-  static const SkColor kExplanatoryTextBackgroundColor;
-  static const SkColor kExplanatoryTextColor;
-  static const SkColor kDividerColor;
 };
 
-}  // namespace autofill
-
 #endif  // CHROME_BROWSER_UI_PASSWORDS_PASSWORD_GENERATION_POPUP_VIEW_H_
diff --git a/chrome/browser/ui/passwords/password_generation_popup_view_browsertest.cc b/chrome/browser/ui/passwords/password_generation_popup_view_browsertest.cc
index 5048375..b749cb78 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_view_browsertest.cc
+++ b/chrome/browser/ui/passwords/password_generation_popup_view_browsertest.cc
@@ -63,7 +63,7 @@
                        MouseMovementInEditingPopup) {
   controller_ = new autofill::TestPasswordGenerationPopupController(
       GetWebContents(), GetNativeView());
-  controller_->Show(false /* display_password */);
+  controller_->Show(PasswordGenerationPopupController::kEditGeneratedPassword);
 
   gfx::Point center_point =
       static_cast<PasswordGenerationPopupController*>(controller_)
@@ -80,7 +80,7 @@
 IN_PROC_BROWSER_TEST_F(PasswordGenerationPopupViewTest, InvalidContainerView) {
   controller_ = new autofill::TestPasswordGenerationPopupController(
       GetWebContents(), NULL);
-  controller_->Show(true /* display password */);
+  controller_->Show(PasswordGenerationPopupController::kOfferGeneration);
 }
 
 // Verify that destroying web contents with visible popup does not crash.
@@ -88,7 +88,7 @@
                        CloseWebContentsWithVisiblePopup) {
   controller_ = new autofill::TestPasswordGenerationPopupController(
       GetWebContents(), GetNativeView());
-  controller_->Show(false);
+  controller_->Show(PasswordGenerationPopupController::kEditGeneratedPassword);
   GetWebContents()->Close();
 }
 
diff --git a/chrome/browser/ui/passwords/password_generation_popup_view_tester.h b/chrome/browser/ui/passwords/password_generation_popup_view_tester.h
index a290cd0..3b200559 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_view_tester.h
+++ b/chrome/browser/ui/passwords/password_generation_popup_view_tester.h
@@ -9,8 +9,6 @@
 
 #include "ui/gfx/geometry/point.h"
 
-namespace autofill {
-
 class PasswordGenerationPopupView;
 
 // Helps test a PasswordGenerationPopupView.
@@ -24,6 +22,4 @@
   virtual void SimulateMouseMovementAt(const gfx::Point& point) = 0;
 };
 
-}  // namespace autofill
-
 #endif  // CHROME_BROWSER_UI_PASSWORDS_PASSWORD_GENERATION_POPUP_VIEW_TESTER_H_
diff --git a/chrome/browser/ui/views/frame/browser_frame_mac.h b/chrome/browser/ui/views/frame/browser_frame_mac.h
index e12cda27..46021944 100644
--- a/chrome/browser/ui/views/frame/browser_frame_mac.h
+++ b/chrome/browser/ui/views/frame/browser_frame_mac.h
@@ -13,6 +13,7 @@
 
 class BrowserFrame;
 class BrowserView;
+@protocol WindowTouchBarDelegate;
 @class ChromeCommandDispatcherDelegate;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -55,6 +56,7 @@
   BrowserView* browser_view_;  // Weak. Our ClientView.
   base::scoped_nsobject<ChromeCommandDispatcherDelegate>
       command_dispatcher_delegate_;
+  base::scoped_nsprotocol<id<WindowTouchBarDelegate>> touch_bar_delegate_;
 
   DISALLOW_COPY_AND_ASSIGN(BrowserFrameMac);
 };
diff --git a/chrome/browser/ui/views/frame/browser_frame_mac.mm b/chrome/browser/ui/views/frame/browser_frame_mac.mm
index b965f14..10455d9 100644
--- a/chrome/browser/ui/views/frame/browser_frame_mac.mm
+++ b/chrome/browser/ui/views/frame/browser_frame_mac.mm
@@ -8,6 +8,7 @@
 #include "chrome/browser/global_keyboard_shortcuts_mac.h"
 #include "chrome/browser/ui/browser_command_controller.h"
 #include "chrome/browser/ui/browser_commands.h"
+#import "chrome/browser/ui/browser_window_touch_bar_mac.h"
 #import "chrome/browser/ui/cocoa/browser_window_command_handler.h"
 #import "chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.h"
 #include "chrome/browser/ui/views/frame/browser_frame.h"
@@ -16,6 +17,7 @@
 #include "components/web_modal/web_contents_modal_dialog_host.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #import "ui/base/cocoa/window_size_constants.h"
+#import "ui/views/cocoa/window_touch_bar_delegate.h"
 
 namespace {
 
@@ -38,6 +40,38 @@
 
 }  // namespace
 
+// Bridge Obj-C class for WindowTouchBarDelegate and BrowserWindowTouchBar.
+@interface BrowserWindowTouchBarViewsDelegate
+    : NSObject<WindowTouchBarDelegate> {
+  Browser* browser_;  // Weak.
+  NSWindow* window_;  // Weak.
+  base::scoped_nsobject<BrowserWindowTouchBar> browserWindowTouchBar_;
+}
+
+@end
+
+@implementation BrowserWindowTouchBarViewsDelegate
+
+- (instancetype)initWithBrowser:(Browser*)browser window:(NSWindow*)window {
+  if ((self = [super init])) {
+    browser_ = browser;
+    window_ = window;
+  }
+
+  return self;
+}
+
+- (NSTouchBar*)makeTouchBar API_AVAILABLE(macos(10.12.2)) {
+  if (!browserWindowTouchBar_) {
+    browserWindowTouchBar_.reset([[BrowserWindowTouchBar alloc]
+        initWithBrowser:browser_
+                 window:window_]);
+  }
+  return [browserWindowTouchBar_ makeTouchBar];
+}
+
+@end
+
 BrowserFrameMac::BrowserFrameMac(BrowserFrame* browser_frame,
                                  BrowserView* browser_view)
     : views::NativeWidgetMac(browser_frame),
@@ -96,6 +130,12 @@
   [ns_window setCommandDispatcherDelegate:command_dispatcher_delegate_];
   [ns_window setCommandHandler:[[[BrowserWindowCommandHandler alloc] init]
                                    autorelease]];
+
+  touch_bar_delegate_.reset([[BrowserWindowTouchBarViewsDelegate alloc]
+      initWithBrowser:browser_view_->browser()
+               window:ns_window]);
+  [ns_window setWindowTouchBarDelegate:touch_bar_delegate_.get()];
+
   return ns_window.autorelease();
 }
 
@@ -106,6 +146,7 @@
       base::mac::ObjCCastStrict<NativeWidgetMacNSWindow>(window);
   [ns_window setCommandHandler:nil];
   [ns_window setCommandDispatcherDelegate:nil];
+  [ns_window setWindowTouchBarDelegate:nil];
 }
 
 int BrowserFrameMac::GetMinimizeButtonOffset() const {
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc
index 5963d3c5..9d02e1a7 100644
--- a/chrome/browser/ui/views/overlay/overlay_window_views.cc
+++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -309,7 +309,7 @@
   close_controls_view_->SetImage(
       views::Button::STATE_NORMAL,
       gfx::CreateVectorIcon(views::kIcCloseIcon,
-                            close_button_size_.width() * 2 / 3,
+                            std::round(close_button_size_.width() * 2.0 / 3.0),
                             kControlIconColor));
   const gfx::ImageSkia close_background =
       gfx::CreateVectorIcon(kPictureInPictureControlBackgroundIcon,
diff --git a/chrome/browser/ui/views/passwords/password_generation_popup_view_tester_views.cc b/chrome/browser/ui/views/passwords/password_generation_popup_view_tester_views.cc
index 92132c8f..9fd3b63f 100644
--- a/chrome/browser/ui/views/passwords/password_generation_popup_view_tester_views.cc
+++ b/chrome/browser/ui/views/passwords/password_generation_popup_view_tester_views.cc
@@ -7,8 +7,6 @@
 #include "chrome/browser/ui/views/passwords/password_generation_popup_view_views.h"
 #include "ui/events/event_utils.h"
 
-namespace autofill {
-
 std::unique_ptr<PasswordGenerationPopupViewTester>
 PasswordGenerationPopupViewTester::For(PasswordGenerationPopupView* view) {
   return std::make_unique<PasswordGenerationPopupViewTesterViews>(
@@ -28,5 +26,3 @@
                             ui::EventTimeForNow(), 0, 0);
   static_cast<views::View*>(view_)->OnMouseMoved(mouse_down);
 }
-
-}  // namespace autofill
diff --git a/chrome/browser/ui/views/passwords/password_generation_popup_view_tester_views.h b/chrome/browser/ui/views/passwords/password_generation_popup_view_tester_views.h
index 0ff110ef..486054c 100644
--- a/chrome/browser/ui/views/passwords/password_generation_popup_view_tester_views.h
+++ b/chrome/browser/ui/views/passwords/password_generation_popup_view_tester_views.h
@@ -8,8 +8,6 @@
 #include "base/macros.h"
 #include "chrome/browser/ui/passwords/password_generation_popup_view_tester.h"
 
-namespace autofill {
-
 class PasswordGenerationPopupViewViews;
 
 class PasswordGenerationPopupViewTesterViews
@@ -28,6 +26,4 @@
   DISALLOW_COPY_AND_ASSIGN(PasswordGenerationPopupViewTesterViews);
 };
 
-}  // namespace autofill
-
 #endif  // CHROME_BROWSER_UI_VIEWS_PASSWORDS_PASSWORD_GENERATION_POPUP_VIEW_TESTER_VIEWS_H_
diff --git a/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc b/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc
index 49862ef..10dbd29 100644
--- a/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc
+++ b/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc
@@ -24,8 +24,6 @@
 #include "ui/views/layout/grid_layout.h"
 #include "ui/views/widget/widget.h"
 
-namespace autofill {
-
 namespace {
 
 // Background color of the bottom part of the prompt.
@@ -45,21 +43,30 @@
   ~GeneratedPasswordBox() override = default;
 
   // |password| is the generated password, |suggestion| is the text to the left
-  // of it.
-  void Init(const base::string16& password, const base::string16& suggestion) {
+  // of it. |generating_state| means that the generated password is offered.
+  void Init(const base::string16& password,
+            const base::string16& suggestion,
+            PasswordGenerationPopupController::GenerationState state) {
     views::GridLayout* layout =
         SetLayoutManager(std::make_unique<views::GridLayout>(this));
     BuildColumnSet(layout);
     layout->StartRow(0, 0);
 
-    views::Label* suggestion_label =
-        new views::Label(suggestion, ChromeTextContext::CONTEXT_BODY_TEXT_LARGE,
-                         views::style::STYLE_PRIMARY);
+    views::Label* suggestion_label = new views::Label(
+        suggestion, ChromeTextContext::CONTEXT_BODY_TEXT_LARGE,
+        state == PasswordGenerationPopupController::kOfferGeneration
+            ? views::style::STYLE_PRIMARY
+            : STYLE_SECONDARY);
     layout->AddView(suggestion_label);
 
-    views::Label* password_label = new views::Label(
+    DCHECK(!password_label_);
+    password_label_ = new views::Label(
         password, ChromeTextContext::CONTEXT_BODY_TEXT_LARGE, STYLE_SECONDARY);
-    layout->AddView(password_label);
+    layout->AddView(password_label_);
+  }
+
+  void UpdatePassword(const base::string16& password) {
+    password_label_->SetText(password);
   }
 
   // views::View:
@@ -79,6 +86,8 @@
                           views::GridLayout::USE_PREF, 0, 0);
   }
 
+  views::Label* password_label_ = nullptr;
+
   DISALLOW_COPY_AND_ASSIGN(GeneratedPasswordBox);
 };
 
@@ -110,13 +119,14 @@
 }
 
 void PasswordGenerationPopupViewViews::UpdateState() {
-  if (static_cast<bool>(password_view_) != controller_->display_password()) {
-    // The state of the drop-down can change from editing generated password
-    // mode back to generation mode.
-    RemoveAllChildViews(true);
-    password_view_ = nullptr;
-    CreateLayoutAndChildren();
-  }
+  RemoveAllChildViews(true);
+  password_view_ = nullptr;
+  CreateLayoutAndChildren();
+}
+
+void PasswordGenerationPopupViewViews::UpdatePasswordValue() {
+  password_view_->UpdatePassword(controller_->password());
+  Layout();
 }
 
 void PasswordGenerationPopupViewViews::UpdateBoundsAndRedrawPopup() {
@@ -160,14 +170,15 @@
       provider->GetDistanceMetric(DISTANCE_TOAST_LABEL_VERTICAL);
   const int kHorizontalMargin =
       provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_HORIZONTAL);
-  if (controller_->display_password()) {
-    password_view_ = new GeneratedPasswordBox();
-    password_view_->SetBorder(
-        views::CreateEmptyBorder(kVerticalPadding, kHorizontalMargin,
-                                 kVerticalPadding, kHorizontalMargin));
-    password_view_->Init(controller_->password(), controller_->SuggestedText());
-    AddChildView(password_view_);
-  }
+
+  password_view_ = new GeneratedPasswordBox();
+  password_view_->SetBorder(
+      views::CreateEmptyBorder(kVerticalPadding, kHorizontalMargin,
+                               kVerticalPadding, kHorizontalMargin));
+  password_view_->Init(controller_->password(), controller_->SuggestedText(),
+                       controller_->state());
+  AddChildView(password_view_);
+  PasswordSelectionUpdated();
 
   views::StyledLabel* help_label =
       new views::StyledLabel(controller_->HelpText(), this);
@@ -227,5 +238,3 @@
 
   return new PasswordGenerationPopupViewViews(controller, observing_widget);
 }
-
-}  // namespace autofill
diff --git a/chrome/browser/ui/views/passwords/password_generation_popup_view_views.h b/chrome/browser/ui/views/passwords/password_generation_popup_view_views.h
index fc52a1d..c2f5c1a 100644
--- a/chrome/browser/ui/views/passwords/password_generation_popup_view_views.h
+++ b/chrome/browser/ui/views/passwords/password_generation_popup_view_views.h
@@ -10,8 +10,6 @@
 #include "chrome/browser/ui/views/autofill/autofill_popup_base_view.h"
 #include "ui/views/controls/styled_label_listener.h"
 
-namespace autofill {
-
 class PasswordGenerationPopupController;
 
 class PasswordGenerationPopupViewViews : public autofill::AutofillPopupBaseView,
@@ -27,6 +25,7 @@
   void Hide() override;
   gfx::Size GetPreferredSizeOfPasswordView() override;
   void UpdateState() override;
+  void UpdatePasswordValue() override;
   void UpdateBoundsAndRedrawPopup() override;
   void PasswordSelectionUpdated() override;
   bool IsPointInPasswordBounds(const gfx::Point& point) override;
@@ -47,7 +46,7 @@
                               const gfx::Range& range,
                               int event_flags) override;
 
-  // Sub view that displays the actual password to be saved.
+  // Sub view that displays the actual generated password.
   GeneratedPasswordBox* password_view_ = nullptr;
 
   // Controller for this view. Weak reference.
@@ -56,6 +55,4 @@
   DISALLOW_COPY_AND_ASSIGN(PasswordGenerationPopupViewViews);
 };
 
-}  // namespace autofill
-
 #endif  // CHROME_BROWSER_UI_VIEWS_PASSWORDS_PASSWORD_GENERATION_POPUP_VIEW_VIEWS_H_
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index 38a9847..8ad9de03 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "base/command_line.h"
+#include "base/feature_list.h"
 #include "base/i18n/number_formatting.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -30,6 +31,7 @@
 #include "components/autofill/core/common/autofill_constants.h"
 #include "components/google/core/browser/google_util.h"
 #include "components/password_manager/core/browser/password_manager_constants.h"
+#include "components/password_manager/core/common/password_manager_features.h"
 #include "components/safe_browsing/common/safe_browsing_prefs.h"
 #include "components/signin/core/browser/signin_buildflags.h"
 #include "components/strings/grit/components_strings.h"
@@ -1376,7 +1378,6 @@
   LocalizedString localized_strings[] = {
       {"passwordsAndAutofillPageTitle",
        IDS_SETTINGS_PASSWORDS_AND_AUTOFILL_PAGE_TITLE},
-      {"autofill", IDS_SETTINGS_AUTOFILL},
       {"googlePayments", IDS_SETTINGS_GOOGLE_PAYMENTS},
       {"googlePaymentsCached", IDS_SETTINGS_GOOGLE_PAYMENTS_CACHED},
       {"autofillFormsLabel", IDS_SETTINGS_AUTOFILL_TOGGLE_LABEL},
@@ -1387,7 +1388,6 @@
       {"addressPhone", IDS_SETTINGS_AUTOFILL_ADDRESSES_PHONE},
       {"addressEmail", IDS_SETTINGS_AUTOFILL_ADDRESSES_EMAIL},
       {"removeAddress", IDS_SETTINGS_ADDRESS_REMOVE},
-      {"creditCards", IDS_SETTINGS_AUTOFILL_CREDIT_CARD_HEADING},
       {"removeCreditCard", IDS_SETTINGS_CREDIT_CARD_REMOVE},
       {"clearCreditCard", IDS_SETTINGS_CREDIT_CARD_CLEAR},
       {"creditCardType", IDS_SETTINGS_AUTOFILL_CREDIT_CARD_TYPE_COLUMN_LABEL},
@@ -1401,7 +1401,6 @@
       {"addCreditCardTitle", IDS_SETTINGS_ADD_CREDIT_CARD_TITLE},
       {"canMakePaymentToggleLabel", IDS_SETTINGS_CAN_MAKE_PAYMENT_TOGGLE_LABEL},
       {"autofillDetail", IDS_SETTINGS_AUTOFILL_DETAIL},
-      {"passwords", IDS_SETTINGS_PASSWORDS},
       {"passwordsSavePasswordsLabel",
        IDS_SETTINGS_PASSWORDS_SAVE_PASSWORDS_TOGGLE_LABEL},
       {"passwordsAutosigninLabel",
@@ -1422,8 +1421,6 @@
       {"editPasswordUsernameLabel", IDS_SETTINGS_PASSWORDS_USERNAME},
       {"editPasswordPasswordLabel", IDS_SETTINGS_PASSWORDS_PASSWORD},
       {"noAddressesFound", IDS_SETTINGS_ADDRESS_NONE},
-      {"noCreditCardsFound", IDS_SETTINGS_CREDIT_CARD_NONE},
-      {"noCreditCardsPolicy", IDS_SETTINGS_CREDIT_CARD_DISABLED},
       {"noPasswordsFound", IDS_SETTINGS_PASSWORDS_NONE},
       {"noExceptionsFound", IDS_SETTINGS_PASSWORDS_EXCEPTIONS_NONE},
       {"import", IDS_PASSWORD_MANAGER_IMPORT_BUTTON},
@@ -1447,6 +1444,30 @@
       {"exportPasswordsFailTipsAnotherFolder",
        IDS_SETTINGS_PASSWORDS_EXPORTING_FAILURE_TIP_ANOTHER_FOLDER}};
 
+  // TODO(https://crbug.com/854562): Integrate these strings into the
+  // |localized_strings| array once Autofill Home is fully launched.
+  if (base::FeatureList::IsEnabled(password_manager::features::kAutofillHome)) {
+    html_source->AddLocalizedString("autofill",
+                                    IDS_SETTINGS_AUTOFILL_AUTOFILL_HOME);
+    html_source->AddLocalizedString("passwords",
+                                    IDS_SETTINGS_PASSWORDS_AUTOFILL_HOME);
+    html_source->AddLocalizedString("creditCards",
+                                    IDS_SETTINGS_AUTOFILL_PAYMENT_METHODS);
+    html_source->AddLocalizedString("noCreditCardsFound",
+                                    IDS_SETTINGS_PAYMENT_METHODS_NONE);
+    html_source->AddLocalizedString("noCreditCardsPolicy",
+                                    IDS_SETTINGS_PAYMENT_METHODS_DISABLED);
+  } else {
+    html_source->AddLocalizedString("autofill", IDS_SETTINGS_AUTOFILL);
+    html_source->AddLocalizedString("passwords", IDS_SETTINGS_PASSWORDS);
+    html_source->AddLocalizedString("creditCards",
+                                    IDS_SETTINGS_AUTOFILL_CREDIT_CARD_HEADING);
+    html_source->AddLocalizedString("noCreditCardsFound",
+                                    IDS_SETTINGS_CREDIT_CARD_NONE);
+    html_source->AddLocalizedString("noCreditCardsPolicy",
+                                    IDS_SETTINGS_CREDIT_CARD_DISABLED);
+  }
+
   html_source->AddString(
       "managePasswordsLabel",
       l10n_util::GetStringFUTF16(
@@ -1643,8 +1664,6 @@
     {"bookmarksCheckboxLabel", IDS_SETTINGS_BOOKMARKS_CHECKBOX_LABEL},
     {"passwordsCheckboxLabel", IDS_SETTINGS_PASSWORDS_CHECKBOX_LABEL},
     {"openTabsCheckboxLabel", IDS_SETTINGS_OPEN_TABS_CHECKBOX_LABEL},
-    {"enablePaymentsIntegrationCheckboxLabel",
-     IDS_SETTINGS_ENABLE_PAYMENTS_INTEGRATION_CHECKBOX_LABEL},
     {"manageSyncedDataTitle", IDS_SETTINGS_MANAGE_SYNCED_DATA_TITLE},
     {"encryptionOptionsTitle", IDS_SETTINGS_ENCRYPTION_OPTIONS},
     {"syncDataEncryptedText", IDS_SETTINGS_SYNC_DATA_ENCRYPTED_TEXT},
@@ -1666,6 +1685,18 @@
   AddLocalizedStringsBulk(html_source, localized_strings,
                           arraysize(localized_strings));
 
+  // TODO(https://crbug.com/854562): Integrate these strings into the
+  // |localized_strings| array once Autofill Home is fully launched.
+  if (base::FeatureList::IsEnabled(password_manager::features::kAutofillHome)) {
+    html_source->AddLocalizedString(
+        "enablePaymentsIntegrationCheckboxLabel",
+        IDS_SETTINGS_ENABLE_PAYMENTS_INTEGRATION_CHECKBOX_LABEL_AUTOFILL_HOME);
+  } else {
+    html_source->AddLocalizedString(
+        "enablePaymentsIntegrationCheckboxLabel",
+        IDS_SETTINGS_ENABLE_PAYMENTS_INTEGRATION_CHECKBOX_LABEL);
+  }
+
   // Format numbers to be used on the pin keyboard.
   for (int j = 0; j <= 9; j++) {
     html_source->AddString("pinKeyboard" + base::IntToString(j),
@@ -2326,6 +2357,10 @@
      IDS_SETTINGS_SITE_SETTINGS_SITE_CLEAR_STORAGE_CONFIRMATION},
     {"siteSettingsSiteClearStorageDialogTitle",
      IDS_SETTINGS_SITE_SETTINGS_SITE_CLEAR_STORAGE_DIALOG_TITLE},
+    {"siteSettingsSiteGroupResetDialogTitle",
+     IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_RESET_DIALOG_TITLE},
+    {"siteSettingsSiteGroupResetConfirmation",
+     IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_RESET_CONFIRMATION},
     {"siteSettingsSiteResetAll", IDS_SETTINGS_SITE_SETTINGS_SITE_RESET_ALL},
     {"siteSettingsSiteResetConfirmation",
      IDS_SETTINGS_SITE_SETTINGS_SITE_RESET_CONFIRMATION},
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 2443e6b6..3430b41 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -224,10 +224,6 @@
                                              base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-// Makes Flash plugin permissions persistent only through the current session.
-const base::Feature kEnableEphemeralFlashPermission{
-    "EnableEphemeralFlashPermission", base::FEATURE_DISABLED_BY_DEFAULT};
-
 // An experimental way of showing app banners, which has modal banners and gives
 // developers more control over when to show them.
 const base::Feature kExperimentalAppBanners {
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index a1cc4ac..a95a379 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -118,8 +118,6 @@
 extern const base::Feature kDownloadsLocationChange;
 #endif
 
-extern const base::Feature kEnableEphemeralFlashPermission;
-
 extern const base::Feature kExperimentalAppBanners;
 
 #if defined(OS_CHROMEOS)
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index a70812e7..a1d192a 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -292,10 +292,6 @@
 // Enables Domain Reliability Monitoring.
 const char kEnableDomainReliability[] = "enable-domain-reliability";
 
-// Makes Flash plugin permissions persistent only through the current session.
-const char kEnableEphemeralFlashPermission[] =
-    "enable-ephemeral-flash-permission";
-
 // Enables logging for extension activity.
 const char kEnableExtensionActivityLogging[] =
     "enable-extension-activity-logging";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 91c6e14b..8112233 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -96,7 +96,6 @@
 extern const char kEnableDeviceDiscoveryNotifications[];
 extern const char kEnableDevToolsExperiments[];
 extern const char kEnableDomainReliability[];
-extern const char kEnableEphemeralFlashPermission[];
 extern const char kEnableExtensionActivityLogging[];
 extern const char kEnableExtensionActivityLogTesting[];
 extern const char kEnableFastUnload[];
diff --git a/chrome/common/extensions/docs/examples/extensions/app_launcher/popup.css b/chrome/common/extensions/docs/examples/extensions/app_launcher/popup.css
index e5fd468..c42fc36 100644
--- a/chrome/common/extensions/docs/examples/extensions/app_launcher/popup.css
+++ b/chrome/common/extensions/docs/examples/extensions/app_launcher/popup.css
@@ -1,6 +1,6 @@
-// Copyright (c) 2010 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.
+/* Copyright (c) 2010 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. */
 
 html {
   overflow-x: hidden;
diff --git a/chrome/gpu/widevine_cdm_proxy_factory.cc b/chrome/gpu/widevine_cdm_proxy_factory.cc
index bab6fde..efdd80c 100644
--- a/chrome/gpu/widevine_cdm_proxy_factory.cc
+++ b/chrome/gpu/widevine_cdm_proxy_factory.cc
@@ -76,7 +76,6 @@
        0x90000001}};
 
   return std::make_unique<media::D3D11CdmProxy>(
-      kD3D11ConfigWidevineStreamId,
-      media::CdmProxy::Protocol::kIntelConvergedSecurityAndManageabilityEngine,
+      kD3D11ConfigWidevineStreamId, media::CdmProxy::Protocol::kIntel,
       std::move(function_id_map));
 }
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
index 124018f..9cd4c88 100644
--- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
+++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -1624,6 +1624,68 @@
   }
 }
 
+// Tests that |FillIntoFocusedField| doesn't fill read-only text fields.
+TEST_F(PasswordAutofillAgentTest, FillIntoFocusedReadonlyTextField) {
+  // Neither field should be autocompleted.
+  CheckTextFieldsDOMState(std::string(), false, std::string(), false);
+
+  // If the field is readonly, it should not be affected.
+  SetElementReadOnly(username_element_, true);
+  SimulateElementClick(kUsernameName);
+  password_autofill_agent_->FillIntoFocusedField(/*is_password=*/false,
+                                                 ASCIIToUTF16(kAliceUsername));
+  CheckTextFieldsDOMState(std::string(), false, std::string(), false);
+}
+
+// Tests that |FillIntoFocusedField| properly fills user-provided credentials.
+TEST_F(PasswordAutofillAgentTest, FillIntoFocusedWritableTextField) {
+  // Neither field should be autocompleted.
+  CheckTextFieldsDOMState(std::string(), false, std::string(), false);
+
+  // The same field should be filled if it is writable.
+  SetFocused(username_element_);
+
+  SetElementReadOnly(username_element_, false);
+  password_autofill_agent_->FillIntoFocusedField(/*is_password=*/false,
+                                                 ASCIIToUTF16(kAliceUsername));
+  CheckTextFieldsDOMState(kAliceUsername, true, std::string(), false);
+  CheckUsernameSelection(strlen(kAliceUsername), strlen(kAliceUsername));
+}
+
+// Tests that |FillIntoFocusedField| doesn't fill passwords in userfields.
+TEST_F(PasswordAutofillAgentTest, FillIntoFocusedFieldOnlyIntoPasswordFields) {
+  // Neither field should be autocompleted.
+  CheckTextFieldsDOMState(std::string(), false, std::string(), false);
+
+  // Filling a password into a username field doesn't work.
+  SimulateElementClick(kUsernameName);
+  password_autofill_agent_->FillIntoFocusedField(/*is_password=*/true,
+                                                 ASCIIToUTF16(kAlicePassword));
+  CheckTextFieldsDOMState(std::string(), false, std::string(), false);
+
+  // When a password field is focus, the filling works.
+  SimulateElementClick(kPasswordName);
+  password_autofill_agent_->FillIntoFocusedField(/*is_password=*/true,
+                                                 ASCIIToUTF16(kAlicePassword));
+  CheckTextFieldsDOMState(std::string(), false, kAlicePassword, true);
+}
+
+// Tests that |FillIntoFocusedField| fills last focused, not last clicked field.
+TEST_F(PasswordAutofillAgentTest, FillIntoFocusedFieldForNonClickFocus) {
+  // Neither field should be autocompleted.
+  CheckTextFieldsDOMState(std::string(), false, std::string(), false);
+
+  // Click the username but shift the focus without click to the password.
+  SimulateElementClick(kUsernameName);
+  SetFocused(password_element_);
+  // The completion should now affect ONLY the password field. Don't fill a
+  // password so the error on failure shows where the filling happened.
+  // (see FillIntoFocusedFieldOnlyIntoPasswordFields).
+  password_autofill_agent_->FillIntoFocusedField(/*is_password=*/false,
+                                                 ASCIIToUTF16("TextToFill"));
+  CheckTextFieldsDOMState(std::string(), false, "TextToFill", true);
+}
+
 // Tests that |ClearPreview| properly clears previewed username and password
 // with neither username nor password being previously autofilled.
 TEST_F(PasswordAutofillAgentTest,
@@ -3539,4 +3601,37 @@
   EXPECT_EQ(kAlicePassword, password_element_.SuggestedValue().Utf8());
 }
 
+TEST_F(PasswordAutofillAgentTest, FillDataWithNoPasswordId) {
+  ClearUsernameAndPasswordFields();
+
+  // Prepare fill data which contain the form ID, to trigger filling by IDs.
+  PasswordFormFillData data = fill_data_;
+  WebFormElement form_element = GetMainFrame()
+                                    ->GetDocument()
+                                    .GetElementById("LoginTestForm")
+                                    .To<WebFormElement>();
+  data.form_renderer_id = form_element.UniqueRendererFormId();
+  data.has_renderer_ids = true;
+  // Simulate that no field was found into which a password should be filled
+  // (i.e. no "current-password" field).
+  data.password_field.unique_renderer_id =
+      FormFieldData::kNotSetFormControlRendererId;
+
+  SimulateOnFillPasswordForm(data);
+
+  // The username and password should not have been autocompleted.
+  CheckTextFieldsSuggestedState("", false, "", false);
+
+  SimulateElementClick(kPasswordName);
+  SimulateSuggestionChoice(password_element_);
+
+  // Check that the correct suggestions were requested.
+  base::RunLoop().RunUntilIdle();
+  ASSERT_TRUE(fake_driver_.called_show_pw_suggestions());
+  EXPECT_EQ(kPasswordFillFormDataId, fake_driver_.show_pw_suggestions_key());
+  fake_driver_.reset_show_pw_suggestions();
+
+  CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
+}
+
 }  // namespace autofill
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index ff2a4c34..9f8f819 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -697,6 +697,7 @@
       "../browser/renderer_host/render_process_host_chrome_browsertest.cc",
       "../browser/repost_form_warning_browsertest.cc",
       "../browser/resource_coordinator/local_site_characteristics_data_store_factory_browsertest.cc",
+      "../browser/resource_coordinator/local_site_characteristics_database_browsertest.cc",
       "../browser/resource_coordinator/render_process_probe_browsertest.cc",
       "../browser/resource_coordinator/tab_activity_watcher_browsertest.cc",
       "../browser/resource_coordinator/tab_manager_browsertest.cc",
@@ -716,6 +717,7 @@
       "../browser/sessions/tab_restore_browsertest.cc",
       "../browser/site_details_browsertest.cc",
       "../browser/thumbnails/thumbnail_browsertest.cc",
+      "../browser/ui/bloated_renderer/bloated_renderer_tab_helper_browsertest.cc",
       "../browser/ui/blocked_content/popup_tracker_browsertest.cc",
       "../browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc",
       "../browser/ui/blocked_content/tab_under_blocker_browsertest.cc",
diff --git a/chrome/test/data/media/picture-in-picture/iframe-content.html b/chrome/test/data/media/picture-in-picture/iframe-content.html
index 71ece3b..80468c60 100644
--- a/chrome/test/data/media/picture-in-picture/iframe-content.html
+++ b/chrome/test/data/media/picture-in-picture/iframe-content.html
@@ -9,6 +9,10 @@
 <script>
   const video = document.querySelector('video');
 
+  video.addEventListener('loadedmetadata', function() {
+    window.parent.postMessage({ loadedmetadata: true }, '*');
+  });
+
   function enterPictureInPicture() {
     video.requestPictureInPicture().then(() => {
       domAutomationController.send('done');
diff --git a/chrome/test/data/media/picture-in-picture/iframe-test.html b/chrome/test/data/media/picture-in-picture/iframe-test.html
index 67bc99ec5..e4f4565a 100644
--- a/chrome/test/data/media/picture-in-picture/iframe-test.html
+++ b/chrome/test/data/media/picture-in-picture/iframe-test.html
@@ -18,5 +18,11 @@
   function removeFrame() {
     document.body.removeChild(document.querySelector('iframe'));
   }
+
+  window.addEventListener('message', function(event) {
+    if (event.data.loadedmetadata) {
+      document.title = 'loadedmetadata';
+    }
+  });
 </script>
 </html>
diff --git a/chrome/test/data/resource_coordinator/default_favicon.png b/chrome/test/data/resource_coordinator/default_favicon.png
new file mode 100644
index 0000000..c44e0f3
--- /dev/null
+++ b/chrome/test/data/resource_coordinator/default_favicon.png
Binary files differ
diff --git a/chrome/test/data/resource_coordinator/site_characteristics_test_page.html b/chrome/test/data/resource_coordinator/site_characteristics_test_page.html
new file mode 100644
index 0000000..c4a70712
--- /dev/null
+++ b/chrome/test/data/resource_coordinator/site_characteristics_test_page.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<html lang="en">
+
+<head>
+  <meta charset="utf-8">
+  <title>Site Characteristics Database Test Page</title>
+</head>
+
+<body>
+  <script>
+    // Requests permission to display Web Notifications.
+    function RequestNotificationsPermission() {
+      Notification.requestPermission(function (level) {
+        domAutomationController.send(level);
+      });
+    }
+
+    // Instantiates a new non-persistent notification with the given |title|
+    // and |options| and then closes it.
+    function DisplayAndCloseNonPersistentNotification(title, options) {
+      const notification = new Notification(title, options || {});
+      notification.addEventListener('show', e => {
+        notification.close();
+      });
+      notification.addEventListener('close', e => {
+        domAutomationController.send('ok');
+      });
+    }
+
+    // Play |test_audio.ogg|.
+    function PlayAudio() {
+      var audio = new Audio('test_audio.ogg');
+      audio.addEventListener('loadeddata', function () {
+        audio.play();
+      })
+    }
+
+    // Change the page title to |new_title|
+    function ChangeTitle(new_title) {
+      document.title = new_title;
+    }
+
+    // Change the favicon to |default_favicon.png|.
+    function ChangeFavicon() {
+      favicon = document.createElement('link');
+      favicon.setAttribute('rel', 'shortcut icon');
+      var head = document.querySelector('head');
+      head.appendChild(favicon);
+      favicon.setAttribute('type', 'image/png');
+      favicon.setAttribute('href', 'default_favicon.png');
+    }
+  </script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/chrome/test/data/resource_coordinator/test_audio.ogg b/chrome/test/data/resource_coordinator/test_audio.ogg
new file mode 100644
index 0000000..c6c4e2c
--- /dev/null
+++ b/chrome/test/data/resource_coordinator/test_audio.ogg
Binary files differ
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js
index 95452b4c..65b2a488 100644
--- a/chrome/test/data/webui/settings/cr_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -974,7 +974,9 @@
 
   /** @override */
   extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([
+    '../test_browser_proxy.js',
     'test_util.js',
+    'test_site_settings_prefs_browser_proxy.js',
     'site_entry_tests.js',
   ]),
 };
diff --git a/chrome/test/data/webui/settings/site_details_permission_tests.js b/chrome/test/data/webui/settings/site_details_permission_tests.js
index f4ff0e8..ecc421b4 100644
--- a/chrome/test/data/webui/settings/site_details_permission_tests.js
+++ b/chrome/test/data/webui/settings/site_details_permission_tests.js
@@ -244,6 +244,7 @@
   test('info string correct for drm disabled source', function() {
     const origin = 'https://www.example.com';
     testElement.category = settings.ContentSettingsTypes.PROTECTED_CONTENT;
+    testElement.$.details.hidden = false;
     testElement.site = {
       origin: origin,
       embeddingOrigin: origin,
diff --git a/chrome/test/data/webui/settings/site_details_tests.js b/chrome/test/data/webui/settings/site_details_tests.js
index 5d0a9e5..9706e1cb 100644
--- a/chrome/test/data/webui/settings/site_details_tests.js
+++ b/chrome/test/data/webui/settings/site_details_tests.js
@@ -158,7 +158,7 @@
       loadTimeData.overrideValues(loadTimeDataOverride);
       testElement = createSiteDetails('https://foo.com:443');
       assertEquals(
-          numContentSettings + 1, testElement.getCategoryList_().length);
+          numContentSettings + 1, testElement.getCategoryList().length);
 
       // Check for setting = off at the end to ensure that the setting does
       // not carry over for the next iteration.
@@ -166,7 +166,7 @@
           [optionalSiteDetailsContentSettingsTypes[contentSetting]] = false;
       loadTimeData.overrideValues(loadTimeDataOverride);
       testElement = createSiteDetails('https://foo.com:443');
-      assertEquals(numContentSettings, testElement.getCategoryList_().length);
+      assertEquals(numContentSettings, testElement.getCategoryList().length);
     }
   });
 
@@ -320,7 +320,7 @@
     // Accepting the dialog will make a call to setOriginPermissions.
     return browserProxy.whenCalled('setOriginPermissions').then((args) => {
       assertEquals(testElement.origin, args[0]);
-      assertDeepEquals(testElement.getCategoryList_(), args[1]);
+      assertDeepEquals(testElement.getCategoryList(), args[1]);
       assertEquals(settings.ContentSetting.DEFAULT, args[2]);
     });
   });
diff --git a/chrome/test/data/webui/settings/site_entry_tests.js b/chrome/test/data/webui/settings/site_entry_tests.js
index b1511b7..946eea5 100644
--- a/chrome/test/data/webui/settings/site_entry_tests.js
+++ b/chrome/test/data/webui/settings/site_entry_tests.js
@@ -22,6 +22,12 @@
   ]);
 
   /**
+   * The mock proxy object to use during test.
+   * @type {TestSiteSettingsPrefsBrowserProxy}
+   */
+  let browserProxy;
+
+  /**
    * A site list element created before each test.
    * @type {SiteList}
    */
@@ -35,6 +41,9 @@
 
   // Initialize a site-list before each test.
   setup(function() {
+    browserProxy = new TestSiteSettingsPrefsBrowserProxy();
+    settings.SiteSettingsPrefsBrowserProxyImpl.instance_ = browserProxy;
+
     PolymerTest.clearBody();
     testElement = document.createElement('site-entry');
     assertTrue(!!testElement);
@@ -106,4 +115,49 @@
         TEST_MULTIPLE_SITE_GROUP.origins[1],
         settings.getQueryParameters().get('site'));
   });
+
+  test('with single origin does not show overflow menu', function() {
+    testElement.siteGroup = TEST_SINGLE_SITE_GROUP;
+    Polymer.dom.flush();
+    const overflowMenuButton = testElement.$.overflowMenuButton;
+    assertTrue(overflowMenuButton.closest('.row-aligned').hidden);
+  });
+
+  test(
+      'with multiple origins can reset settings via overflow menu', function() {
+        testElement.siteGroup = TEST_MULTIPLE_SITE_GROUP;
+        Polymer.dom.flush();
+        const overflowMenuButton = testElement.$.overflowMenuButton;
+        assertFalse(overflowMenuButton.closest('.row-aligned').hidden);
+
+        // Open the reset settings dialog and make sure both cancelling the
+        // action and resetting all permissions work.
+        const overflowMenu = testElement.$.menu.get();
+        const menuItems = overflowMenu.querySelectorAll('.dropdown-item');
+        ['cancel-button', 'action-button'].forEach(buttonType => {
+          // Test clicking on the overflow menu button opens the menu.
+          assertFalse(overflowMenu.open);
+          MockInteractions.tap(overflowMenuButton);
+          assertTrue(overflowMenu.open);
+
+          // Open the reset settings dialog and tap the |buttonType| button.
+          assertFalse(testElement.$.confirmResetSettings.open);
+          MockInteractions.tap(menuItems[0]);
+          assertTrue(testElement.$.confirmResetSettings.open);
+          const actionButtonList =
+              testElement.$.confirmResetSettings.getElementsByClassName(
+                  buttonType);
+          assertEquals(1, actionButtonList.length);
+          MockInteractions.tap(actionButtonList[0]);
+
+          // Check the dialog and overflow menu are now both closed.
+          assertFalse(testElement.$.confirmResetSettings.open);
+          assertFalse(overflowMenu.open);
+        });
+
+        // Ensure a call was made to setOriginPermissions for each origin.
+        assertEquals(
+            TEST_MULTIPLE_SITE_GROUP.origins.length,
+            browserProxy.getCallCount('setOriginPermissions'));
+      });
 });
diff --git a/chromeos/components/proximity_auth/BUILD.gn b/chromeos/components/proximity_auth/BUILD.gn
index e6770ff..7bafc9e 100644
--- a/chromeos/components/proximity_auth/BUILD.gn
+++ b/chromeos/components/proximity_auth/BUILD.gn
@@ -55,8 +55,6 @@
     "//chromeos",
     "//chromeos/components/proximity_auth/logging",
     "//chromeos/components/proximity_auth/public/interfaces",
-    "//chromeos/services/secure_channel/public/cpp/client",
-    "//chromeos/services/secure_channel/public/mojom",
     "//components/account_id",
     "//components/cryptauth",
     "//components/cryptauth/ble",
@@ -115,7 +113,6 @@
     "//chromeos",
     "//chromeos/components/proximity_auth/logging",
     "//chromeos/components/proximity_auth/logging:unit_tests",
-    "//chromeos/services/secure_channel/public/cpp/client:test_support",
     "//components/cryptauth:test_support",
     "//components/prefs:test_support",
     "//components/sync_preferences:test_support",
diff --git a/chromeos/components/proximity_auth/proximity_monitor_impl.cc b/chromeos/components/proximity_auth/proximity_monitor_impl.cc
index c857d66..df21020a 100644
--- a/chromeos/components/proximity_auth/proximity_monitor_impl.cc
+++ b/chromeos/components/proximity_auth/proximity_monitor_impl.cc
@@ -16,7 +16,6 @@
 #include "chromeos/components/proximity_auth/metrics.h"
 #include "chromeos/components/proximity_auth/proximity_auth_pref_manager.h"
 #include "chromeos/components/proximity_auth/proximity_monitor_observer.h"
-#include "chromeos/services/secure_channel/public/cpp/client/client_channel.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 
@@ -34,17 +33,13 @@
 const int kDefaultRssiThreshold = -70;
 
 ProximityMonitorImpl::ProximityMonitorImpl(
-    cryptauth::RemoteDeviceRef remote_device,
-    chromeos::secure_channel::ClientChannel* channel,
     cryptauth::Connection* connection,
     ProximityAuthPrefManager* pref_manager)
-    : remote_device_(remote_device),
-      channel_(channel),
-      connection_(connection),
-      pref_manager_(pref_manager),
+    : connection_(connection),
       remote_device_is_in_proximity_(false),
       is_active_(false),
       rssi_threshold_(kDefaultRssiThreshold),
+      pref_manager_(pref_manager),
       polling_weak_ptr_factory_(this),
       weak_ptr_factory_(this) {
   if (device::BluetoothAdapterFactory::IsBluetoothSupported()) {
@@ -81,7 +76,7 @@
                                     : metrics::kUnknownProximityValue;
 
   std::string remote_device_model = metrics::kUnknownDeviceModel;
-  cryptauth::RemoteDeviceRef remote_device = remote_device_;
+  cryptauth::RemoteDeviceRef remote_device = connection_->remote_device();
   if (!remote_device.name().empty())
     remote_device_model = remote_device.name();
 
@@ -136,69 +131,37 @@
 void ProximityMonitorImpl::Poll() {
   DCHECK(ShouldPoll());
 
-  if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) {
-    if (channel_->is_disconnected()) {
-      PA_LOG(ERROR) << "Channel is disconnected.";
-      ClearProximityState();
-      return;
-    }
+  std::string address = connection_->GetDeviceAddress();
+  BluetoothDevice* device = bluetooth_adapter_->GetDevice(address);
 
-    channel_->GetConnectionMetadata(
-        base::BindOnce(&ProximityMonitorImpl::OnGetConnectionMetadata,
-                       weak_ptr_factory_.GetWeakPtr()));
-  } else {
-    std::string address = connection_->GetDeviceAddress();
-    BluetoothDevice* device = bluetooth_adapter_->GetDevice(address);
-
-    if (!device) {
-      PA_LOG(ERROR) << "Unknown Bluetooth device with address " << address;
-      ClearProximityState();
-      return;
-    }
-    if (!device->IsConnected()) {
-      PA_LOG(ERROR) << "Bluetooth device with address " << address
-                    << " is not connected.";
-      ClearProximityState();
-      return;
-    }
-
-    device->GetConnectionInfo(
-        base::BindRepeating(&ProximityMonitorImpl::OnConnectionInfo,
-                            weak_ptr_factory_.GetWeakPtr()));
+  if (!device) {
+    PA_LOG(ERROR) << "Unknown Bluetooth device with address " << address;
+    ClearProximityState();
+    return;
   }
-}
+  if (!device->IsConnected()) {
+    PA_LOG(ERROR) << "Bluetooth device with address " << address
+                  << " is not connected.";
+    ClearProximityState();
+    return;
+  }
 
-void ProximityMonitorImpl::OnGetConnectionMetadata(
-    chromeos::secure_channel::mojom::ConnectionMetadataPtr
-        connection_metadata) {
-  DCHECK(base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
-
-  if (connection_metadata->bluetooth_connection_metadata)
-    OnGetRssi(connection_metadata->bluetooth_connection_metadata->current_rssi);
-  else
-    OnGetRssi(base::nullopt);
+  device->GetConnectionInfo(base::Bind(&ProximityMonitorImpl::OnConnectionInfo,
+                                       weak_ptr_factory_.GetWeakPtr()));
 }
 
 void ProximityMonitorImpl::OnConnectionInfo(
     const BluetoothDevice::ConnectionInfo& connection_info) {
-  DCHECK(!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
-
-  if (connection_info.rssi == BluetoothDevice::kUnknownPower)
-    OnGetRssi(base::nullopt);
-  else
-    OnGetRssi(connection_info.rssi);
-}
-
-void ProximityMonitorImpl::OnGetRssi(const base::Optional<int32_t>& rssi) {
   if (!is_active_) {
-    PA_LOG(INFO) << "Received RSSI after stopping.";
+    PA_LOG(INFO) << "[Proximity] Got connection info after stopping";
     return;
   }
 
-  if (rssi) {
-    AddSample(*rssi);
+  if (connection_info.rssi != BluetoothDevice::kUnknownPower) {
+    AddSample(connection_info);
   } else {
-    PA_LOG(WARNING) << "Received invalid RSSI value.";
+    PA_LOG(WARNING) << "[Proximity] Unknown values received from API: "
+                    << connection_info.rssi;
     rssi_rolling_average_.reset();
     CheckForProximityStateChange();
   }
@@ -214,13 +177,14 @@
   rssi_rolling_average_.reset();
 }
 
-void ProximityMonitorImpl::AddSample(int32_t rssi) {
+void ProximityMonitorImpl::AddSample(
+    const BluetoothDevice::ConnectionInfo& connection_info) {
   double weight = kRssiSampleWeight;
   if (!rssi_rolling_average_) {
-    rssi_rolling_average_.reset(new double(rssi));
+    rssi_rolling_average_.reset(new double(connection_info.rssi));
   } else {
     *rssi_rolling_average_ =
-        weight * rssi + (1 - weight) * (*rssi_rolling_average_);
+        weight * connection_info.rssi + (1 - weight) * (*rssi_rolling_average_);
   }
 
   CheckForProximityStateChange();
diff --git a/chromeos/components/proximity_auth/proximity_monitor_impl.h b/chromeos/components/proximity_auth/proximity_monitor_impl.h
index d8153be..17fca4ec 100644
--- a/chromeos/components/proximity_auth/proximity_monitor_impl.h
+++ b/chromeos/components/proximity_auth/proximity_monitor_impl.h
@@ -11,23 +11,14 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
-#include "base/optional.h"
-#include "chromeos/chromeos_features.h"
 #include "chromeos/components/proximity_auth/proximity_monitor.h"
-#include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h"
 #include "components/cryptauth/connection.h"
 #include "components/cryptauth/remote_device_ref.h"
 #include "device/bluetooth/bluetooth_device.h"
 
-namespace chromeos {
-namespace secure_channel {
-class ClientChannel;
-}  // namespace secure_channel
-}  // namespace chromeos
-
 namespace device {
 class BluetoothAdapter;
-}  // namespace device
+}
 
 namespace proximity_auth {
 
@@ -38,9 +29,7 @@
 class ProximityMonitorImpl : public ProximityMonitor {
  public:
   // The |connection| is not owned, and must outlive |this| instance.
-  ProximityMonitorImpl(cryptauth::RemoteDeviceRef remote_device,
-                       chromeos::secure_channel::ClientChannel* channel,
-                       cryptauth::Connection* connection,
+  ProximityMonitorImpl(cryptauth::Connection* connection,
                        ProximityAuthPrefManager* pref_manager);
   ~ProximityMonitorImpl() override;
 
@@ -73,19 +62,18 @@
   // Polls the connection information.
   void Poll();
 
-  void OnGetConnectionMetadata(
-      chromeos::secure_channel::mojom::ConnectionMetadataPtr
-          connection_metadata);
+  // Callback to received the polled-for connection info.
   void OnConnectionInfo(
       const device::BluetoothDevice::ConnectionInfo& connection_info);
-  void OnGetRssi(const base::Optional<int32_t>& rssi);
 
   // Resets the proximity state to |false|, and clears all member variables
   // tracking the proximity state.
   void ClearProximityState();
 
-  // Updates the proximity state with a new sample of the current RSSI.
-  void AddSample(int32_t rssi);
+  // Updates the proximity state with a new |connection_info| sample of the
+  // current RSSI.
+  void AddSample(
+      const device::BluetoothDevice::ConnectionInfo& connection_info);
 
   // Checks whether the proximity state has changed based on the current
   // samples. Notifies |observers_| on a change.
@@ -95,19 +83,10 @@
   // RSSI value.
   void GetRssiThresholdFromPrefs();
 
-  // Used to get the name of the remote device that ProximitMonitor is
-  // communicating with, for metrics purposes.
-  cryptauth::RemoteDeviceRef remote_device_;
-
-  // Used to communicate with the remote device to gauge its proximity via RSSI
-  // measurement.
-  chromeos::secure_channel::ClientChannel* channel_;
+  // The current connection being monitored. Not owned and must outlive this
+  // instance.
   cryptauth::Connection* connection_;
 
-  // Used to get determine the user pref for how far away the phone is allowed
-  // to be.
-  ProximityAuthPrefManager* pref_manager_;
-
   // The observers attached to the ProximityMonitor.
   base::ObserverList<ProximityMonitorObserver> observers_;
 
@@ -131,6 +110,10 @@
   // measurement.
   std::unique_ptr<double> rssi_rolling_average_;
 
+  // Contains perferences that outlive the lifetime of this object and across
+  // process restarts. Not owned and must outlive this instance.
+  ProximityAuthPrefManager* pref_manager_;
+
   // Used to vend weak pointers for polling. Using a separate factory for these
   // weak pointers allows the weak pointers to be invalidated when polling
   // stops, which effectively cancels the scheduled tasks.
diff --git a/chromeos/components/proximity_auth/proximity_monitor_impl_unittest.cc b/chromeos/components/proximity_auth/proximity_monitor_impl_unittest.cc
index 7736a7d..acf782a8 100644
--- a/chromeos/components/proximity_auth/proximity_monitor_impl_unittest.cc
+++ b/chromeos/components/proximity_auth/proximity_monitor_impl_unittest.cc
@@ -11,16 +11,13 @@
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.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/test/test_simple_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
-#include "chromeos/chromeos_features.h"
 #include "chromeos/components/proximity_auth/logging/logging.h"
 #include "chromeos/components/proximity_auth/proximity_auth_profile_pref_manager.h"
 #include "chromeos/components/proximity_auth/proximity_monitor_observer.h"
-#include "chromeos/services/secure_channel/public/cpp/client/fake_client_channel.h"
 #include "components/cryptauth/fake_connection.h"
 #include "components/cryptauth/remote_device_ref.h"
 #include "components/cryptauth/remote_device_test_util.h"
@@ -93,18 +90,13 @@
                                  "",
                                  false /* paired */,
                                  true /* connected */),
-        fake_client_channel_(
-            std::make_unique<chromeos::secure_channel::FakeClientChannel>()),
         remote_device_(cryptauth::RemoteDeviceRefBuilder()
                            .SetUserId(kRemoteDeviceUserId)
                            .SetName(kRemoteDeviceName)
                            .Build()),
         connection_(remote_device_),
         pref_manager_(new NiceMock<MockProximityAuthPrefManager>()),
-        monitor_(remote_device_,
-                 fake_client_channel_.get(),
-                 &connection_,
-                 pref_manager_.get()),
+        monitor_(&connection_, pref_manager_.get()),
         task_runner_(new base::TestSimpleTaskRunner()),
         thread_task_runner_handle_(task_runner_) {
     ON_CALL(*bluetooth_adapter_, GetDevice(std::string()))
@@ -118,42 +110,16 @@
 
   ~ProximityAuthProximityMonitorImplTest() override {}
 
-  void SetMultiDeviceApiEnabled() {
-    scoped_feature_list_.InitAndEnableFeature(
-        chromeos::features::kMultiDeviceApi);
-  }
-
   void RunPendingTasks() { task_runner_->RunPendingTasks(); }
 
-  void ProvideRssi(base::Optional<int32_t> rssi) {
+  void ProvideConnectionInfo(
+      const BluetoothDevice::ConnectionInfo& connection_info) {
     RunPendingTasks();
+    connection_info_callback_.Run(connection_info);
 
-    if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) {
-      std::vector<chromeos::secure_channel::mojom::ConnectionCreationDetail>
-          creation_details{
-              chromeos::secure_channel::mojom::ConnectionCreationDetail::
-                  REMOTE_DEVICE_USED_BACKGROUND_BLE_ADVERTISING};
-
-      chromeos::secure_channel::mojom::BluetoothConnectionMetadataPtr
-          bluetooth_connection_metadata_ptr;
-      if (rssi) {
-        bluetooth_connection_metadata_ptr =
-            chromeos::secure_channel::mojom::BluetoothConnectionMetadata::New(
-                *rssi);
-      }
-
-      chromeos::secure_channel::mojom::ConnectionMetadataPtr
-          connection_metadata_ptr =
-              chromeos::secure_channel::mojom::ConnectionMetadata::New(
-                  creation_details,
-                  std::move(bluetooth_connection_metadata_ptr));
-      fake_client_channel_->InvokePendingGetConnectionMetadataCallback(
-          std::move(connection_metadata_ptr));
-    } else {
-      ProvideConnectionInfo({rssi ? *rssi : BluetoothDevice::kUnknownPower,
-                             4 /* transmit_power */,
-                             4 /* max_transmit_power */});
-    }
+    // Reset the callback to ensure that tests correctly only respond at most
+    // once per call to GetConnectionInfo().
+    connection_info_callback_ = BluetoothDevice::ConnectionInfoCallback();
   }
 
  protected:
@@ -163,8 +129,6 @@
   // Mocks used for verifying interactions with the Bluetooth subsystem.
   scoped_refptr<device::MockBluetoothAdapter> bluetooth_adapter_;
   NiceMock<device::MockBluetoothDevice> remote_bluetooth_device_;
-  std::unique_ptr<chromeos::secure_channel::FakeClientChannel>
-      fake_client_channel_;
   cryptauth::RemoteDeviceRef remote_device_;
   cryptauth::FakeConnection connection_;
 
@@ -175,23 +139,10 @@
   ProximityMonitorImpl monitor_;
 
  private:
-  void ProvideConnectionInfo(
-      const BluetoothDevice::ConnectionInfo& connection_info) {
-    DCHECK(!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
-
-    connection_info_callback_.Run(connection_info);
-
-    // Reset the callback to ensure that tests correctly only respond at most
-    // once per call to GetConnectionInfo().
-    connection_info_callback_ = BluetoothDevice::ConnectionInfoCallback();
-  }
-
   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
   base::ThreadTaskRunnerHandle thread_task_runner_handle_;
   BluetoothDevice::ConnectionInfoCallback connection_info_callback_;
   ScopedDisableLoggingForTesting disable_logging_;
-
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_NeverStarted) {
@@ -199,51 +150,22 @@
 }
 
 TEST_F(ProximityAuthProximityMonitorImplTest,
-       IsUnlockAllowed_Started_NoRssiReceivedYet) {
-  monitor_.Start();
-  EXPECT_FALSE(monitor_.IsUnlockAllowed());
-}
-
-TEST_F(ProximityAuthProximityMonitorImplTest,
-       IsUnlockAllowed_Started_NoRssiReceivedYet_MultiDeviceApiEnabled) {
-  SetMultiDeviceApiEnabled();
-
+       IsUnlockAllowed_Started_NoConnectionInfoReceivedYet) {
   monitor_.Start();
   EXPECT_FALSE(monitor_.IsUnlockAllowed());
 }
 
 TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_RssiInRange) {
   monitor_.Start();
-  ProvideRssi(4);
-  EXPECT_TRUE(monitor_.IsUnlockAllowed());
-}
-
-TEST_F(ProximityAuthProximityMonitorImplTest,
-       IsUnlockAllowed_RssiInRange_MultiDeviceApiEnabled) {
-  SetMultiDeviceApiEnabled();
-
-  monitor_.Start();
-  ProvideRssi(4);
+  ProvideConnectionInfo({0, 4, 4});
   EXPECT_TRUE(monitor_.IsUnlockAllowed());
 }
 
 TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_UnknownRssi) {
   monitor_.Start();
 
-  ProvideRssi(0);
-  ProvideRssi(base::nullopt);
-
-  EXPECT_FALSE(monitor_.IsUnlockAllowed());
-}
-
-TEST_F(ProximityAuthProximityMonitorImplTest,
-       IsUnlockAllowed_UnknownRssi_MultiDeviceApiEnabled) {
-  SetMultiDeviceApiEnabled();
-
-  monitor_.Start();
-
-  ProvideRssi(0);
-  ProvideRssi(base::nullopt);
+  ProvideConnectionInfo({0, 0, 4});
+  ProvideConnectionInfo({BluetoothDevice::kUnknownPower, 0, 4});
 
   EXPECT_FALSE(monitor_.IsUnlockAllowed());
 }
@@ -256,53 +178,20 @@
 
   // Simulate receiving an RSSI reading in proximity.
   EXPECT_CALL(observer_, OnProximityStateChanged()).Times(1);
-  ProvideRssi(kRssiThreshold / 2);
+  ProvideConnectionInfo({kRssiThreshold / 2, 4, 4});
   EXPECT_TRUE(monitor_.IsUnlockAllowed());
 
   // Simulate a reading indicating non-proximity.
   EXPECT_CALL(observer_, OnProximityStateChanged()).Times(1);
-  ProvideRssi(kRssiThreshold * 2);
-  ProvideRssi(kRssiThreshold * 2);
-  EXPECT_FALSE(monitor_.IsUnlockAllowed());
-}
-
-TEST_F(ProximityAuthProximityMonitorImplTest,
-       IsUnlockAllowed_InformsObserverOfChanges_MultiDeviceApiEnabled) {
-  SetMultiDeviceApiEnabled();
-
-  // Initially, the device is not in proximity.
-  monitor_.Start();
-  EXPECT_FALSE(monitor_.IsUnlockAllowed());
-
-  // Simulate receiving an RSSI reading in proximity.
-  EXPECT_CALL(observer_, OnProximityStateChanged()).Times(1);
-  ProvideRssi(kRssiThreshold / 2);
-  EXPECT_TRUE(monitor_.IsUnlockAllowed());
-
-  // Simulate a reading indicating non-proximity.
-  EXPECT_CALL(observer_, OnProximityStateChanged()).Times(1);
-  ProvideRssi(kRssiThreshold * 2);
-  ProvideRssi(kRssiThreshold * 2);
+  ProvideConnectionInfo({2 * kRssiThreshold, 4, 4});
+  ProvideConnectionInfo({2 * kRssiThreshold, 4, 4});
   EXPECT_FALSE(monitor_.IsUnlockAllowed());
 }
 
 TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_StartThenStop) {
   monitor_.Start();
 
-  ProvideRssi(0);
-  EXPECT_TRUE(monitor_.IsUnlockAllowed());
-
-  monitor_.Stop();
-  EXPECT_FALSE(monitor_.IsUnlockAllowed());
-}
-
-TEST_F(ProximityAuthProximityMonitorImplTest,
-       IsUnlockAllowed_StartThenStop_MultiDeviceApiEnabled) {
-  SetMultiDeviceApiEnabled();
-
-  monitor_.Start();
-
-  ProvideRssi(0);
+  ProvideConnectionInfo({0, 0, 4});
   EXPECT_TRUE(monitor_.IsUnlockAllowed());
 
   monitor_.Stop();
@@ -312,39 +201,18 @@
 TEST_F(ProximityAuthProximityMonitorImplTest,
        IsUnlockAllowed_StartThenStopThenStartAgain) {
   monitor_.Start();
-  ProvideRssi(kRssiThreshold / 2);
-  ProvideRssi(kRssiThreshold / 2);
-  ProvideRssi(kRssiThreshold / 2);
-  ProvideRssi(kRssiThreshold / 2);
-  ProvideRssi(kRssiThreshold / 2);
+  ProvideConnectionInfo({kRssiThreshold / 2, 4, 4});
+  ProvideConnectionInfo({kRssiThreshold / 2, 4, 4});
+  ProvideConnectionInfo({kRssiThreshold / 2, 4, 4});
+  ProvideConnectionInfo({kRssiThreshold / 2, 4, 4});
+  ProvideConnectionInfo({kRssiThreshold / 2, 4, 4});
   EXPECT_TRUE(monitor_.IsUnlockAllowed());
   monitor_.Stop();
 
   // Restarting the monitor should immediately reset the proximity state, rather
   // than building on the previous rolling average.
   monitor_.Start();
-  ProvideRssi(kRssiThreshold - 1);
-
-  EXPECT_FALSE(monitor_.IsUnlockAllowed());
-}
-
-TEST_F(ProximityAuthProximityMonitorImplTest,
-       IsUnlockAllowed_StartThenStopThenStartAgain_MultiDeviceApiEnabled) {
-  SetMultiDeviceApiEnabled();
-
-  monitor_.Start();
-  ProvideRssi(kRssiThreshold / 2);
-  ProvideRssi(kRssiThreshold / 2);
-  ProvideRssi(kRssiThreshold / 2);
-  ProvideRssi(kRssiThreshold / 2);
-  ProvideRssi(kRssiThreshold / 2);
-  EXPECT_TRUE(monitor_.IsUnlockAllowed());
-  monitor_.Stop();
-
-  // Restarting the monitor should immediately reset the proximity state, rather
-  // than building on the previous rolling average.
-  monitor_.Start();
-  ProvideRssi(kRssiThreshold - 1);
+  ProvideConnectionInfo({kRssiThreshold - 1, 4, 4});
 
   EXPECT_FALSE(monitor_.IsUnlockAllowed());
 }
@@ -352,33 +220,15 @@
 TEST_F(ProximityAuthProximityMonitorImplTest,
        IsUnlockAllowed_RemoteDeviceRemainsInProximity) {
   monitor_.Start();
-  ProvideRssi(kRssiThreshold / 2 + 1);
-  ProvideRssi(kRssiThreshold / 2 - 1);
-  ProvideRssi(kRssiThreshold / 2 + 2);
-  ProvideRssi(kRssiThreshold / 2 - 3);
+  ProvideConnectionInfo({kRssiThreshold / 2 + 1, 4, 4});
+  ProvideConnectionInfo({kRssiThreshold / 2 - 1, 4, 4});
+  ProvideConnectionInfo({kRssiThreshold / 2 + 2, 4, 4});
+  ProvideConnectionInfo({kRssiThreshold / 2 - 3, 4, 4});
 
   EXPECT_TRUE(monitor_.IsUnlockAllowed());
 
   // Brief drops in RSSI should be handled by weighted averaging.
-  ProvideRssi(kRssiThreshold - 5);
-
-  EXPECT_TRUE(monitor_.IsUnlockAllowed());
-}
-
-TEST_F(ProximityAuthProximityMonitorImplTest,
-       IsUnlockAllowed_RemoteDeviceRemainsInProximity_MultiDeviceApiEnabled) {
-  SetMultiDeviceApiEnabled();
-
-  monitor_.Start();
-  ProvideRssi(kRssiThreshold / 2 + 1);
-  ProvideRssi(kRssiThreshold / 2 - 1);
-  ProvideRssi(kRssiThreshold / 2 + 2);
-  ProvideRssi(kRssiThreshold / 2 - 3);
-
-  EXPECT_TRUE(monitor_.IsUnlockAllowed());
-
-  // Brief drops in RSSI should be handled by weighted averaging.
-  ProvideRssi(kRssiThreshold - 5);
+  ProvideConnectionInfo({kRssiThreshold - 5, 4, 4});
 
   EXPECT_TRUE(monitor_.IsUnlockAllowed());
 }
@@ -388,49 +238,22 @@
   monitor_.Start();
 
   // Start with a device in proximity.
-  ProvideRssi(0);
+  ProvideConnectionInfo({0, 4, 4});
   EXPECT_TRUE(monitor_.IsUnlockAllowed());
 
   // Simulate readings for the remote device leaving proximity.
-  ProvideRssi(-1);
-  ProvideRssi(-4);
-  ProvideRssi(0);
-  ProvideRssi(-10);
-  ProvideRssi(-15);
-  ProvideRssi(-20);
-  ProvideRssi(kRssiThreshold);
-  ProvideRssi(kRssiThreshold - 10);
-  ProvideRssi(kRssiThreshold - 20);
-  ProvideRssi(kRssiThreshold - 20);
-  ProvideRssi(kRssiThreshold - 20);
-  ProvideRssi(kRssiThreshold - 20);
-
-  EXPECT_FALSE(monitor_.IsUnlockAllowed());
-}
-
-TEST_F(ProximityAuthProximityMonitorImplTest,
-       IsUnlockAllowed_RemoteDeviceLeavesProximity_MultiDeviceApiEnabled) {
-  SetMultiDeviceApiEnabled();
-
-  monitor_.Start();
-
-  // Start with a device in proximity.
-  ProvideRssi(0);
-  EXPECT_TRUE(monitor_.IsUnlockAllowed());
-
-  // Simulate readings for the remote device leaving proximity.
-  ProvideRssi(-1);
-  ProvideRssi(-4);
-  ProvideRssi(0);
-  ProvideRssi(-10);
-  ProvideRssi(-15);
-  ProvideRssi(-20);
-  ProvideRssi(kRssiThreshold);
-  ProvideRssi(kRssiThreshold - 10);
-  ProvideRssi(kRssiThreshold - 20);
-  ProvideRssi(kRssiThreshold - 20);
-  ProvideRssi(kRssiThreshold - 20);
-  ProvideRssi(kRssiThreshold - 20);
+  ProvideConnectionInfo({-1, 4, 4});
+  ProvideConnectionInfo({-4, 4, 4});
+  ProvideConnectionInfo({0, 4, 4});
+  ProvideConnectionInfo({-10, 4, 4});
+  ProvideConnectionInfo({-15, 4, 4});
+  ProvideConnectionInfo({-20, 4, 4});
+  ProvideConnectionInfo({kRssiThreshold, 4, 4});
+  ProvideConnectionInfo({kRssiThreshold - 10, 4, 4});
+  ProvideConnectionInfo({kRssiThreshold - 20, 4, 4});
+  ProvideConnectionInfo({kRssiThreshold - 20, 4, 4});
+  ProvideConnectionInfo({kRssiThreshold - 20, 4, 4});
+  ProvideConnectionInfo({kRssiThreshold - 20, 4, 4});
 
   EXPECT_FALSE(monitor_.IsUnlockAllowed());
 }
@@ -440,41 +263,19 @@
   monitor_.Start();
 
   // Start with a device out of proximity.
-  ProvideRssi(kRssiThreshold * 2);
+  ProvideConnectionInfo({2 * kRssiThreshold, 4, 4});
   EXPECT_FALSE(monitor_.IsUnlockAllowed());
 
   // Simulate readings for the remote device entering proximity.
-  ProvideRssi(-15);
-  ProvideRssi(-8);
-  ProvideRssi(-12);
-  ProvideRssi(-18);
-  ProvideRssi(-7);
-  ProvideRssi(-3);
-  ProvideRssi(-2);
-  ProvideRssi(0);
-  ProvideRssi(0);
-
-  EXPECT_TRUE(monitor_.IsUnlockAllowed());
-}
-
-TEST_F(ProximityAuthProximityMonitorImplTest,
-       IsUnlockAllowed_RemoteDeviceEntersProximity_MultiDeviceApiEnabled) {
-  monitor_.Start();
-
-  // Start with a device out of proximity.
-  ProvideRssi(kRssiThreshold * 2);
-  EXPECT_FALSE(monitor_.IsUnlockAllowed());
-
-  // Simulate readings for the remote device entering proximity.
-  ProvideRssi(-15);
-  ProvideRssi(-8);
-  ProvideRssi(-12);
-  ProvideRssi(-18);
-  ProvideRssi(-7);
-  ProvideRssi(-3);
-  ProvideRssi(-2);
-  ProvideRssi(0);
-  ProvideRssi(0);
+  ProvideConnectionInfo({-15, 4, 4});
+  ProvideConnectionInfo({-8, 4, 4});
+  ProvideConnectionInfo({-12, 4, 4});
+  ProvideConnectionInfo({-18, 4, 4});
+  ProvideConnectionInfo({-7, 4, 4});
+  ProvideConnectionInfo({-3, 4, 4});
+  ProvideConnectionInfo({-2, 4, 4});
+  ProvideConnectionInfo({0, 4, 4});
+  ProvideConnectionInfo({0, 4, 4});
 
   EXPECT_TRUE(monitor_.IsUnlockAllowed());
 }
@@ -484,24 +285,7 @@
   monitor_.Start();
 
   // Start with the device known to the adapter and in proximity.
-  ProvideRssi(0);
-  EXPECT_TRUE(monitor_.IsUnlockAllowed());
-
-  // Simulate it being forgotten.
-  ON_CALL(*bluetooth_adapter_, GetDevice(std::string()))
-      .WillByDefault(Return(nullptr));
-  EXPECT_CALL(observer_, OnProximityStateChanged());
-  RunPendingTasks();
-
-  EXPECT_FALSE(monitor_.IsUnlockAllowed());
-}
-
-TEST_F(ProximityAuthProximityMonitorImplTest,
-       IsUnlockAllowed_DeviceNotKnownToAdapter_MultiDeviceApiEnabled) {
-  monitor_.Start();
-
-  // Start with the device known to the adapter and in proximity.
-  ProvideRssi(0);
+  ProvideConnectionInfo({0, 4, 4});
   EXPECT_TRUE(monitor_.IsUnlockAllowed());
 
   // Simulate it being forgotten.
@@ -518,7 +302,7 @@
   monitor_.Start();
 
   // Start with the device connected and in proximity.
-  ProvideRssi(0);
+  ProvideConnectionInfo({0, 4, 4});
   EXPECT_TRUE(monitor_.IsUnlockAllowed());
 
   // Simulate it disconnecting.
@@ -530,66 +314,19 @@
 }
 
 TEST_F(ProximityAuthProximityMonitorImplTest,
-       IsUnlockAllowed_DeviceNotConnected_MultiDeviceApiEnabled) {
-  SetMultiDeviceApiEnabled();
-
-  monitor_.Start();
-
-  // Start with the device connected and in proximity.
-  ProvideRssi(0);
-  EXPECT_TRUE(monitor_.IsUnlockAllowed());
-
-  // Simulate it disconnecting.
-  fake_client_channel_->NotifyDisconnected();
-  EXPECT_CALL(observer_, OnProximityStateChanged());
-  RunPendingTasks();
-
-  EXPECT_FALSE(monitor_.IsUnlockAllowed());
-}
-
-TEST_F(ProximityAuthProximityMonitorImplTest,
        IsUnlockAllowed_ConnectionInfoReceivedAfterStopping) {
   monitor_.Start();
   monitor_.Stop();
-  ProvideRssi(0);
-  EXPECT_FALSE(monitor_.IsUnlockAllowed());
-}
-
-TEST_F(
-    ProximityAuthProximityMonitorImplTest,
-    IsUnlockAllowed_ConnectionInfoReceivedAfterStopping_MultiDeviceApiEnabled) {
-  SetMultiDeviceApiEnabled();
-
-  monitor_.Start();
-  monitor_.Stop();
-  ProvideRssi(0);
+  ProvideConnectionInfo({0, 4, 4});
   EXPECT_FALSE(monitor_.IsUnlockAllowed());
 }
 
 TEST_F(ProximityAuthProximityMonitorImplTest,
        RecordProximityMetricsOnAuthSuccess_NormalValues) {
   monitor_.Start();
-  ProvideRssi(0);
+  ProvideConnectionInfo({0, 0, 4});
 
-  ProvideRssi(-20);
-
-  base::HistogramTester histogram_tester;
-  monitor_.RecordProximityMetricsOnAuthSuccess();
-  histogram_tester.ExpectUniqueSample("EasyUnlock.AuthProximity.RollingRssi",
-                                      -6, 1);
-  histogram_tester.ExpectUniqueSample(
-      "EasyUnlock.AuthProximity.RemoteDeviceModelHash",
-      1881443083 /* hash of "LGE Nexus 5" */, 1);
-}
-
-TEST_F(ProximityAuthProximityMonitorImplTest,
-       RecordProximityMetricsOnAuthSuccess_NormalValues_MultiDeviceApiEnabled) {
-  SetMultiDeviceApiEnabled();
-
-  monitor_.Start();
-  ProvideRssi(0);
-
-  ProvideRssi(-20);
+  ProvideConnectionInfo({-20, 3, 4});
 
   base::HistogramTester histogram_tester;
   monitor_.RecordProximityMetricsOnAuthSuccess();
@@ -603,21 +340,7 @@
 TEST_F(ProximityAuthProximityMonitorImplTest,
        RecordProximityMetricsOnAuthSuccess_ClampedValues) {
   monitor_.Start();
-  ProvideRssi(-99999);
-
-  base::HistogramTester histogram_tester;
-  monitor_.RecordProximityMetricsOnAuthSuccess();
-  histogram_tester.ExpectUniqueSample("EasyUnlock.AuthProximity.RollingRssi",
-                                      -100, 1);
-}
-
-TEST_F(
-    ProximityAuthProximityMonitorImplTest,
-    RecordProximityMetricsOnAuthSuccess_ClampedValues_MultiDeviceApiEnabled) {
-  SetMultiDeviceApiEnabled();
-
-  monitor_.Start();
-  ProvideRssi(-99999);
+  ProvideConnectionInfo({-99999, 99999, 12345});
 
   base::HistogramTester histogram_tester;
   monitor_.RecordProximityMetricsOnAuthSuccess();
@@ -628,44 +351,15 @@
 TEST_F(ProximityAuthProximityMonitorImplTest,
        RecordProximityMetricsOnAuthSuccess_UnknownValues) {
   // Note: A device without a recorded name will have "Unknown" as its name.
-  cryptauth::RemoteDeviceRef remote_device = cryptauth::RemoteDeviceRefBuilder()
-                                                 .SetUserId(kRemoteDeviceUserId)
-                                                 .SetName(std::string())
-                                                 .Build();
-  cryptauth::FakeConnection connection(remote_device);
+  cryptauth::FakeConnection connection(cryptauth::RemoteDeviceRefBuilder()
+                                           .SetUserId(kRemoteDeviceUserId)
+                                           .SetName(std::string())
+                                           .Build());
 
-  ProximityMonitorImpl monitor(remote_device, fake_client_channel_.get(),
-                               &connection, pref_manager_.get());
+  ProximityMonitorImpl monitor(&connection, pref_manager_.get());
   monitor.AddObserver(&observer_);
   monitor.Start();
-  ProvideRssi(127);
-
-  base::HistogramTester histogram_tester;
-  monitor.RecordProximityMetricsOnAuthSuccess();
-  histogram_tester.ExpectUniqueSample("EasyUnlock.AuthProximity.RollingRssi",
-                                      127, 1);
-  histogram_tester.ExpectUniqueSample(
-      "EasyUnlock.AuthProximity.RemoteDeviceModelHash",
-      -1808066424 /* hash of "Unknown" */, 1);
-}
-
-TEST_F(
-    ProximityAuthProximityMonitorImplTest,
-    RecordProximityMetricsOnAuthSuccess_UnknownValues_MultiDeviceApiEnabled) {
-  SetMultiDeviceApiEnabled();
-
-  // Note: A device without a recorded name will have "Unknown" as its name.
-  cryptauth::RemoteDeviceRef remote_device = cryptauth::RemoteDeviceRefBuilder()
-                                                 .SetUserId(kRemoteDeviceUserId)
-                                                 .SetName(std::string())
-                                                 .Build();
-  cryptauth::FakeConnection connection(remote_device);
-
-  ProximityMonitorImpl monitor(remote_device, fake_client_channel_.get(),
-                               &connection, pref_manager_.get());
-  monitor.AddObserver(&observer_);
-  monitor.Start();
-  ProvideRssi(127);
+  ProvideConnectionInfo({127, 127, 127});
 
   base::HistogramTester histogram_tester;
   monitor.RecordProximityMetricsOnAuthSuccess();
diff --git a/chromeos/components/proximity_auth/unlock_manager_impl.cc b/chromeos/components/proximity_auth/unlock_manager_impl.cc
index d4bed74a..bf99248 100644
--- a/chromeos/components/proximity_auth/unlock_manager_impl.cc
+++ b/chromeos/components/proximity_auth/unlock_manager_impl.cc
@@ -324,10 +324,7 @@
 std::unique_ptr<ProximityMonitor> UnlockManagerImpl::CreateProximityMonitor(
     cryptauth::Connection* connection,
     ProximityAuthPrefManager* pref_manager) {
-  // TODO(crbug.com/752273): Inject a real ClientChannel.
-  return std::make_unique<ProximityMonitorImpl>(connection->remote_device(),
-                                                nullptr /* channel */,
-                                                connection, pref_manager);
+  return std::make_unique<ProximityMonitorImpl>(connection, pref_manager);
 }
 
 void UnlockManagerImpl::SendSignInChallenge() {
diff --git a/chromeos/login/auth/mock_auth_status_consumer.cc b/chromeos/login/auth/mock_auth_status_consumer.cc
index 1409dee..93574c5 100644
--- a/chromeos/login/auth/mock_auth_status_consumer.cc
+++ b/chromeos/login/auth/mock_auth_status_consumer.cc
@@ -10,66 +10,57 @@
 
 namespace chromeos {
 
-MockAuthStatusConsumer::MockAuthStatusConsumer() = default;
+MockAuthStatusConsumer::MockAuthStatusConsumer(base::OnceClosure quit_closure)
+    : quit_closure_(std::move(quit_closure)) {}
 
 MockAuthStatusConsumer::~MockAuthStatusConsumer() = default;
 
-// static
 void MockAuthStatusConsumer::OnRetailModeSuccessQuit(
     const UserContext& user_context) {
-  base::RunLoop::QuitCurrentWhenIdleDeprecated();
+  std::move(quit_closure_).Run();
 }
 
-// static
 void MockAuthStatusConsumer::OnRetailModeSuccessQuitAndFail(
     const UserContext& user_context) {
   ADD_FAILURE() << "Retail mode login should have failed!";
-  base::RunLoop::QuitCurrentWhenIdleDeprecated();
+  std::move(quit_closure_).Run();
 }
 
-// static
 void MockAuthStatusConsumer::OnGuestSuccessQuit() {
-  base::RunLoop::QuitCurrentWhenIdleDeprecated();
+  std::move(quit_closure_).Run();
 }
 
-// static
 void MockAuthStatusConsumer::OnGuestSuccessQuitAndFail() {
   ADD_FAILURE() << "Guest login should have failed!";
-  base::RunLoop::QuitCurrentWhenIdleDeprecated();
+  std::move(quit_closure_).Run();
 }
 
-// static
 void MockAuthStatusConsumer::OnSuccessQuit(const UserContext& user_context) {
-  base::RunLoop::QuitCurrentWhenIdleDeprecated();
+  std::move(quit_closure_).Run();
 }
 
-// static
 void MockAuthStatusConsumer::OnSuccessQuitAndFail(
     const UserContext& user_context) {
   ADD_FAILURE() << "Login should NOT have succeeded!";
-  base::RunLoop::QuitCurrentWhenIdleDeprecated();
+  std::move(quit_closure_).Run();
 }
 
-// static
 void MockAuthStatusConsumer::OnFailQuit(const AuthFailure& error) {
-  base::RunLoop::QuitCurrentWhenIdleDeprecated();
+  std::move(quit_closure_).Run();
 }
 
-// static
 void MockAuthStatusConsumer::OnFailQuitAndFail(const AuthFailure& error) {
   ADD_FAILURE() << "Login should not have failed!";
-  base::RunLoop::QuitCurrentWhenIdleDeprecated();
+  std::move(quit_closure_).Run();
 }
 
-// static
 void MockAuthStatusConsumer::OnMigrateQuit() {
-  base::RunLoop::QuitCurrentWhenIdleDeprecated();
+  std::move(quit_closure_).Run();
 }
 
-// static
 void MockAuthStatusConsumer::OnMigrateQuitAndFail() {
   ADD_FAILURE() << "Should not have detected a PW change!";
-  base::RunLoop::QuitCurrentWhenIdleDeprecated();
+  std::move(quit_closure_).Run();
 }
 
 }  // namespace chromeos
diff --git a/chromeos/login/auth/mock_auth_status_consumer.h b/chromeos/login/auth/mock_auth_status_consumer.h
index 649a6bb..c25fe433 100644
--- a/chromeos/login/auth/mock_auth_status_consumer.h
+++ b/chromeos/login/auth/mock_auth_status_consumer.h
@@ -5,6 +5,7 @@
 #ifndef CHROMEOS_LOGIN_AUTH_MOCK_AUTH_STATUS_CONSUMER_H_
 #define CHROMEOS_LOGIN_AUTH_MOCK_AUTH_STATUS_CONSUMER_H_
 
+#include "base/callback.h"
 #include "chromeos/chromeos_export.h"
 #include "chromeos/login/auth/auth_status_consumer.h"
 #include "chromeos/login/auth/user_context.h"
@@ -14,7 +15,7 @@
 
 class CHROMEOS_EXPORT MockAuthStatusConsumer : public AuthStatusConsumer {
  public:
-  MockAuthStatusConsumer();
+  explicit MockAuthStatusConsumer(base::OnceClosure quit_closure);
   virtual ~MockAuthStatusConsumer();
 
   MOCK_METHOD1(OnAuthFailure, void(const AuthFailure& error));
@@ -26,24 +27,27 @@
   // The following functions can be used in gmock Invoke() clauses.
 
   // Compatible with AuthStatusConsumer::OnRetailModeAuthSuccess()
-  static void OnRetailModeSuccessQuit(const UserContext& user_context);
-  static void OnRetailModeSuccessQuitAndFail(const UserContext& user_context);
+  void OnRetailModeSuccessQuit(const UserContext& user_context);
+  void OnRetailModeSuccessQuitAndFail(const UserContext& user_context);
 
   // Compatible with AuthStatusConsumer::OnOffTheRecordAuthSuccess()
-  static void OnGuestSuccessQuit();
-  static void OnGuestSuccessQuitAndFail();
+  void OnGuestSuccessQuit();
+  void OnGuestSuccessQuitAndFail();
 
   // Compatible with AuthStatusConsumer::OnAuthSuccess()
-  static void OnSuccessQuit(const UserContext& user_context);
-  static void OnSuccessQuitAndFail(const UserContext& user_context);
+  void OnSuccessQuit(const UserContext& user_context);
+  void OnSuccessQuitAndFail(const UserContext& user_context);
 
   // Compatible with AuthStatusConsumer::OnAuthFailure()
-  static void OnFailQuit(const AuthFailure& error);
-  static void OnFailQuitAndFail(const AuthFailure& error);
+  void OnFailQuit(const AuthFailure& error);
+  void OnFailQuitAndFail(const AuthFailure& error);
 
   // Compatible with AuthStatusConsumer::OnPasswordChangeDetected()
-  static void OnMigrateQuit();
-  static void OnMigrateQuitAndFail();
+  void OnMigrateQuit();
+  void OnMigrateQuitAndFail();
+
+ private:
+  base::OnceClosure quit_closure_;
 };
 
 }  // namespace chromeos
diff --git a/chromeos/services/secure_channel/public/cpp/client/fake_client_channel.cc b/chromeos/services/secure_channel/public/cpp/client/fake_client_channel.cc
index d773735..9f6ce7c91 100644
--- a/chromeos/services/secure_channel/public/cpp/client/fake_client_channel.cc
+++ b/chromeos/services/secure_channel/public/cpp/client/fake_client_channel.cc
@@ -14,16 +14,9 @@
 
 FakeClientChannel::~FakeClientChannel() = default;
 
-void FakeClientChannel::InvokePendingGetConnectionMetadataCallback(
-    mojom::ConnectionMetadataPtr connection_metadata) {
-  std::move(get_connection_metadata_callback_queue_.front())
-      .Run(std::move(connection_metadata));
-  get_connection_metadata_callback_queue_.pop();
-}
-
 void FakeClientChannel::PerformGetConnectionMetadata(
     base::OnceCallback<void(mojom::ConnectionMetadataPtr)> callback) {
-  get_connection_metadata_callback_queue_.push(std::move(callback));
+  std::move(callback).Run(std::move(connection_metadata_for_next_call_));
 }
 
 void FakeClientChannel::PerformSendMessage(const std::string& payload,
diff --git a/chromeos/services/secure_channel/public/cpp/client/fake_client_channel.h b/chromeos/services/secure_channel/public/cpp/client/fake_client_channel.h
index a149976..cf564ca 100644
--- a/chromeos/services/secure_channel/public/cpp/client/fake_client_channel.h
+++ b/chromeos/services/secure_channel/public/cpp/client/fake_client_channel.h
@@ -5,8 +5,6 @@
 #ifndef CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_FAKE_CLIENT_CHANNEL_H_
 #define CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_FAKE_CLIENT_CHANNEL_H_
 
-#include <queue>
-
 #include "base/macros.h"
 #include "chromeos/services/secure_channel/public/cpp/client/client_channel.h"
 #include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h"
@@ -24,8 +22,11 @@
   using ClientChannel::NotifyDisconnected;
   using ClientChannel::NotifyMessageReceived;
 
-  void InvokePendingGetConnectionMetadataCallback(
-      mojom::ConnectionMetadataPtr connection_metadata);
+  void set_connection_metadata_for_next_call(
+      mojom::ConnectionMetadataPtr connection_metadata_for_next_call) {
+    connection_metadata_for_next_call_ =
+        std::move(connection_metadata_for_next_call);
+  }
 
   std::vector<std::pair<std::string, base::OnceClosure>>& sent_messages() {
     return sent_messages_;
@@ -40,10 +41,7 @@
   void PerformSendMessage(const std::string& payload,
                           base::OnceClosure on_sent_callback) override;
 
-  // Queues up callbacks passed into PerformGetConnectionMetadata(), to be
-  // invoked later.
-  std::queue<base::OnceCallback<void(mojom::ConnectionMetadataPtr)>>
-      get_connection_metadata_callback_queue_;
+  mojom::ConnectionMetadataPtr connection_metadata_for_next_call_;
   std::vector<std::pair<std::string, base::OnceClosure>> sent_messages_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeClientChannel);
diff --git a/components/autofill/content/common/autofill_agent.mojom b/components/autofill/content/common/autofill_agent.mojom
index 66a2f59..93aea42 100644
--- a/components/autofill/content/common/autofill_agent.mojom
+++ b/components/autofill/content/common/autofill_agent.mojom
@@ -84,6 +84,9 @@
   // ShowPasswordSuggestions messages to the browser.
   FillPasswordForm(int32 key, PasswordFormFillData form_data);
 
+  // Fills the given |credential| into the last focused text input.
+  FillIntoFocusedField(bool is_password, mojo_base.mojom.String16 credential);
+
   // Notification to start (|active| == true) or stop (|active| == false)
   // logging the decisions made about saving the password.
   SetLoggingState(bool active);
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
index 554207cf..b33b643 100644
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -238,6 +238,7 @@
   }
 
   HidePopup();
+  last_input_element_.Reset();
 
   if (node.IsNull() || !node.IsElementNode()) {
     if (!last_interacted_form_.IsNull()) {
@@ -264,6 +265,7 @@
     return;
 
   element_ = *element;
+  last_input_element_ = *element;
 
   FormData form;
   FormFieldData field;
@@ -814,10 +816,15 @@
   last_clicked_form_control_element_was_focused_for_testing_ = was_focused;
   was_last_action_fill_ = false;
 
+  last_input_element_.Reset();
   const WebInputElement* input_element = ToWebInputElement(&element);
   if (!input_element && !form_util::IsTextAreaElement(element))
     return;
 
+  if (input_element) {
+    last_input_element_ = *input_element;
+  }
+
   ShowSuggestionsOptions options;
   options.autofill_on_empty_values = true;
   // Show full suggestions when clicking on an already-focused form field.
@@ -987,6 +994,7 @@
   last_clicked_form_control_element_for_testing_.Reset();
   formless_elements_user_edited_.clear();
   provisionally_saved_form_.reset();
+  last_input_element_.Reset();
 }
 
 void AutofillAgent::UpdateLastInteractedForm(blink::WebFormElement form) {
diff --git a/components/autofill/content/renderer/autofill_agent.h b/components/autofill/content/renderer/autofill_agent.h
index 1567c18..678054e5 100644
--- a/components/autofill/content/renderer/autofill_agent.h
+++ b/components/autofill/content/renderer/autofill_agent.h
@@ -95,6 +95,11 @@
     return weak_ptr_factory_.GetWeakPtr();
   }
 
+  // Returns the input element that was last focused.
+  blink::WebInputElement GetLastFocusedInput() const {
+    return last_input_element_;
+  }
+
   // FormTracker::Observer
   void OnProvisionallySaveForm(const blink::WebFormElement& form,
                                const blink::WebFormControlElement& element,
@@ -286,6 +291,9 @@
   // Last form which was interacted with by the user.
   blink::WebFormElement last_interacted_form_;
 
+  // Last input element the user interacted with.
+  blink::WebInputElement last_input_element_;
+
   // When dealing with forms that don't use a <form> tag, we keep track of the
   // elements the user has modified so we can determine when submission occurs.
   std::set<blink::WebFormControlElement> formless_elements_user_edited_;
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
index 785f7ed..f0b3f67 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -796,20 +796,10 @@
   if (IsUsernameAmendable(username_element,
                           element->IsPasswordFieldForAutofill()) &&
       username_element.Value().Utf16() != username) {
-    username_element.SetAutofillValue(blink::WebString::FromUTF16(username));
-    username_element.SetAutofillState(WebAutofillState::kAutofilled);
-    UpdateFieldValueAndPropertiesMaskMap(username_element, &username,
-                                         FieldPropertiesFlags::AUTOFILLED,
-                                         &field_value_and_properties_map_);
+    FillField(&username_element, username);
   }
 
-  password_element.SetAutofillValue(blink::WebString::FromUTF16(password));
-  password_element.SetAutofillState(WebAutofillState::kAutofilled);
-  UpdateFieldValueAndPropertiesMaskMap(password_element, &password,
-                                       FieldPropertiesFlags::AUTOFILLED,
-                                       &field_value_and_properties_map_);
-  ProvisionallySavePassword(password_element.Form(), password_element,
-                            RESTRICTION_NONE);
+  FillPasswordFieldAndSave(&password_element, password);
 
   blink::WebInputElement mutable_filled_element = *element;
   mutable_filled_element.SetSelectionRange(element->Value().length(),
@@ -818,6 +808,47 @@
   return true;
 }
 
+void PasswordAutofillAgent::FillIntoFocusedField(
+    bool is_password,
+    const base::string16& credential) {
+  if (!autofill_agent_.get()) {
+    return;
+  }
+  blink::WebInputElement input = autofill_agent_.get()->GetLastFocusedInput();
+  if (input.IsNull() || (!input.IsTextField() || !IsElementEditable(input))) {
+    return;
+  }
+  if (is_password) {
+    if (!input.IsPasswordFieldForAutofill()) {
+      return;
+    }
+    FillPasswordFieldAndSave(&input, credential);
+  } else {
+    FillField(&input, credential);
+  }
+}
+
+void PasswordAutofillAgent::FillField(blink::WebInputElement* input,
+                                      const base::string16& credential) {
+  DCHECK(input);
+  DCHECK(!input->IsNull());
+  input->SetAutofillValue(blink::WebString::FromUTF16(credential));
+  input->SetAutofillState(WebAutofillState::kAutofilled);
+  UpdateFieldValueAndPropertiesMaskMap(*input, &credential,
+                                       FieldPropertiesFlags::AUTOFILLED,
+                                       &field_value_and_properties_map_);
+}
+
+void PasswordAutofillAgent::FillPasswordFieldAndSave(
+    blink::WebInputElement* password_input,
+    const base::string16& credential) {
+  DCHECK(password_input);
+  DCHECK(password_input->IsPasswordFieldForAutofill());
+  FillField(password_input, credential);
+  ProvisionallySavePassword(password_input->Form(), *password_input,
+                            RESTRICTION_NONE);
+}
+
 bool PasswordAutofillAgent::PreviewSuggestion(
     const blink::WebFormControlElement& control_element,
     const blink::WebString& username,
@@ -1924,28 +1955,32 @@
   const bool is_password_present =
       password_renderer_id != FormFieldData::kNotSetFormControlRendererId;
 
-  DCHECK(is_password_present);
-
-  std::vector<uint32_t> element_ids = {password_renderer_id};
+  std::vector<uint32_t> element_ids;
+  if (is_password_present)
+    element_ids.push_back(password_renderer_id);
   if (is_username_present)
     element_ids.push_back(username_renderer_id);
 
   WebDocument doc = render_frame()->GetWebFrame()->GetDocument();
-  bool is_form_tag =
+  bool wrapped_in_form_tag =
       form_data.form_renderer_id != FormData::kNotSetFormRendererId;
   std::vector<WebFormControlElement> elements =
-      is_form_tag ? form_util::FindFormControlElementsByUniqueRendererId(
-                        doc, form_data.form_renderer_id, element_ids)
-                  : form_util::FindFormControlElementsByUniqueRendererId(
-                        doc, element_ids);
+      wrapped_in_form_tag
+          ? form_util::FindFormControlElementsByUniqueRendererId(
+                doc, form_data.form_renderer_id, element_ids)
+          : form_util::FindFormControlElementsByUniqueRendererId(doc,
+                                                                 element_ids);
 
   // Set password element.
-  WebInputElement password_field = ConvertToWebInput(elements[0]);
+  WebInputElement password_field;
+  size_t current_index = 0;
+  if (is_password_present)
+    password_field = ConvertToWebInput(elements[current_index++]);
 
   // Set username element.
   WebInputElement username_field;
   if (is_username_present)
-    username_field = ConvertToWebInput(elements[1]);
+    username_field = ConvertToWebInput(elements[current_index++]);
 
   return std::make_pair(username_field, password_field);
 }
diff --git a/components/autofill/content/renderer/password_autofill_agent.h b/components/autofill/content/renderer/password_autofill_agent.h
index a466f546..09f666e 100644
--- a/components/autofill/content/renderer/password_autofill_agent.h
+++ b/components/autofill/content/renderer/password_autofill_agent.h
@@ -66,6 +66,8 @@
   // mojom::PasswordAutofillAgent:
   void FillPasswordForm(int key,
                         const PasswordFormFillData& form_data) override;
+  void FillIntoFocusedField(bool is_password,
+                            const base::string16& credential) override;
   void SetLoggingState(bool active) override;
   void AutofillUsernameAndPasswordDataReceived(
       const FormsPredictionsMap& predictions) override;
@@ -267,6 +269,16 @@
   void ClearPreview(blink::WebInputElement* username,
                     blink::WebInputElement* password);
 
+  // Checks that a given input field is valid before filling the given |input|
+  // with the given |credential| and marking the field as auto-filled.
+  void FillField(blink::WebInputElement* input,
+                 const base::string16& credential);
+
+  // Uses |FillField| to fill the given |credential| into the |password_input|.
+  // Saves the password for its associated form.
+  void FillPasswordFieldAndSave(blink::WebInputElement* password_input,
+                                const base::string16& credential);
+
   // Saves |form| and |input| in |provisionally_saved_form_|, as long as it
   // satisfies |restriction|. |form| and |input| are the elements user has just
   // been interacting with before the form save. |form| or |input| can be null
diff --git a/components/autofill/content/renderer/password_form_conversion_utils.cc b/components/autofill/content/renderer/password_form_conversion_utils.cc
index d2809dd..ba246c3 100644
--- a/components/autofill/content/renderer/password_form_conversion_utils.cc
+++ b/components/autofill/content/renderer/password_form_conversion_utils.cc
@@ -470,11 +470,11 @@
         control_elements, form_data, username_detector_cache);
   }
 
-  // Narrow the scope to enabled inputs.
+  // Narrow the scope to enabled text inputs.
   std::vector<const FormFieldData*> enabled_fields;
   enabled_fields.reserve(form_data.fields.size());
   for (const FormFieldData& field : form_data.fields) {
-    if (field.is_enabled)
+    if (field.is_enabled && field.IsTextInputElement())
       enabled_fields.push_back(&field);
   }
 
diff --git a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
index ddb0edbd..732fb63e 100644
--- a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
+++ b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
@@ -155,6 +155,12 @@
         name_and_id, name_and_id, value);
   }
 
+  // Add a field with a given type. Useful to add non-text fields.
+  void AddFieldWithType(const char* name_and_id, const char* type) {
+    base::StringAppendF(&html_, "<INPUT type=\"%s\" name=\"%s\" id=\"%s\"/>",
+                        type, name_and_id, name_and_id);
+  }
+
   // Appends a new submit-type field at the end of the form with the specified
   // |name|.
   void AddSubmitButton(const char* name) {
@@ -2514,4 +2520,24 @@
   EXPECT_EQ(base::string16(), password_form->form_data.fields[2].typed_value);
 }
 
+// Check that non-text fields are ignored.
+TEST_F(MAYBE_PasswordFormConversionUtilsTest, NonTextFields) {
+  PasswordFormBuilder builder(kTestFormActionURL);
+  // Avoid calling the text fields anything related to "username" to prevent the
+  // local HTML classifier from influencing the test result.
+  builder.AddTextField("textField", "", "");
+  builder.AddFieldWithType("radioInput", "radio");
+  builder.AddPasswordField("password", "", "");
+  std::string html = builder.ProduceHTML();
+
+  WebFormElement form;
+  LoadWebFormFromHTML(html, &form, nullptr);
+
+  std::unique_ptr<PasswordForm> password_form =
+      CreatePasswordFormFromWebForm(form, nullptr, nullptr, nullptr);
+
+  ASSERT_TRUE(password_form);
+  EXPECT_EQ(base::UTF8ToUTF16("textField"), password_form->username_element);
+}
+
 }  // namespace autofill
diff --git a/components/autofill/content/renderer/password_generation_agent.cc b/components/autofill/content/renderer/password_generation_agent.cc
index dc80c11..d74eee9 100644
--- a/components/autofill/content/renderer/password_generation_agent.cc
+++ b/components/autofill/content/renderer/password_generation_agent.cc
@@ -672,7 +672,7 @@
   GetPasswordManagerClient()->ShowPasswordEditingPopup(
       render_frame()->GetRenderView()->ElementBoundsInWindow(
           generation_element_),
-      *generation_form_data_->form);
+      *CreatePasswordFormToPresave());
   editing_popup_shown_ = true;
 }
 
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 872c35b..b889f70 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -501,8 +501,8 @@
   UpdatePendingForm(form);
 
   if (!user_did_type_ || autofill_field->is_autofilled)
-    form_interactions_ukm_logger_->LogTextFieldDidChange(
-        *autofill_field, form_structure->form_parsed_timestamp());
+    form_interactions_ukm_logger_->LogTextFieldDidChange(*form_structure,
+                                                         *autofill_field);
 
   if (!user_did_type_) {
     user_did_type_ = true;
diff --git a/components/autofill/core/browser/autofill_metrics.cc b/components/autofill/core/browser/autofill_metrics.cc
index 6923a50..253c3446 100644
--- a/components/autofill/core/browser/autofill_metrics.cc
+++ b/components/autofill/core/browser/autofill_metrics.cc
@@ -1796,12 +1796,14 @@
 }
 
 void AutofillMetrics::FormInteractionsUkmLogger::LogTextFieldDidChange(
-    const AutofillField& field,
-    const base::TimeTicks& form_parsed_timestamp) {
+    const FormStructure& form,
+    const AutofillField& field) {
   if (!CanLog())
     return;
 
   ukm::builders::Autofill_TextFieldDidChange(source_id_)
+      .SetFormSignature(HashFormSignature(form.form_signature()))
+      .SetFieldSignature(HashFieldSignature(field.GetFieldSignature()))
       .SetFieldTypeGroup(static_cast<int>(field.Type().group()))
       .SetHeuristicType(static_cast<int>(field.heuristic_type()))
       .SetServerType(static_cast<int>(field.server_type()))
@@ -1810,7 +1812,7 @@
       .SetIsAutofilled(field.is_autofilled)
       .SetIsEmpty(field.IsEmpty())
       .SetMillisecondsSinceFormParsed(
-          MillisecondsSinceFormParsed(form_parsed_timestamp))
+          MillisecondsSinceFormParsed(form.form_parsed_timestamp()))
       .Record(ukm_recorder_);
 }
 
diff --git a/components/autofill/core/browser/autofill_metrics.h b/components/autofill/core/browser/autofill_metrics.h
index 4a9ac36..55a4145 100644
--- a/components/autofill/core/browser/autofill_metrics.h
+++ b/components/autofill/core/browser/autofill_metrics.h
@@ -692,8 +692,8 @@
     void LogDidFillSuggestion(int record_type,
                               const FormStructure& form,
                               const AutofillField& field);
-    void LogTextFieldDidChange(const AutofillField& field,
-                               const base::TimeTicks& form_parsed_timestamp);
+    void LogTextFieldDidChange(const FormStructure& form,
+                               const AutofillField& field);
     void LogFieldFillStatus(const FormStructure& form,
                             const AutofillField& field,
                             QualityMetricType metric_type);
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc
index 2f234d8..f83a0f0e 100644
--- a/components/autofill/core/browser/autofill_metrics_unittest.cc
+++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -6307,7 +6307,11 @@
         {UkmTextFieldDidChangeType::kHtmlFieldModeName, HTML_MODE_NONE},
         {UkmTextFieldDidChangeType::kIsAutofilledName, false},
         {UkmTextFieldDidChangeType::kIsEmptyName, true},
-        {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+        {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+        {UkmTextFieldDidChangeType::kFieldSignatureName,
+         Collapse(CalculateFieldSignatureForField(form.fields[0]))},
+        {UkmTextFieldDidChangeType::kFormSignatureName,
+         Collapse(CalculateFormSignature(form))}},
        {{UkmTextFieldDidChangeType::kFieldTypeGroupName, NAME},
         {UkmTextFieldDidChangeType::kHeuristicTypeName, NAME_FULL},
         {UkmTextFieldDidChangeType::kServerTypeName, NO_SERVER_DATA},
@@ -6315,7 +6319,11 @@
         {UkmTextFieldDidChangeType::kHtmlFieldModeName, HTML_MODE_NONE},
         {UkmTextFieldDidChangeType::kIsAutofilledName, true},
         {UkmTextFieldDidChangeType::kIsEmptyName, true},
-        {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+        {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+        {UkmTextFieldDidChangeType::kFieldSignatureName,
+         Collapse(CalculateFieldSignatureForField(form.fields[0]))},
+        {UkmTextFieldDidChangeType::kFormSignatureName,
+         Collapse(CalculateFormSignature(form))}},
        {{UkmTextFieldDidChangeType::kFieldTypeGroupName, EMAIL},
         {UkmTextFieldDidChangeType::kHeuristicTypeName, EMAIL_ADDRESS},
         {UkmTextFieldDidChangeType::kServerTypeName, NO_SERVER_DATA},
@@ -6323,7 +6331,11 @@
         {UkmTextFieldDidChangeType::kHtmlFieldModeName, HTML_MODE_NONE},
         {UkmTextFieldDidChangeType::kIsAutofilledName, true},
         {UkmTextFieldDidChangeType::kIsEmptyName, true},
-        {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
+        {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+        {UkmTextFieldDidChangeType::kFieldSignatureName,
+         Collapse(CalculateFieldSignatureForField(form.fields[1]))},
+        {UkmTextFieldDidChangeType::kFormSignatureName,
+         Collapse(CalculateFormSignature(form))}}});
 }
 
 // Verify that we correctly log metrics tracking the duration of form fill.
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc
index 6f5401f..2ab12db 100644
--- a/components/browser_sync/profile_sync_service.cc
+++ b/components/browser_sync/profile_sync_service.cc
@@ -345,10 +345,9 @@
   // immediately.
   if (start_behavior_ == AUTO_START && IsSyncRequested() &&
       !IsFirstSetupComplete()) {
-    startup_controller_->TryStartImmediately();
-  } else {
-    startup_controller_->TryStart();
+    startup_controller_->SetBypassSetupCompleteAndDeferredStartup();
   }
+  startup_controller_->TryStart(/*force_immediate=*/false);
 }
 
 void ProfileSyncService::StartSyncingWithServer() {
@@ -434,7 +433,7 @@
     DCHECK(!engine_);
   } else {
     DCHECK(!engine_);
-    startup_controller_->TryStart();
+    startup_controller_->TryStart(IsSetupInProgress());
   }
 }
 
@@ -1024,7 +1023,7 @@
       break;
     case syncer::RESET_LOCAL_SYNC_DATA:
       ShutdownImpl(syncer::DISABLE_SYNC);
-      startup_controller_->TryStart();
+      startup_controller_->TryStart(IsSetupInProgress());
       UMA_HISTOGRAM_ENUMERATION(
           "Sync.ClearServerDataEvents",
           syncer::CLEAR_SERVER_DATA_RESET_LOCAL_DATA_RECEIVED,
@@ -1054,7 +1053,7 @@
   // Shutdown sync, delete the Directory, then restart, restoring the cached
   // nigori state.
   ShutdownImpl(syncer::DISABLE_SYNC);
-  startup_controller_->TryStart();
+  startup_controller_->TryStart(IsSetupInProgress());
   UMA_HISTOGRAM_ENUMERATION("Sync.ClearServerDataEvents",
                             syncer::CLEAR_SERVER_DATA_SUCCEEDED,
                             syncer::CLEAR_SERVER_DATA_MAX);
@@ -1207,7 +1206,7 @@
 
 bool ProfileSyncService::IsSetupInProgress() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return startup_controller_->IsSetupInProgress();
+  return outstanding_setup_in_progress_handles_ > 0;
 }
 
 bool ProfileSyncService::QueryDetailedSyncStatus(
@@ -1234,7 +1233,7 @@
 
 bool ProfileSyncService::IsFirstSetupInProgress() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return !IsFirstSetupComplete() && startup_controller_->IsSetupInProgress();
+  return !IsFirstSetupComplete() && IsSetupInProgress();
 }
 
 std::unique_ptr<syncer::SyncSetupInProgressHandle>
@@ -1242,8 +1241,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (++outstanding_setup_in_progress_handles_ == 1) {
-    DCHECK(!startup_controller_->IsSetupInProgress());
-    startup_controller_->SetSetupInProgress(true);
+    startup_controller_->TryStart(/*force_immediate=*/true);
 
     NotifyObservers();
   }
@@ -1716,7 +1714,7 @@
     StopImpl(CLEAR_DATA);
   } else {
     // Sync is no longer disabled by policy. Try starting it up if appropriate.
-    startup_controller_->TryStart();
+    startup_controller_->TryStart(IsSetupInProgress());
   }
 }
 
@@ -1968,7 +1966,8 @@
     sync_prefs_.SetSyncRequested(true);
     NotifyObservers();
   }
-  startup_controller_->TryStartImmediately();
+  startup_controller_->SetBypassSetupCompleteAndDeferredStartup();
+  startup_controller_->TryStart(IsSetupInProgress());
 }
 
 void ProfileSyncService::ReconfigureDatatypeManager() {
@@ -2184,9 +2183,6 @@
   if (--outstanding_setup_in_progress_handles_ != 0)
     return;
 
-  DCHECK(startup_controller_->IsSetupInProgress());
-  startup_controller_->SetSetupInProgress(false);
-
   if (IsEngineInitialized())
     ReconfigureDatatypeManager();
   NotifyObservers();
diff --git a/components/content_settings/core/browser/website_settings_registry.cc b/components/content_settings/core/browser/website_settings_registry.cc
index cafc147..67e410a 100644
--- a/components/content_settings/core/browser/website_settings_registry.cc
+++ b/components/content_settings/core/browser/website_settings_registry.cc
@@ -10,6 +10,7 @@
 #include "base/memory/ptr_util.h"
 #include "build/build_config.h"
 #include "components/content_settings/core/common/content_settings.h"
+#include "components/content_settings/core/common/features.h"
 
 namespace {
 
@@ -181,10 +182,17 @@
            WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE,
            DESKTOP | PLATFORM_ANDROID,
            WebsiteSettingsInfo::DONT_INHERIT_IN_INCOGNITO);
-  Register(CONTENT_SETTINGS_TYPE_PLUGINS_DATA, "flash-data", nullptr,
-           WebsiteSettingsInfo::UNSYNCABLE, WebsiteSettingsInfo::NOT_LOSSY,
-           WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE, DESKTOP,
-           WebsiteSettingsInfo::INHERIT_IN_INCOGNITO);
+  Register(
+      CONTENT_SETTINGS_TYPE_PLUGINS_DATA, "flash-data", nullptr,
+      // To counteract the reduced usability of the Flash permission
+      // when it becomes ephemeral, we sync the bit indicating that
+      // the Flash permission should be displayed in the page info.
+      base::FeatureList::IsEnabled(features::kEnableEphemeralFlashPermission)
+          ? WebsiteSettingsInfo::SYNCABLE
+          : WebsiteSettingsInfo::UNSYNCABLE,
+      WebsiteSettingsInfo::NOT_LOSSY,
+      WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE, DESKTOP,
+      WebsiteSettingsInfo::INHERIT_IN_INCOGNITO);
 }
 
 }  // namespace content_settings
diff --git a/components/content_settings/core/common/BUILD.gn b/components/content_settings/core/common/BUILD.gn
index 947dbdaf..b706236 100644
--- a/components/content_settings/core/common/BUILD.gn
+++ b/components/content_settings/core/common/BUILD.gn
@@ -17,6 +17,8 @@
     "content_settings_utils.h",
     "cookie_settings_base.cc",
     "cookie_settings_base.h",
+    "features.cc",
+    "features.h",
     "pref_names.cc",
     "pref_names.h",
   ]
diff --git a/components/content_settings/core/common/features.cc b/components/content_settings/core/common/features.cc
new file mode 100644
index 0000000..1bf1adac
--- /dev/null
+++ b/components/content_settings/core/common/features.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.
+
+// This file defines all the public base::FeatureList features for the chrome
+// module.
+
+#include "components/content_settings/core/common/features.h"
+
+namespace content_settings {
+namespace features {
+
+// Makes Flash plugin permissions persistent only through the current session.
+const base::Feature kEnableEphemeralFlashPermission{
+    "EnableEphemeralFlashPermission", base::FEATURE_DISABLED_BY_DEFAULT};
+
+}  // namespace features
+}  // namespace content_settings
diff --git a/components/content_settings/core/common/features.h b/components/content_settings/core/common/features.h
new file mode 100644
index 0000000..ac2bafd2
--- /dev/null
+++ b/components/content_settings/core/common/features.h
@@ -0,0 +1,21 @@
+// 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.
+
+// This file defines all the public base::FeatureList features for the chrome
+// module.
+
+#ifndef COMPONENTS_CONTENT_SETTINGS_CORE_COMMON_FEATURES_H_
+#define COMPONENTS_CONTENT_SETTINGS_CORE_COMMON_FEATURES_H_
+
+#include "base/feature_list.h"
+
+namespace content_settings {
+namespace features {
+
+extern const base::Feature kEnableEphemeralFlashPermission;
+
+}  // namespace features
+}  // namespace content_settings
+
+#endif  // COMPONENTS_CONTENT_SETTINGS_CORE_COMMON_FEATURES_H_
diff --git a/components/gcm_driver/gcm_account_tracker.cc b/components/gcm_driver/gcm_account_tracker.cc
index ca9bb46..770ab91 100644
--- a/components/gcm_driver/gcm_account_tracker.cc
+++ b/components/gcm_driver/gcm_account_tracker.cc
@@ -122,18 +122,14 @@
   AccountInfos::iterator iter = account_infos_.find(request->GetAccountId());
   DCHECK(iter != account_infos_.end());
   if (iter != account_infos_.end()) {
-    DCHECK(iter->second.state == GETTING_TOKEN ||
-           iter->second.state == ACCOUNT_REMOVED);
-    // If OnAccountSignedOut(..) was called most recently, account is kept in
-    // ACCOUNT_REMOVED state.
-    if (iter->second.state == GETTING_TOKEN) {
-      iter->second.state = TOKEN_PRESENT;
-      iter->second.access_token = access_token;
-      iter->second.expiration_time = expiration_time;
-    }
+    DCHECK_EQ(GETTING_TOKEN, iter->second.state);
+
+    iter->second.state = TOKEN_PRESENT;
+    iter->second.access_token = access_token;
+    iter->second.expiration_time = expiration_time;
   }
 
-  DeleteTokenRequest(request);
+  pending_token_requests_.erase(request->GetAccountId());
   ReportTokens();
 }
 
@@ -147,20 +143,16 @@
   AccountInfos::iterator iter = account_infos_.find(request->GetAccountId());
   DCHECK(iter != account_infos_.end());
   if (iter != account_infos_.end()) {
-    DCHECK(iter->second.state == GETTING_TOKEN ||
-           iter->second.state == ACCOUNT_REMOVED);
-    // If OnAccountSignedOut(..) was called most recently, account is kept in
-    // ACCOUNT_REMOVED state.
-    if (iter->second.state == GETTING_TOKEN) {
-      // Given the fetcher has a built in retry logic, consider this situation
-      // to be invalid refresh token, that is only fixed when user signs in.
-      // Once the users signs in properly the minting will retry.
-      iter->second.access_token.clear();
-      iter->second.state = ACCOUNT_REMOVED;
-    }
+    DCHECK_EQ(GETTING_TOKEN, iter->second.state);
+
+    // Given the fetcher has a built in retry logic, consider this situation
+    // to be invalid refresh token, that is only fixed when user signs in.
+    // Once the users signs in properly the minting will retry.
+    iter->second.access_token.clear();
+    iter->second.state = ACCOUNT_REMOVED;
   }
 
-  DeleteTokenRequest(request);
+  pending_token_requests_.erase(request->GetAccountId());
   ReportTokens();
 }
 
@@ -297,17 +289,6 @@
   return time_till_next_reporting;
 }
 
-void GCMAccountTracker::DeleteTokenRequest(
-    const OAuth2TokenService::Request* request) {
-  auto iter = std::find_if(
-      pending_token_requests_.begin(), pending_token_requests_.end(),
-      [request](const std::unique_ptr<OAuth2TokenService::Request>& r) {
-        return request == r.get();
-      });
-  if (iter != pending_token_requests_.end())
-    pending_token_requests_.erase(iter);
-}
-
 void GCMAccountTracker::GetAllNeededTokens() {
   // Only start fetching tokens if driver is running, they have a limited
   // validity time and GCM connection is a good indication of network running.
@@ -334,7 +315,8 @@
   std::unique_ptr<OAuth2TokenService::Request> request =
       token_service_->StartRequest(account_iter->first, scopes, this);
 
-  pending_token_requests_.push_back(std::move(request));
+  DCHECK(pending_token_requests_.count(account_iter->first) == 0);
+  pending_token_requests_.emplace(account_iter->first, std::move(request));
   account_iter->second.state = GETTING_TOKEN;
 }
 
@@ -360,6 +342,12 @@
 
   iter->second.access_token.clear();
   iter->second.state = ACCOUNT_REMOVED;
+
+  // Delete any ongoing access token request now so that if the account is later
+  // re-added and a new access token request made, we do not break this class'
+  // invariant that there is at most one ongoing access token request per
+  // account.
+  pending_token_requests_.erase(ids.account_key);
   ReportTokens();
 }
 
diff --git a/components/gcm_driver/gcm_account_tracker.h b/components/gcm_driver/gcm_account_tracker.h
index 1e78da7..f95f5c6 100644
--- a/components/gcm_driver/gcm_account_tracker.h
+++ b/components/gcm_driver/gcm_account_tracker.h
@@ -129,9 +129,6 @@
   bool IsTokenFetchingRequired() const;
   // Gets the time until next token reporting.
   base::TimeDelta GetTimeToNextTokenReporting() const;
-  // Deletes a token request. Should be called from OnGetTokenSuccess(..) or
-  // OnGetTokenFailure(..).
-  void DeleteTokenRequest(const OAuth2TokenService::Request* request);
   // Checks on all known accounts, and calls GetToken(..) for those with
   // |state == TOKEN_NEEDED|.
   void GetAllNeededTokens();
@@ -157,8 +154,12 @@
   // Indicates whether shutdown has been called.
   bool shutdown_called_;
 
-  std::vector<std::unique_ptr<OAuth2TokenService::Request>>
-      pending_token_requests_;
+  // Stores the ongoing access token requests for deletion either upon
+  // completion or upon signout of the account for which the request is being
+  // made.
+  using AccountIDToTokenRequestMap =
+      std::map<std::string, std::unique_ptr<OAuth2TokenService::Request>>;
+  AccountIDToTokenRequestMap pending_token_requests_;
 
   // Creates weak pointers used to postpone reporting tokens. See
   // ScheduleReportTokens.
diff --git a/components/password_manager/content/browser/content_password_manager_driver.cc b/components/password_manager/content/browser/content_password_manager_driver.cc
index fdc0536..e5f6b28 100644
--- a/components/password_manager/content/browser/content_password_manager_driver.cc
+++ b/components/password_manager/content/browser/content_password_manager_driver.cc
@@ -113,6 +113,12 @@
   GetAutofillAgent()->FillPasswordSuggestion(username, password);
 }
 
+void ContentPasswordManagerDriver::FillIntoFocusedField(
+    bool is_password,
+    const base::string16& credential) {
+  GetPasswordAutofillAgent()->FillIntoFocusedField(is_password, credential);
+}
+
 void ContentPasswordManagerDriver::PreviewSuggestion(
     const base::string16& username,
     const base::string16& password) {
diff --git a/components/password_manager/content/browser/content_password_manager_driver.h b/components/password_manager/content/browser/content_password_manager_driver.h
index 5ad32e3..ff1071b 100644
--- a/components/password_manager/content/browser/content_password_manager_driver.h
+++ b/components/password_manager/content/browser/content_password_manager_driver.h
@@ -66,6 +66,8 @@
   void UserSelectedManualGenerationOption() override;
   void FillSuggestion(const base::string16& username,
                       const base::string16& password) override;
+  void FillIntoFocusedField(bool is_password,
+                            const base::string16& credential) override;
   void PreviewSuggestion(const base::string16& username,
                          const base::string16& password) override;
   void ShowInitialPasswordAccountSuggestions(
diff --git a/components/password_manager/content/browser/content_password_manager_driver_unittest.cc b/components/password_manager/content/browser/content_password_manager_driver_unittest.cc
index 7a8ba9f..af5e3f1f 100644
--- a/components/password_manager/content/browser/content_password_manager_driver_unittest.cc
+++ b/components/password_manager/content/browser/content_password_manager_driver_unittest.cc
@@ -80,6 +80,7 @@
   // autofill::mojom::PasswordAutofillAgent:
   MOCK_METHOD2(FillPasswordForm,
                void(int, const autofill::PasswordFormFillData&));
+  MOCK_METHOD2(FillIntoFocusedField, void(bool, const base::string16&));
 
   MOCK_METHOD0(BlacklistedFormFound, void());
 
diff --git a/components/password_manager/core/browser/new_password_form_manager.cc b/components/password_manager/core/browser/new_password_form_manager.cc
index a386f22..fe2be9a7 100644
--- a/components/password_manager/core/browser/new_password_form_manager.cc
+++ b/components/password_manager/core/browser/new_password_form_manager.cc
@@ -226,11 +226,6 @@
   if (!driver_ || best_matches_.empty() || filled_)
     return;
 
-  // Do not fill forms without password field.
-  if (observed_password_form->password_element_renderer_id ==
-      FormFieldData::kNotSetFormControlRendererId)
-    return;
-
   // TODO(https://crbug.com/831123). Implement correct treating of federated
   // matches.
   std::vector<const autofill::PasswordForm*> federated_matches;
diff --git a/components/password_manager/core/browser/new_password_form_manager_unittest.cc b/components/password_manager/core/browser/new_password_form_manager_unittest.cc
index 37602041..1f91d2e1 100644
--- a/components/password_manager/core/browser/new_password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/new_password_form_manager_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/test/test_mock_time_task_runner.h"
 #include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/common/form_data.h"
+#include "components/autofill/core/common/form_field_data.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/autofill/core/common/password_form_fill_data.h"
 #include "components/password_manager/core/browser/fake_form_fetcher.h"
@@ -137,19 +138,29 @@
   EXPECT_EQ(saved_match_.password_value, fill_data.password_field.value);
 }
 
-TEST_F(NewPasswordFormManagerTest, NoAutofillSignUpForm) {
+// NewPasswordFormManager should always send fill data to renderer, even for
+// sign-up forms (no "current-password" field, i.e., no password field to fill
+// into). However, for sign-up forms, no particular password field should be
+// identified for filling. That way, Chrome won't disturb the user by filling
+// the sign-up form, but will be able to offer a manual fallback for filling if
+// the form was misclassified.
+TEST_F(NewPasswordFormManagerTest, AutofillSignUpForm) {
   TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
   FakeFormFetcher fetcher;
   fetcher.Fetch();
   // Make |observed_form_| to be sign-up form.
   observed_form_.fields.back().autocomplete_attribute = "new-password";
 
-  EXPECT_CALL(driver_, FillPasswordForm(_)).Times(0);
+  PasswordFormFillData fill_data;
+  EXPECT_CALL(driver_, FillPasswordForm(_)).WillOnce(SaveArg<0>(&fill_data));
   NewPasswordFormManager form_manager(&client_, driver_.AsWeakPtr(),
                                       observed_form_, &fetcher);
   fetcher.SetNonFederated({&saved_match_}, 0u);
 
   task_runner_->FastForwardUntilNoTasksRemain();
+  constexpr uint32_t kNoID = FormFieldData::kNotSetFormControlRendererId;
+  EXPECT_EQ(kNoID, fill_data.password_field.unique_renderer_id);
+  EXPECT_EQ(saved_match_.password_value, fill_data.password_field.value);
 }
 
 TEST_F(NewPasswordFormManagerTest, SetSubmitted) {
diff --git a/components/password_manager/core/browser/password_manager_driver.h b/components/password_manager/core/browser/password_manager_driver.h
index 3803165..cf12a4b5a 100644
--- a/components/password_manager/core/browser/password_manager_driver.h
+++ b/components/password_manager/core/browser/password_manager_driver.h
@@ -69,6 +69,11 @@
   virtual void FillSuggestion(const base::string16& username,
                               const base::string16& password) = 0;
 
+  // Tells the renderer to fill the given credential into the focused element.
+  virtual void FillIntoFocusedField(
+      bool is_password,
+      const base::string16& user_provided_credential) {}
+
   // Tells the driver to preview filling form with the |username| and
   // |password|.
   virtual void PreviewSuggestion(const base::string16& username,
diff --git a/components/policy/core/common/BUILD.gn b/components/policy/core/common/BUILD.gn
index 7fbc0f12..d36c8c4 100644
--- a/components/policy/core/common/BUILD.gn
+++ b/components/policy/core/common/BUILD.gn
@@ -69,8 +69,6 @@
     "cloud/machine_level_user_cloud_policy_metrics.h",
     "cloud/machine_level_user_cloud_policy_store.cc",
     "cloud/machine_level_user_cloud_policy_store.h",
-    "cloud/policy_header_io_helper.cc",
-    "cloud/policy_header_io_helper.h",
     "cloud/policy_header_service.cc",
     "cloud/policy_header_service.h",
     "cloud/resource_cache.cc",
@@ -307,7 +305,6 @@
     "cloud/cloud_policy_service_unittest.cc",
     "cloud/cloud_policy_validator_unittest.cc",
     "cloud/device_management_service_unittest.cc",
-    "cloud/policy_header_io_helper_unittest.cc",
     "cloud/policy_header_service_unittest.cc",
     "cloud/user_info_fetcher_unittest.cc",
     "generate_policy_source_unittest.cc",
diff --git a/components/policy/core/common/cloud/policy_header_io_helper.cc b/components/policy/core/common/cloud/policy_header_io_helper.cc
deleted file mode 100644
index 37e866c..0000000
--- a/components/policy/core/common/cloud/policy_header_io_helper.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/policy/core/common/cloud/policy_header_io_helper.h"
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/sequenced_task_runner.h"
-#include "components/policy/core/common/cloud/cloud_policy_constants.h"
-#include "net/url_request/url_request.h"
-
-namespace policy {
-
-PolicyHeaderIOHelper::PolicyHeaderIOHelper(
-    const std::string& server_url,
-    const std::string& initial_header_value,
-    const scoped_refptr<base::SequencedTaskRunner>& task_runner)
-    : server_url_(server_url),
-      io_task_runner_(task_runner),
-      policy_header_(initial_header_value) {
-}
-
-PolicyHeaderIOHelper::~PolicyHeaderIOHelper() {
-}
-
-// Sets any necessary policy headers on the passed request.
-void PolicyHeaderIOHelper::AddPolicyHeaders(const GURL& url,
-                                            net::URLRequest* request) const {
-  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
-  if (!policy_header_.empty() &&
-      url.spec().compare(0, server_url_.size(), server_url_) == 0) {
-    request->SetExtraRequestHeaderByName(kChromePolicyHeader,
-                                         policy_header_,
-                                         true /* overwrite */);
-  }
-}
-
-void PolicyHeaderIOHelper::UpdateHeader(const std::string& new_header) {
-  // Post a task to the IO thread to modify this.
-  io_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&PolicyHeaderIOHelper::UpdateHeaderOnIOThread,
-                 base::Unretained(this), new_header));
-}
-
-void PolicyHeaderIOHelper::UpdateHeaderOnIOThread(
-    const std::string& new_header) {
-  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
-  policy_header_ = new_header;
-}
-
-void PolicyHeaderIOHelper::SetServerURLForTest(const std::string& server_url) {
-  io_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&PolicyHeaderIOHelper::SetServerURLOnIOThread,
-                 base::Unretained(this), server_url));
-}
-
-void PolicyHeaderIOHelper::SetServerURLOnIOThread(
-    const std::string& server_url) {
-  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
-  server_url_ = server_url;
-}
-
-}  // namespace policy
diff --git a/components/policy/core/common/cloud/policy_header_io_helper.h b/components/policy/core/common/cloud/policy_header_io_helper.h
deleted file mode 100644
index 5dae51a..0000000
--- a/components/policy/core/common/cloud/policy_header_io_helper.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_POLICY_CORE_COMMON_CLOUD_POLICY_HEADER_IO_HELPER_H_
-#define COMPONENTS_POLICY_CORE_COMMON_CLOUD_POLICY_HEADER_IO_HELPER_H_
-
-#include <string>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/sequenced_task_runner.h"
-#include "components/policy/policy_export.h"
-#include "url/gurl.h"
-
-namespace net {
-class URLRequest;
-}
-
-namespace policy {
-
-// Helper class that lives on the I/O thread and adds policy headers to
-// outgoing requests. Instances of this class are created by
-// PolicyHeaderService on the UI thread, and that class is responsible for
-// notifying this class via UpdateHeaderFromUI() when the header changes.
-// Ownership is transferred to ProfileIOData, and this object is run and
-// destroyed on the I/O thread.
-class POLICY_EXPORT PolicyHeaderIOHelper {
- public:
-  PolicyHeaderIOHelper(
-      const std::string& server_url,
-      const std::string& initial_header_value,
-      const scoped_refptr<base::SequencedTaskRunner>& task_runner);
-  ~PolicyHeaderIOHelper();
-
-  // Sets any necessary policy headers for the specified URL on the passed
-  // request. Should be invoked only from the I/O thread.
-  void AddPolicyHeaders(const GURL& url,
-                        net::URLRequest* request) const;
-
-  // API invoked when the header changes. Can be called from any thread - calls
-  // are marshalled via the TaskRunner to run on the appropriate thread.
-  // If |new_header| is the empty string, no header will be added to
-  // outgoing requests.
-  void UpdateHeader(const std::string& new_header);
-
-  // Test-only routine used to inject the server URL at runtime - this is
-  // required because PolicyHeaderIOHelper is created very early in BrowserTest
-  // initialization, before we startup the EmbeddedTestServer.
-  void SetServerURLForTest(const std::string& server_url);
-
- private:
-  // API invoked via the TaskRunner to update the header.
-  void UpdateHeaderOnIOThread(const std::string& new_header);
-
-  // Helper routine invoked via the TaskRunner to update the cached server URL.
-  void SetServerURLOnIOThread(const std::string& new_header);
-
-  // The URL we should add policy headers to.
-  std::string server_url_;
-
-  // The task runner associated with the I/O thread that runs this object.
-  scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
-
-  // The current policy header value.
-  std::string policy_header_;
-
-  DISALLOW_COPY_AND_ASSIGN(PolicyHeaderIOHelper);
-};
-
-}  // namespace policy
-
-#endif  // COMPONENTS_POLICY_CORE_COMMON_CLOUD_POLICY_HEADER_IO_HELPER_H_
diff --git a/components/policy/core/common/cloud/policy_header_io_helper_unittest.cc b/components/policy/core/common/cloud/policy_header_io_helper_unittest.cc
deleted file mode 100644
index 8b1d297..0000000
--- a/components/policy/core/common/cloud/policy_header_io_helper_unittest.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/policy/core/common/cloud/policy_header_io_helper.h"
-
-#include <memory>
-
-#include "base/message_loop/message_loop.h"
-#include "base/test/test_simple_task_runner.h"
-#include "net/http/http_request_headers.h"
-#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace policy {
-
-namespace {
-const char kDMServerURL[] = "http://server_url";
-const char kPolicyHeaderName[] = "Chrome-Policy-Posture";
-const char kInitialPolicyHeader[] = "initial_header";
-
-class PolicyHeaderIOHelperTest : public testing::Test {
- public:
-  PolicyHeaderIOHelperTest() {
-    task_runner_ = base::MakeRefCounted<base::TestSimpleTaskRunner>();
-  }
-  ~PolicyHeaderIOHelperTest() override {}
-
-  void SetUp() override {
-    helper_ = std::make_unique<PolicyHeaderIOHelper>(
-        kDMServerURL, kInitialPolicyHeader, task_runner_);
-    task_runner_->RunUntilIdle();
-  }
-  void TearDown() override {
-    task_runner_->RunUntilIdle();
-    helper_.reset();
-  }
-
-  void ValidateHeader(const net::HttpRequestHeaders& headers,
-                      const std::string& expected) {
-    std::string header;
-    EXPECT_TRUE(headers.GetHeader(kPolicyHeaderName, &header));
-    EXPECT_EQ(header, expected);
-  }
-
-  base::MessageLoop loop_;
-  std::unique_ptr<PolicyHeaderIOHelper> helper_;
-  net::TestURLRequestContext context_;
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
-};
-
-}  // namespace
-
-TEST_F(PolicyHeaderIOHelperTest, InitialHeader) {
-  std::unique_ptr<net::URLRequest> request(
-      context_.CreateRequest(GURL(kDMServerURL), net::DEFAULT_PRIORITY, nullptr,
-                             TRAFFIC_ANNOTATION_FOR_TESTS));
-  helper_->AddPolicyHeaders(request->url(), request.get());
-  ValidateHeader(request->extra_request_headers(), kInitialPolicyHeader);
-}
-
-TEST_F(PolicyHeaderIOHelperTest, NoHeaderOnNonMatchingURL) {
-  std::unique_ptr<net::URLRequest> request(context_.CreateRequest(
-      GURL("http://non-matching.com"), net::DEFAULT_PRIORITY, nullptr,
-      TRAFFIC_ANNOTATION_FOR_TESTS));
-  helper_->AddPolicyHeaders(request->url(), request.get());
-  EXPECT_TRUE(request->extra_request_headers().IsEmpty());
-}
-
-TEST_F(PolicyHeaderIOHelperTest, HeaderChange) {
-  std::string new_header = "new_header";
-  helper_->UpdateHeader(new_header);
-  task_runner_->RunUntilIdle();
-  std::unique_ptr<net::URLRequest> request(
-      context_.CreateRequest(GURL(kDMServerURL), net::DEFAULT_PRIORITY, nullptr,
-                             TRAFFIC_ANNOTATION_FOR_TESTS));
-  helper_->AddPolicyHeaders(request->url(), request.get());
-  ValidateHeader(request->extra_request_headers(), new_header);
-}
-
-TEST_F(PolicyHeaderIOHelperTest, ChangeToNoHeader) {
-  helper_->UpdateHeader("");
-  task_runner_->RunUntilIdle();
-  std::unique_ptr<net::URLRequest> request(
-      context_.CreateRequest(GURL(kDMServerURL), net::DEFAULT_PRIORITY, nullptr,
-                             TRAFFIC_ANNOTATION_FOR_TESTS));
-  helper_->AddPolicyHeaders(request->url(), request.get());
-  EXPECT_TRUE(request->extra_request_headers().IsEmpty());
-}
-
-}  // namespace policy
diff --git a/components/policy/core/common/cloud/policy_header_service.cc b/components/policy/core/common/cloud/policy_header_service.cc
index 2bc90bb3..e4a38448 100644
--- a/components/policy/core/common/cloud/policy_header_service.cc
+++ b/components/policy/core/common/cloud/policy_header_service.cc
@@ -8,8 +8,9 @@
 #include "base/json/json_writer.h"
 #include "base/sequenced_task_runner.h"
 #include "base/values.h"
+#include "components/policy/core/common/cloud/cloud_policy_constants.h"
 #include "components/policy/core/common/cloud/cloud_policy_store.h"
-#include "components/policy/core/common/cloud/policy_header_io_helper.h"
+#include "net/http/http_request_headers.h"
 
 namespace {
 const char kUserDMTokenKey[] = "user_dmtoken";
@@ -27,21 +28,23 @@
       verification_key_hash_(verification_key_hash),
       user_policy_store_(user_policy_store) {
   user_policy_store_->AddObserver(this);
+  policy_header_ = CreateHeaderValue();
 }
 
 PolicyHeaderService::~PolicyHeaderService() {
   user_policy_store_->RemoveObserver(this);
 }
 
-std::unique_ptr<PolicyHeaderIOHelper>
-PolicyHeaderService::CreatePolicyHeaderIOHelper(
-    scoped_refptr<base::SequencedTaskRunner> task_runner) {
-  std::string initial_header_value = CreateHeaderValue();
-  std::unique_ptr<PolicyHeaderIOHelper> helper =
-      std::make_unique<PolicyHeaderIOHelper>(server_url_, initial_header_value,
-                                             task_runner);
-  helpers_.push_back(helper.get());
-  return helper;
+void PolicyHeaderService::AddPolicyHeaders(
+    const GURL& url,
+    std::unique_ptr<net::HttpRequestHeaders>* extra_headers) const {
+  DCHECK(extra_headers);
+  if (!policy_header_.empty() &&
+      url.spec().compare(0, server_url_.size(), server_url_) == 0) {
+    if (!extra_headers->get())
+      (*extra_headers) = std::make_unique<net::HttpRequestHeaders>();
+    (*extra_headers)->SetHeader(kChromePolicyHeader, policy_header_);
+  }
 }
 
 std::string PolicyHeaderService::CreateHeaderValue() {
@@ -80,22 +83,19 @@
 }
 
 void PolicyHeaderService::OnStoreLoaded(CloudPolicyStore* store) {
-  // If we have a PolicyHeaderIOHelper, notify it of the new header value.
-  if (!helpers_.empty()) {
-    std::string new_header = CreateHeaderValue();
-    for (std::vector<PolicyHeaderIOHelper*>::const_iterator it =
-             helpers_.begin(); it != helpers_.end(); ++it) {
-      (*it)->UpdateHeader(new_header);
-    }
-  }
+  policy_header_ = CreateHeaderValue();
 }
 
 void PolicyHeaderService::OnStoreError(CloudPolicyStore* store) {
   // Do nothing on errors.
 }
 
-std::vector<PolicyHeaderIOHelper*> PolicyHeaderService::GetHelpersForTest() {
-  return helpers_;
+void PolicyHeaderService::SetHeaderForTest(const std::string& new_header) {
+  policy_header_ = new_header;
+}
+
+void PolicyHeaderService::SetServerURLForTest(const std::string& server_url) {
+  server_url_ = server_url;
 }
 
 }  // namespace policy
diff --git a/components/policy/core/common/cloud/policy_header_service.h b/components/policy/core/common/cloud/policy_header_service.h
index def3d3a4..584fa5d 100644
--- a/components/policy/core/common/cloud/policy_header_service.h
+++ b/components/policy/core/common/cloud/policy_header_service.h
@@ -13,17 +13,15 @@
 #include "base/memory/ref_counted.h"
 #include "components/policy/core/common/cloud/cloud_policy_store.h"
 #include "components/policy/policy_export.h"
+#include "url/gurl.h"
 
-namespace base {
-class SequencedTaskRunner;
+namespace net {
+class HttpRequestHeaders;
 }
 
 namespace policy {
 
-class PolicyHeaderIOHelper;
-
-// Per-profile service used to generate PolicyHeaderIOHelper objects, and
-// keep them up to date as policy changes.
+// Per-profile service used to keep track of policy changes.
 // TODO(atwilson): Move to components/policy once CloudPolicyStore is moved.
 class POLICY_EXPORT PolicyHeaderService : public CloudPolicyStore::Observer {
  public:
@@ -35,27 +33,26 @@
                       CloudPolicyStore* user_policy_store);
   ~PolicyHeaderService() override;
 
-  // Creates a PolicyHeaderIOHelper object to be run on the IO thread and
-  // add policy headers to outgoing requests. The caller takes ownership of
-  // this object and must ensure it outlives ProfileHeaderService (in practice,
-  // this is called by ProfileIOData, which is shutdown *after* all
-  // ProfileKeyedServices are shutdown).
-  std::unique_ptr<PolicyHeaderIOHelper> CreatePolicyHeaderIOHelper(
-      scoped_refptr<base::SequencedTaskRunner> task_runner);
+  // Update |*extra_headers| (allocate if necessary) with the policy header if
+  // |url| matches |server_url_|. Otherwise |extra_headers| remains unchanged.
+  void AddPolicyHeaders(
+      const GURL& url,
+      std::unique_ptr<net::HttpRequestHeaders>* extra_headers) const;
 
   // Overridden CloudPolicyStore::Observer methods:
   void OnStoreLoaded(CloudPolicyStore* store) override;
   void OnStoreError(CloudPolicyStore* store) override;
 
-  // Returns a list of all PolicyHeaderIOHelpers created by this object.
-  std::vector<PolicyHeaderIOHelper*> GetHelpersForTest();
+  // Test-only routines used to inject the server URL/headers at runtime.
+  void SetHeaderForTest(const std::string& new_header);
+  void SetServerURLForTest(const std::string& server_url);
 
  private:
   // Generate a policy header based on the currently loaded policy.
   std::string CreateHeaderValue();
 
-  // Weak pointer to created PolicyHeaderIOHelper objects.
-  std::vector<PolicyHeaderIOHelper*> helpers_;
+  // The current policy header value.
+  std::string policy_header_;
 
   // URL of the policy server.
   std::string server_url_;
diff --git a/components/policy/core/common/cloud/policy_header_service_unittest.cc b/components/policy/core/common/cloud/policy_header_service_unittest.cc
index ea04325b..a4a1124 100644
--- a/components/policy/core/common/cloud/policy_header_service_unittest.cc
+++ b/components/policy/core/common/cloud/policy_header_service_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/values.h"
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
-#include "components/policy/core/common/cloud/policy_header_io_helper.h"
 #include "net/http/http_request_headers.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "net/url_request/url_request.h"
@@ -48,14 +47,19 @@
     service_.reset(new PolicyHeaderService(kDMServerURL,
                                            kPolicyVerificationKeyHash,
                                            &user_store_));
-    helper_ = service_->CreatePolicyHeaderIOHelper(task_runner_);
   }
 
   void TearDown() override {
     task_runner_->RunUntilIdle();
     // Helper should outlive the service.
     service_.reset();
-    helper_.reset();
+  }
+
+  void ValidateHeader(const net::HttpRequestHeaders& headers,
+                      const std::string& expected) {
+    std::string header;
+    EXPECT_TRUE(headers.GetHeader(kPolicyHeaderName, &header));
+    EXPECT_EQ(header, expected);
   }
 
   void ValidateHeader(const net::HttpRequestHeaders& headers,
@@ -88,7 +92,6 @@
   base::MessageLoop loop_;
   std::unique_ptr<PolicyHeaderService> service_;
   TestCloudPolicyStore user_store_;
-  std::unique_ptr<PolicyHeaderIOHelper> helper_;
   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
 };
 
@@ -97,11 +100,10 @@
 TEST_F(PolicyHeaderServiceTest, TestCreationAndShutdown) {
   // Just tests that the objects can be created and shutdown properly.
   EXPECT_TRUE(service_);
-  EXPECT_TRUE(helper_);
 }
 
 TEST_F(PolicyHeaderServiceTest, TestWithAndWithoutPolicyHeader) {
-  // Set policy - this should push a header to the PolicyHeaderIOHelper.
+  // Set policy.
   std::unique_ptr<PolicyData> policy(new PolicyData());
   std::string expected_dmtoken = "expected_dmtoken";
   std::string expected_policy_token = "expected_dmtoken";
@@ -111,22 +113,44 @@
   task_runner_->RunUntilIdle();
 
   net::TestURLRequestContext context;
-  std::unique_ptr<net::URLRequest> request(
-      context.CreateRequest(GURL(kDMServerURL), net::DEFAULT_PRIORITY, nullptr,
-                            TRAFFIC_ANNOTATION_FOR_TESTS));
-  helper_->AddPolicyHeaders(request->url(), request.get());
-  ValidateHeader(request->extra_request_headers(), expected_dmtoken,
-                 expected_policy_token);
+  std::unique_ptr<net::HttpRequestHeaders> extra_headers =
+      std::make_unique<net::HttpRequestHeaders>();
+  service_->AddPolicyHeaders(GURL(kDMServerURL), &extra_headers);
+  ValidateHeader(*extra_headers, expected_dmtoken, expected_policy_token);
 
   // Now blow away the policy data.
   user_store_.SetPolicy(std::unique_ptr<PolicyData>());
   task_runner_->RunUntilIdle();
 
-  std::unique_ptr<net::URLRequest> request2(
-      context.CreateRequest(GURL(kDMServerURL), net::DEFAULT_PRIORITY, nullptr,
-                            TRAFFIC_ANNOTATION_FOR_TESTS));
-  helper_->AddPolicyHeaders(request2->url(), request2.get());
-  ValidateHeader(request2->extra_request_headers(), "", "");
+  std::unique_ptr<net::HttpRequestHeaders> extra_headers2 =
+      std::make_unique<net::HttpRequestHeaders>();
+  service_->AddPolicyHeaders(GURL(kDMServerURL), &extra_headers2);
+  ValidateHeader(*extra_headers2, "", "");
+}
+
+TEST_F(PolicyHeaderServiceTest, NoHeaderOnNonMatchingURL) {
+  service_->SetHeaderForTest("new_header");
+  std::unique_ptr<net::HttpRequestHeaders> extra_headers =
+      std::make_unique<net::HttpRequestHeaders>();
+  service_->AddPolicyHeaders(GURL("http://non-matching.com"), &extra_headers);
+  EXPECT_TRUE(extra_headers->IsEmpty());
+}
+
+TEST_F(PolicyHeaderServiceTest, HeaderChange) {
+  std::string new_header = "new_header";
+  service_->SetHeaderForTest(new_header);
+  std::unique_ptr<net::HttpRequestHeaders> extra_headers =
+      std::make_unique<net::HttpRequestHeaders>();
+  service_->AddPolicyHeaders(GURL(kDMServerURL), &extra_headers);
+  ValidateHeader(*extra_headers, new_header);
+}
+
+TEST_F(PolicyHeaderServiceTest, ChangeToNoHeader) {
+  service_->SetHeaderForTest("");
+  std::unique_ptr<net::HttpRequestHeaders> extra_headers =
+      std::make_unique<net::HttpRequestHeaders>();
+  service_->AddPolicyHeaders(GURL(kDMServerURL), &extra_headers);
+  EXPECT_TRUE(extra_headers->IsEmpty());
 }
 
 }  // namespace policy
diff --git a/components/policy/core/common/schema_unittest.cc b/components/policy/core/common/schema_unittest.cc
index 54764d8..934a10fd 100644
--- a/components/policy/core/common/schema_unittest.cc
+++ b/components/policy/core/common/schema_unittest.cc
@@ -23,116 +23,115 @@
     TestSchemaValidationHelper(          \
         base::StringPrintf("%s:%i", __FILE__, __LINE__), a, b, c, d)
 
-const char kTestSchema[] =
-    "{"
-    "  \"type\": \"object\","
-    "  \"properties\": {"
-    "    \"Boolean\": { \"type\": \"boolean\" },"
-    "    \"Integer\": { \"type\": \"integer\" },"
-    "    \"Null\": { \"type\": \"null\" },"
-    "    \"Number\": { \"type\": \"number\" },"
-    "    \"String\": { \"type\": \"string\" },"
-    "    \"Array\": {"
-    "      \"type\": \"array\","
-    "      \"items\": { \"type\": \"string\" }"
-    "    },"
-    "    \"ArrayOfObjects\": {"
-    "      \"type\": \"array\","
-    "      \"items\": {"
-    "        \"type\": \"object\","
-    "        \"properties\": {"
-    "          \"one\": { \"type\": \"string\" },"
-    "          \"two\": { \"type\": \"integer\" }"
-    "        }"
-    "      }"
-    "    },"
-    "    \"ArrayOfArray\": {"
-    "      \"type\": \"array\","
-    "      \"items\": {"
-    "        \"type\": \"array\","
-    "        \"items\": { \"type\": \"string\" }"
-    "      }"
-    "    },"
-    "    \"Object\": {"
-    "      \"type\": \"object\","
-    "      \"properties\": {"
-    "        \"one\": { \"type\": \"boolean\" },"
-    "        \"two\": { \"type\": \"integer\" }"
-    "      },"
-    "      \"additionalProperties\": { \"type\": \"string\" }"
-    "    },"
-    "    \"ObjectOfObject\": {"
-    "      \"type\": \"object\","
-    "      \"properties\": {"
-    "        \"Object\": {"
-    "          \"type\": \"object\","
-    "          \"properties\": {"
-    "            \"one\": { \"type\": \"string\" },"
-    "            \"two\": { \"type\": \"integer\" }"
-    "          }"
-    "        }"
-    "      }"
-    "    },"
-    "    \"IntegerWithEnums\": {"
-    "      \"type\": \"integer\","
-    "      \"enum\": [1, 2, 3]"
-    "    },"
-    "    \"IntegerWithEnumsGaps\": {"
-    "      \"type\": \"integer\","
-    "      \"enum\": [10, 20, 30]"
-    "    },"
-    "    \"StringWithEnums\": {"
-    "      \"type\": \"string\","
-    "      \"enum\": [\"one\", \"two\", \"three\"]"
-    "    },"
-    "    \"IntegerWithRange\": {"
-    "      \"type\": \"integer\","
-    "      \"minimum\": 1,"
-    "      \"maximum\": 3"
-    "    },"
-    "    \"ObjectOfArray\": {"
-    "      \"type\": \"object\","
-    "      \"properties\": {"
-    "        \"List\": {"
-    "          \"type\": \"array\","
-    "          \"items\": { \"type\": \"integer\" }"
-    "        }"
-    "      }"
-    "    },"
-    "    \"ArrayOfObjectOfArray\": {"
-    "      \"type\": \"array\","
-    "      \"items\": {"
-    "        \"type\": \"object\","
-    "        \"properties\": {"
-    "          \"List\": {"
-    "            \"type\": \"array\","
-    "            \"items\": { \"type\": \"string\" }"
-    "          }"
-    "        }"
-    "      }"
-    "    },"
-    "    \"StringWithPattern\": {"
-    "      \"type\": \"string\","
-    "      \"pattern\": \"^foo+$\""
-    "    },"
-    "    \"ObjectWithPatternProperties\": {"
-    "      \"type\": \"object\","
-    "      \"patternProperties\": {"
-    "        \"^foo+$\": { \"type\": \"integer\" },"
-    "        \"^bar+$\": {"
-    "          \"type\": \"string\","
-    "          \"enum\": [\"one\", \"two\"]"
-    "        }"
-    "      },"
-    "      \"properties\": {"
-    "        \"bar\": {"
-    "          \"type\": \"string\","
-    "          \"enum\": [\"one\", \"three\"]"
-    "        }"
-    "      }"
-    "    }"
-    "  }"
-    "}";
+const char kTestSchema[] = R"({
+  "type": "object",
+  "properties": {
+    "Boolean": { "type": "boolean" },
+    "Integer": { "type": "integer" },
+    "Null": { "type": "null" },
+    "Number": { "type": "number" },
+    "String": { "type": "string" },
+    "Array": {
+      "type": "array",
+      "items": { "type": "string" }
+    },
+    "ArrayOfObjects": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "properties": {
+          "one": { "type": "string" },
+          "two": { "type": "integer" }
+        }
+      }
+    },
+    "ArrayOfArray": {
+      "type": "array",
+      "items": {
+        "type": "array",
+        "items": { "type": "string" }
+      }
+    },
+    "Object": {
+      "type": "object",
+      "properties": {
+        "one": { "type": "boolean" },
+        "two": { "type": "integer" }
+      },
+      "additionalProperties": { "type": "string" }
+    },
+    "ObjectOfObject": {
+      "type": "object",
+      "properties": {
+        "Object": {
+          "type": "object",
+          "properties": {
+            "one": { "type": "string" },
+            "two": { "type": "integer" }
+          }
+        }
+      }
+    },
+    "IntegerWithEnums": {
+      "type": "integer",
+      "enum": [1, 2, 3]
+    },
+    "IntegerWithEnumsGaps": {
+      "type": "integer",
+      "enum": [10, 20, 30]
+    },
+    "StringWithEnums": {
+      "type": "string",
+      "enum": ["one", "two", "three"]
+    },
+    "IntegerWithRange": {
+      "type": "integer",
+      "minimum": 1,
+      "maximum": 3
+    },
+    "ObjectOfArray": {
+      "type": "object",
+      "properties": {
+        "List": {
+          "type": "array",
+          "items": { "type": "integer" }
+        }
+      }
+    },
+    "ArrayOfObjectOfArray": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "properties": {
+          "List": {
+            "type": "array",
+            "items": { "type": "string" }
+          }
+        }
+      }
+    },
+    "StringWithPattern": {
+      "type": "string",
+      "pattern": "^foo+$"
+    },
+    "ObjectWithPatternProperties": {
+      "type": "object",
+      "patternProperties": {
+        "^foo+$": { "type": "integer" },
+        "^bar+$": {
+          "type": "string",
+          "enum": ["one", "two"]
+        }
+      },
+      "properties": {
+        "bar": {
+          "type": "string",
+          "enum": ["one", "three"]
+        }
+      }
+    }
+  }
+})";
 
 bool ParseFails(const std::string& content) {
   std::string error;
@@ -202,7 +201,7 @@
 }  // namespace
 
 TEST(SchemaTest, MinimalSchema) {
-  EXPECT_FALSE(ParseFails("{ \"type\": \"object\" }"));
+  EXPECT_FALSE(ParseFails(R"({ "type": "object" })"));
 }
 
 TEST(SchemaTest, InvalidSchemas) {
@@ -214,63 +213,56 @@
   EXPECT_TRUE(ParseFails("null"));
   EXPECT_TRUE(ParseFails("{}"));
 
-  EXPECT_TRUE(ParseFails(
-      "{"
-      "  \"type\": \"object\","
-        "\"additionalProperties\": { \"type\":\"object\" }"
-      "}"));
+  EXPECT_TRUE(ParseFails(R"({
+    "type": "object",
+    "additionalProperties": { "type":"object" }
+  })"));
 
-  EXPECT_TRUE(ParseFails(
-      "{"
-      "  \"type\": \"object\","
-      "  \"patternProperties\": { \"a+b*\": { \"type\": \"object\" } }"
-      "}"));
+  EXPECT_TRUE(ParseFails(R"({
+    "type": "object",
+    "patternProperties": { "a+b*": { "type": "object" } }
+  })"));
 
-  EXPECT_TRUE(ParseFails(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": { \"Policy\": { \"type\": \"bogus\" } }"
-      "}"));
+  EXPECT_TRUE(ParseFails(R"({
+    "type": "object",
+    "properties": { "Policy": { "type": "bogus" } }
+  })"));
 
-  EXPECT_TRUE(ParseFails(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": { \"Policy\": { \"type\": [\"string\", \"number\"] } }"
-      "}"));
+  EXPECT_TRUE(ParseFails(R"({
+    "type": "object",
+    "properties": { "Policy": { "type": ["string", "number"] } }
+  })"));
 
-  EXPECT_TRUE(ParseFails(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": { \"Policy\": { \"type\": \"any\" } }"
-      "}"));
+  EXPECT_TRUE(ParseFails(R"({
+    "type": "object",
+    "properties": { "Policy": { "type": "any" } }
+  })"));
 
-  EXPECT_TRUE(ParseFails(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": { \"Policy\": 123 }"
-      "}"));
+  EXPECT_TRUE(ParseFails(R"({
+    "type": "object",
+    "properties": { "Policy": 123 }
+  })"));
 
-  EXPECT_FALSE(ParseFails(
-      "{"
-      "  \"type\": \"object\","
-      "  \"unknown attribute\": \"is ignored\""
-      "}"));
+  EXPECT_FALSE(ParseFails(R"({
+    "type": "object",
+    "unknown attribute": "is ignored"
+  })"));
 }
 
 TEST(SchemaTest, Ownership) {
   std::string error;
-  Schema schema = Schema::Parse(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": {"
-      "    \"sub\": {"
-      "      \"type\": \"object\","
-      "      \"properties\": {"
-      "        \"subsub\": { \"type\": \"string\" }"
-      "      }"
-      "    }"
-      "  }"
-      "}", &error);
+  Schema schema = Schema::Parse(R"({
+    "type": "object",
+    "properties": {
+      "sub": {
+        "type": "object",
+        "properties": {
+          "subsub": { "type": "string" }
+        }
+      }
+    }
+  })",
+                                &error);
   ASSERT_TRUE(schema.valid()) << error;
   ASSERT_EQ(base::Value::Type::DICTIONARY, schema.type());
 
@@ -428,7 +420,7 @@
 TEST(SchemaTest, Lookups) {
   std::string error;
 
-  Schema schema = Schema::Parse("{ \"type\": \"object\" }", &error);
+  Schema schema = Schema::Parse(R"({ "type": "object" })", &error);
   ASSERT_TRUE(schema.valid()) << error;
   ASSERT_EQ(base::Value::Type::DICTIONARY, schema.type());
 
@@ -437,13 +429,13 @@
   EXPECT_FALSE(schema.GetKnownProperty("xyz").valid());
   EXPECT_TRUE(schema.GetPropertiesIterator().IsAtEnd());
 
-  schema = Schema::Parse(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": {"
-      "    \"Boolean\": { \"type\": \"boolean\" }"
-      "  }"
-      "}", &error);
+  schema = Schema::Parse(R"({
+    "type": "object",
+    "properties": {
+      "Boolean": { "type": "boolean" }
+    }
+  })",
+                         &error);
   ASSERT_TRUE(schema.valid()) << error;
   ASSERT_EQ(base::Value::Type::DICTIONARY, schema.type());
 
@@ -451,17 +443,17 @@
   EXPECT_FALSE(schema.GetKnownProperty("xyz").valid());
   EXPECT_TRUE(schema.GetKnownProperty("Boolean").valid());
 
-  schema = Schema::Parse(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": {"
-      "    \"bb\" : { \"type\": \"null\" },"
-      "    \"aa\" : { \"type\": \"boolean\" },"
-      "    \"abab\" : { \"type\": \"string\" },"
-      "    \"ab\" : { \"type\": \"number\" },"
-      "    \"aba\" : { \"type\": \"integer\" }"
-      "  }"
-      "}", &error);
+  schema = Schema::Parse(R"({
+    "type": "object",
+    "properties": {
+      "bb" : { "type": "null" },
+      "aa" : { "type": "boolean" },
+      "abab" : { "type": "string" },
+      "ab" : { "type": "number" },
+      "aba" : { "type": "integer" }
+    }
+  })",
+                         &error);
   ASSERT_TRUE(schema.valid()) << error;
   ASSERT_EQ(base::Value::Type::DICTIONARY, schema.type());
 
@@ -923,79 +915,74 @@
 
 TEST(SchemaTest, InvalidReferences) {
   // References to undeclared schemas fail.
-  EXPECT_TRUE(ParseFails(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": {"
-      "    \"name\": { \"$ref\": \"undeclared\" }"
-      "  }"
-      "}"));
+  EXPECT_TRUE(ParseFails(R"({
+    "type": "object",
+    "properties": {
+      "name": { "$ref": "undeclared" }
+    }
+  })"));
 
   // Can't refer to self.
-  EXPECT_TRUE(ParseFails(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": {"
-      "    \"name\": {"
-      "      \"id\": \"self\","
-      "      \"$ref\": \"self\""
-      "    }"
-      "  }"
-      "}"));
+  EXPECT_TRUE(ParseFails(R"({
+    "type": "object",
+    "properties": {
+      "name": {
+        "id": "self",
+        "$ref": "self"
+      }
+    }
+  })"));
 
   // Duplicated IDs are invalid.
-  EXPECT_TRUE(ParseFails(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": {"
-      "    \"name\": {"
-      "      \"id\": \"x\","
-      "      \"type\": \"string\""
-      "    },"
-      "    \"another\": {"
-      "      \"id\": \"x\","
-      "      \"type\": \"string\""
-      "    }"
-      "  }"
-      "}"));
+  EXPECT_TRUE(ParseFails(R"({
+    "type": "object",
+    "properties": {
+      "name": {
+        "id": "x",
+        "type": "string"
+      },
+      "another": {
+        "id": "x",
+        "type": "string"
+      }
+    }
+  })"));
 
   // Main object can't be a reference.
-  EXPECT_TRUE(ParseFails(
-      "{"
-      "  \"type\": \"object\","
-      "  \"id\": \"main\","
-      "  \"$ref\": \"main\""
-      "}"));
+  EXPECT_TRUE(ParseFails(R"({
+    "type": "object",
+    "id": "main",
+    "$ref": "main"
+  })"));
 
-  EXPECT_TRUE(ParseFails(
-      "{"
-      "  \"type\": \"object\","
-      "  \"$ref\": \"main\""
-      "}"));
+  EXPECT_TRUE(ParseFails(R"({
+    "type": "object",
+    "$ref": "main"
+  })"));
 }
 
 TEST(SchemaTest, RecursiveReferences) {
   // Verifies that references can go to a parent schema, to define a
   // recursive type.
   std::string error;
-  Schema schema = Schema::Parse(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": {"
-      "    \"bookmarks\": {"
-      "      \"type\": \"array\","
-      "      \"id\": \"ListOfBookmarks\","
-      "      \"items\": {"
-      "        \"type\": \"object\","
-      "        \"properties\": {"
-      "          \"name\": { \"type\": \"string\" },"
-      "          \"url\": { \"type\": \"string\" },"
-      "          \"children\": { \"$ref\": \"ListOfBookmarks\" }"
-      "        }"
-      "      }"
-      "    }"
-      "  }"
-      "}", &error);
+  Schema schema = Schema::Parse(R"({
+    "type": "object",
+    "properties": {
+      "bookmarks": {
+        "type": "array",
+        "id": "ListOfBookmarks",
+        "items": {
+          "type": "object",
+          "properties": {
+            "name": { "type": "string" },
+            "url": { "type": "string" },
+            "children": { "$ref": "ListOfBookmarks" }
+          }
+        }
+      }
+    }
+  })",
+                                &error);
   ASSERT_TRUE(schema.valid()) << error;
   ASSERT_EQ(base::Value::Type::DICTIONARY, schema.type());
 
@@ -1028,24 +1015,24 @@
 TEST(SchemaTest, UnorderedReferences) {
   // Verifies that references and IDs can come in any order.
   std::string error;
-  Schema schema = Schema::Parse(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": {"
-      "    \"a\": { \"$ref\": \"shared\" },"
-      "    \"b\": { \"$ref\": \"shared\" },"
-      "    \"c\": { \"$ref\": \"shared\" },"
-      "    \"d\": { \"$ref\": \"shared\" },"
-      "    \"e\": {"
-      "      \"type\": \"boolean\","
-      "      \"id\": \"shared\""
-      "    },"
-      "    \"f\": { \"$ref\": \"shared\" },"
-      "    \"g\": { \"$ref\": \"shared\" },"
-      "    \"h\": { \"$ref\": \"shared\" },"
-      "    \"i\": { \"$ref\": \"shared\" }"
-      "  }"
-      "}", &error);
+  Schema schema = Schema::Parse(R"({
+    "type": "object",
+    "properties": {
+      "a": { "$ref": "shared" },
+      "b": { "$ref": "shared" },
+      "c": { "$ref": "shared" },
+      "d": { "$ref": "shared" },
+      "e": {
+        "type": "boolean",
+        "id": "shared"
+      },
+      "f": { "$ref": "shared" },
+      "g": { "$ref": "shared" },
+      "h": { "$ref": "shared" },
+      "i": { "$ref": "shared" }
+    }
+  })",
+                                &error);
   ASSERT_TRUE(schema.valid()) << error;
   ASSERT_EQ(base::Value::Type::DICTIONARY, schema.type());
 
@@ -1059,22 +1046,22 @@
 TEST(SchemaTest, AdditionalPropertiesReference) {
   // Verifies that "additionalProperties" can be a reference.
   std::string error;
-  Schema schema = Schema::Parse(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": {"
-      "    \"policy\": {"
-      "      \"type\": \"object\","
-      "      \"properties\": {"
-      "        \"foo\": {"
-      "          \"type\": \"boolean\","
-      "          \"id\": \"FooId\""
-      "        }"
-      "      },"
-      "      \"additionalProperties\": { \"$ref\": \"FooId\" }"
-      "    }"
-      "  }"
-      "}", &error);
+  Schema schema = Schema::Parse(R"({
+    "type": "object",
+    "properties": {
+      "policy": {
+        "type": "object",
+        "properties": {
+          "foo": {
+            "type": "boolean",
+            "id": "FooId"
+          }
+        },
+        "additionalProperties": { "$ref": "FooId" }
+      }
+    }
+  })",
+                                &error);
   ASSERT_TRUE(schema.valid()) << error;
   ASSERT_EQ(base::Value::Type::DICTIONARY, schema.type());
 
@@ -1098,20 +1085,20 @@
 TEST(SchemaTest, ItemsReference) {
   // Verifies that "items" can be a reference.
   std::string error;
-  Schema schema = Schema::Parse(
-      "{"
-      "  \"type\": \"object\","
-      "  \"properties\": {"
-      "    \"foo\": {"
-      "      \"type\": \"boolean\","
-      "      \"id\": \"FooId\""
-      "    },"
-      "    \"list\": {"
-      "      \"type\": \"array\","
-      "      \"items\": { \"$ref\": \"FooId\" }"
-      "    }"
-      "  }"
-      "}", &error);
+  Schema schema = Schema::Parse(R"({
+    "type": "object",
+    "properties": {
+      "foo": {
+        "type": "boolean",
+        "id": "FooId"
+      },
+      "list": {
+        "type": "array",
+        "items": { "$ref": "FooId" }
+      }
+    }
+  })",
+                                &error);
   ASSERT_TRUE(schema.valid()) << error;
   ASSERT_EQ(base::Value::Type::DICTIONARY, schema.type());
 
@@ -1130,53 +1117,46 @@
 
 TEST(SchemaTest, EnumerationRestriction) {
   // Enum attribute is a list.
-  EXPECT_TRUE(ParseFails(SchemaObjectWrapper(
-      "{"
-      "  \"type\": \"string\","
-      "  \"enum\": 12"
-      "}")));
+  EXPECT_TRUE(ParseFails(SchemaObjectWrapper(R"({
+    "type": "string",
+    "enum": 12
+  })")));
 
   // Empty enum attributes is not allowed.
-  EXPECT_TRUE(ParseFails(SchemaObjectWrapper(
-      "{"
-      "  \"type\": \"integer\","
-      "  \"enum\": []"
-      "}")));
+  EXPECT_TRUE(ParseFails(SchemaObjectWrapper(R"({
+    "type": "integer",
+    "enum": []
+  })")));
 
   // Enum elements type should be same as stated.
-  EXPECT_TRUE(ParseFails(SchemaObjectWrapper(
-      "{"
-      "  \"type\": \"string\","
-      "  \"enum\": [1, 2, 3]"
-      "}")));
+  EXPECT_TRUE(ParseFails(SchemaObjectWrapper(R"({
+    "type": "string",
+    "enum": [1, 2, 3]
+  })")));
 
-  EXPECT_FALSE(ParseFails(SchemaObjectWrapper(
-      "{"
-      "  \"type\": \"integer\","
-      "  \"enum\": [1, 2, 3]"
-      "}")));
+  EXPECT_FALSE(ParseFails(SchemaObjectWrapper(R"({
+    "type": "integer",
+    "enum": [1, 2, 3]
+  })")));
 
-  EXPECT_FALSE(ParseFails(SchemaObjectWrapper(
-      "{"
-      "  \"type\": \"string\","
-      "  \"enum\": [\"1\", \"2\", \"3\"]"
-      "}")));
+  EXPECT_FALSE(ParseFails(SchemaObjectWrapper(R"({
+    "type": "string",
+    "enum": ["1", "2", "3"]
+  })")));
 }
 
 TEST(SchemaTest, RangedRestriction) {
-  EXPECT_TRUE(ParseFails(SchemaObjectWrapper(
-      "{"
-      "  \"type\": \"integer\","
-      "  \"minimum\": 10,"
-      "  \"maximum\": 5"
-      "}")));
+  EXPECT_TRUE(ParseFails(SchemaObjectWrapper(R"({
+    "type": "integer",
+    "minimum": 10,
+    "maximum": 5
+  })")));
 
-  EXPECT_FALSE(ParseFails(SchemaObjectWrapper(
-      "{"
-      "  \"type\": \"integer\","
-      "  \"minimum\": 10,"
-      "  \"maximum\": 20"
-      "}")));
+  EXPECT_FALSE(ParseFails(SchemaObjectWrapper(R"({
+    "type": "integer",
+    "minimum": 10,
+    "maximum": 20
+  })")));
 }
 
 }  // namespace policy
diff --git a/components/resources/default_100_percent/autofill/infobar_autofill_cc.png b/components/resources/default_100_percent/autofill/infobar_autofill_cc.png
index 8cb55a6..b733627 100644
--- a/components/resources/default_100_percent/autofill/infobar_autofill_cc.png
+++ b/components/resources/default_100_percent/autofill/infobar_autofill_cc.png
Binary files differ
diff --git a/components/resources/default_200_percent/autofill/infobar_autofill_cc.png b/components/resources/default_200_percent/autofill/infobar_autofill_cc.png
index 2d03fbf..6cdb9ce6 100644
--- a/components/resources/default_200_percent/autofill/infobar_autofill_cc.png
+++ b/components/resources/default_200_percent/autofill/infobar_autofill_cc.png
Binary files differ
diff --git a/components/resources/default_300_percent/autofill/infobar_autofill_cc.png b/components/resources/default_300_percent/autofill/infobar_autofill_cc.png
index 7a3255a..870022b3 100644
--- a/components/resources/default_300_percent/autofill/infobar_autofill_cc.png
+++ b/components/resources/default_300_percent/autofill/infobar_autofill_cc.png
Binary files differ
diff --git a/components/safe_browsing/features.cc b/components/safe_browsing/features.cc
index aaa629c8..e44df76e3 100644
--- a/components/safe_browsing/features.cc
+++ b/components/safe_browsing/features.cc
@@ -47,7 +47,7 @@
     "InspectDownloadedRarFiles", base::FEATURE_DISABLED_BY_DEFAULT};
 
 const base::Feature kEnterprisePasswordProtectionV1{
-    "EnterprisePasswordProtectionV1", base::FEATURE_DISABLED_BY_DEFAULT};
+    "EnterprisePasswordProtectionV1", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kForceEnableResetPasswordWebUI{
     "ForceEnableResetPasswordWebUI", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -63,7 +63,6 @@
 } kExperimentalFeatures[]{
     {&kAdSamplerTriggerFeature, false},
     {&kCheckByURLLoaderThrottle, true},
-    {&kEnterprisePasswordProtectionV1, true},
     {&kForceEnableResetPasswordWebUI, true},
     {&kInspectDownloadedRarFiles, true},
     {&kSuspiciousSiteTriggerQuotaFeature, false},
diff --git a/components/sync/driver/model_association_manager.cc b/components/sync/driver/model_association_manager.cc
index 63b01e59..94386c5d 100644
--- a/components/sync/driver/model_association_manager.cc
+++ b/components/sync/driver/model_association_manager.cc
@@ -180,6 +180,7 @@
     auto dtc_iter = controllers_->find(type);
     DCHECK(dtc_iter != controllers_->end());
     DataTypeController* dtc = dtc_iter->second.get();
+    DCHECK_NE(DataTypeController::STOPPING, dtc->state());
     if (dtc->state() == DataTypeController::NOT_RUNNING) {
       DCHECK(!loaded_types_.Has(dtc->type()));
       DCHECK(!associated_types_.Has(dtc->type()));
diff --git a/components/sync/driver/model_type_controller.cc b/components/sync/driver/model_type_controller.cc
index 87fe2d1..6819c11 100644
--- a/components/sync/driver/model_type_controller.cc
+++ b/components/sync/driver/model_type_controller.cc
@@ -108,14 +108,9 @@
     const ModelLoadCallback& model_load_callback) {
   DCHECK(CalledOnValidThread());
   DCHECK(!model_load_callback.is_null());
-  model_load_callback_ = model_load_callback;
+  DCHECK_EQ(NOT_RUNNING, state_);
 
-  if (state() != NOT_RUNNING) {
-    LoadModelsDone(RUNTIME_ERROR,
-                   SyncError(FROM_HERE, SyncError::DATATYPE_ERROR,
-                             "Model already running", type()));
-    return;
-  }
+  model_load_callback_ = model_load_callback;
 
   DVLOG(1) << "Sync starting for " << ModelTypeToString(type());
   state_ = MODEL_STARTING;
@@ -169,6 +164,7 @@
     DVLOG(1) << "Sync start completed for " << ModelTypeToString(type());
   } else {
     RecordStartFailure(result);
+    state_ = FAILED;
   }
 
   if (!model_load_callback_.is_null()) {
@@ -241,21 +237,31 @@
 void ModelTypeController::Stop(SyncStopMetadataFate metadata_fate) {
   DCHECK(CalledOnValidThread());
 
-  if (state() == NOT_RUNNING)
-    return;
+  switch (state()) {
+    case ASSOCIATING:
+    case STOPPING:
+      // We don't really use these states in this class.
+      NOTREACHED();
+      break;
 
-  // Only call StopSync if the delegate is ready to handle it (controller is
-  // in loaded state).
-  if (state() == MODEL_LOADED || state() == RUNNING) {
-    DVLOG(1) << "Stopping sync for " << ModelTypeToString(type());
-    PostModelTask(FROM_HERE,
-                  base::BindOnce(&StopSyncHelperOnModelThread, metadata_fate));
-  } else {
-    DCHECK_EQ(MODEL_STARTING, state_);
-    DVLOG(1) << "Shortcutting stop for " << ModelTypeToString(type())
-             << " because it's still starting";
-    // TODO(mastiz): Enter STOPPING state here and/or queue pending stops,
-    // together with |metadata_fate|.
+    case NOT_RUNNING:
+    case FAILED:
+      // Nothing to stop. |metadata_fate| might require CLEAR_METADATA,
+      // which could lead to leaking sync metadata, but it doesn't seem a
+      // realistic scenario (disable sync during shutdown?).
+      return;
+
+    case MODEL_STARTING:
+      DLOG(WARNING) << "Shortcutting stop for " << ModelTypeToString(type())
+                    << " because it's still starting";
+      break;
+
+    case MODEL_LOADED:
+    case RUNNING:
+      DVLOG(1) << "Stopping sync for " << ModelTypeToString(type());
+      PostModelTask(FROM_HERE, base::BindOnce(&StopSyncHelperOnModelThread,
+                                              metadata_fate));
+      break;
   }
 
   state_ = NOT_RUNNING;
diff --git a/components/sync/driver/model_type_controller_unittest.cc b/components/sync/driver/model_type_controller_unittest.cc
index 054305d..28a944c 100644
--- a/components/sync/driver/model_type_controller_unittest.cc
+++ b/components/sync/driver/model_type_controller_unittest.cc
@@ -312,16 +312,6 @@
   ExpectProcessorConnected(false);
 }
 
-TEST_F(ModelTypeControllerTest, LoadModelsTwice) {
-  LoadModels();
-  RunAllTasks();
-  EXPECT_EQ(DataTypeController::MODEL_LOADED, controller()->state());
-  EXPECT_FALSE(load_models_last_error().IsSet());
-  // A second LoadModels call should set the error.
-  LoadModels();
-  EXPECT_TRUE(load_models_last_error().IsSet());
-}
-
 TEST_F(ModelTypeControllerTest, Activate) {
   LoadModels();
   RunAllTasks();
diff --git a/components/sync/driver/startup_controller.cc b/components/sync/driver/startup_controller.cc
index 710f68b4a..3b3d24f 100644
--- a/components/sync/driver/startup_controller.cc
+++ b/components/sync/driver/startup_controller.cc
@@ -67,14 +67,13 @@
       can_start_callback_(std::move(can_start)),
       start_engine_callback_(std::move(start_engine)),
       bypass_setup_complete_(false),
-      received_start_request_(false),
-      setup_in_progress_(false),
+      bypass_deferred_startup_(false),
       weak_factory_(this) {}
 
 StartupController::~StartupController() {}
 
 void StartupController::Reset() {
-  received_start_request_ = false;
+  bypass_deferred_startup_ = false;
   bypass_setup_complete_ = false;
   start_up_time_ = base::Time();
   start_engine_time_ = base::Time();
@@ -82,13 +81,6 @@
   weak_factory_.InvalidateWeakPtrs();
 }
 
-void StartupController::SetSetupInProgress(bool setup_in_progress) {
-  setup_in_progress_ = setup_in_progress;
-  if (setup_in_progress_) {
-    TryStart();
-  }
-}
-
 void StartupController::StartUp(StartUpDeferredOption deferred_option) {
   const bool first_start = start_up_time_.is_null();
   if (first_start) {
@@ -113,7 +105,7 @@
   }
 }
 
-void StartupController::TryStart() {
+void StartupController::TryStart(bool force_immediate) {
   if (!can_start_callback_.Run()) {
     return;
   }
@@ -125,17 +117,16 @@
   //   and encryption information to the UI.
   // Do not start up the sync engine if setup has not completed and isn't
   // in progress, unless told to otherwise.
-  if (setup_in_progress_) {
+  if (force_immediate) {
     StartUp(STARTUP_IMMEDIATE);
   } else if (sync_prefs_->IsFirstSetupComplete() || bypass_setup_complete_) {
-    StartUp(received_start_request_ ? STARTUP_IMMEDIATE : STARTUP_DEFERRED);
+    StartUp(bypass_deferred_startup_ ? STARTUP_IMMEDIATE : STARTUP_DEFERRED);
   }
 }
 
-void StartupController::TryStartImmediately() {
-  received_start_request_ = true;
+void StartupController::SetBypassSetupCompleteAndDeferredStartup() {
+  bypass_deferred_startup_ = true;
   bypass_setup_complete_ = true;
-  TryStart();
 }
 
 void StartupController::RecordTimeDeferred() {
@@ -156,8 +147,8 @@
   RecordTimeDeferred();
   UMA_HISTOGRAM_ENUMERATION("Sync.Startup.DeferredInitTrigger",
                             TRIGGER_FALLBACK_TIMER, MAX_TRIGGER_VALUE);
-  received_start_request_ = true;
-  TryStart();
+  bypass_deferred_startup_ = true;
+  TryStart(/*force_immediate=*/false);
 }
 
 StartupController::State StartupController::GetState() const {
@@ -191,8 +182,8 @@
     UMA_HISTOGRAM_ENUMERATION("Sync.Startup.DeferredInitTrigger",
                               TRIGGER_DATA_TYPE_REQUEST, MAX_TRIGGER_VALUE);
   }
-  received_start_request_ = true;
-  TryStart();
+  bypass_deferred_startup_ = true;
+  TryStart(/*force_immediate=*/false);
 }
 
 }  // namespace syncer
diff --git a/components/sync/driver/startup_controller.h b/components/sync/driver/startup_controller.h
index ccce7aad..714ae63c 100644
--- a/components/sync/driver/startup_controller.h
+++ b/components/sync/driver/startup_controller.h
@@ -37,11 +37,17 @@
   ~StartupController();
 
   // Starts up sync if it is requested by the user and preconditions are met.
-  void TryStart();
+  // If |force_immediate| is true, this will start sync immediately, bypassing
+  // deferred startup and the "first setup complete" check (but *not* the
+  // |can_start_callback_| check!).
+  void TryStart(bool force_immediate);
 
-  // Same as TryStart() above, but bypasses deferred startup and the first setup
-  // complete check.
-  void TryStartImmediately();
+  // Tells the controller to bypass deferred startup and the "first setup
+  // complete" check. After this, any TryStart() calls (until a Reset()) will
+  // cause immediate startup.
+  // TODO(crbug.com/854978): See if we can get rid of this and just call
+  // TryStart(true) instead.
+  void SetBypassSetupCompleteAndDeferredStartup();
 
   // Called when a datatype (SyncableService) has a need for sync to start
   // ASAP, presumably because a local change event has occurred but we're
@@ -52,18 +58,10 @@
 
   // Prepares this object for a new attempt to start sync, forgetting
   // whether or not preconditions were previously met.
-  // NOTE: This resets internal state managed by this class, but does not
-  // touch values that are explicitly set and reset by higher layers to
-  // tell this class whether a setup UI dialog is being shown to the user.
-  // See setup_in_progress_.
   void Reset();
 
-  // Sets the setup in progress flag and tries to start sync if it's true.
-  void SetSetupInProgress(bool setup_in_progress);
-
   State GetState() const;
 
-  bool IsSetupInProgress() const { return setup_in_progress_; }
   base::Time start_engine_time() const { return start_engine_time_; }
 
  private:
@@ -89,13 +87,13 @@
   const base::RepeatingClosure start_engine_callback_;
 
   // If true, will bypass the FirstSetupComplete check when triggering sync
-  // startup. Set in TryStartImmediately.
+  // startup. Set in SetBypassSetupCompleteAndDeferredStartup.
   bool bypass_setup_complete_;
 
-  // True if we should start sync ASAP because either a data type has
-  // requested it, or TryStartImmediately was called, or our deferred startup
-  // timer has expired.
-  bool received_start_request_;
+  // True if we should start sync ASAP because either a data type has requested
+  // it, or SetBypassSetupCompleteAndDeferredStartup was called, or our deferred
+  // startup timer has expired.
+  bool bypass_deferred_startup_;
 
   // The time that StartUp() is called. This is used to calculate time spent
   // in the deferred state; that is, after StartUp and before invoking the
@@ -103,13 +101,6 @@
   // startup has been triggered.
   base::Time start_up_time_;
 
-  // If |true|, there is setup UI visible so we should not start downloading
-  // data types.
-  // Note: this is explicitly controlled by higher layers (UI) and is meant to
-  // reflect what the UI claims the setup state to be. Therefore, only set this
-  // due to explicit requests to do so via SetSetupInProgress.
-  bool setup_in_progress_;
-
   // The time at which we invoked the |start_engine_| callback. If this is
   // non-null, then |start_engine_| shouldn't be called again.
   base::Time start_engine_time_;
diff --git a/components/sync/driver/startup_controller_unittest.cc b/components/sync/driver/startup_controller_unittest.cc
index 049af22..9f1ae7b 100644
--- a/components/sync/driver/startup_controller_unittest.cc
+++ b/components/sync/driver/startup_controller_unittest.cc
@@ -81,11 +81,11 @@
 
 // Test that sync doesn't start if setup is not in progress or complete.
 TEST_F(StartupControllerTest, NoSetupComplete) {
-  controller()->TryStart();
+  controller()->TryStart(/*force_immediate=*/false);
   ExpectNotStarted();
 
   SetCanStart(true);
-  controller()->TryStart();
+  controller()->TryStart(/*force_immediate=*/false);
   ExpectNotStarted();
 }
 
@@ -93,7 +93,7 @@
 TEST_F(StartupControllerTest, DefersAfterFirstSetupComplete) {
   sync_prefs()->SetFirstSetupComplete();
   SetCanStart(true);
-  controller()->TryStart();
+  controller()->TryStart(/*force_immediate=*/false);
   ExpectStartDeferred();
 }
 
@@ -110,7 +110,7 @@
 TEST_F(StartupControllerTest, DataTypeTriggerInterruptsDeferral) {
   sync_prefs()->SetFirstSetupComplete();
   SetCanStart(true);
-  controller()->TryStart();
+  controller()->TryStart(/*force_immediate=*/false);
   ExpectStartDeferred();
 
   controller()->OnDataTypeRequestsSyncStartup(SESSIONS);
@@ -128,7 +128,7 @@
 TEST_F(StartupControllerTest, FallbackTimer) {
   sync_prefs()->SetFirstSetupComplete();
   SetCanStart(true);
-  controller()->TryStart();
+  controller()->TryStart(/*force_immediate=*/false);
   ExpectStartDeferred();
 
   base::RunLoop().RunUntilIdle();
@@ -147,14 +147,14 @@
 
   sync_prefs()->SetFirstSetupComplete();
   SetCanStart(true);
-  controller()->TryStart();
+  controller()->TryStart(/*force_immediate=*/false);
   ExpectStarted();
 }
 
 // Sanity check that the fallback timer doesn't fire before startup
 // conditions are met.
 TEST_F(StartupControllerTest, FallbackTimerWaits) {
-  controller()->TryStart();
+  controller()->TryStart(/*force_immediate=*/false);
   ExpectNotStarted();
   base::RunLoop().RunUntilIdle();
   ExpectNotStarted();
@@ -164,7 +164,7 @@
 TEST_F(StartupControllerTest, NoDeferralSetupInProgressTrigger) {
   sync_prefs()->SetFirstSetupComplete();
   SetCanStart(true);
-  controller()->SetSetupInProgress(true);
+  controller()->TryStart(/*force_immediate=*/true);
   ExpectStarted();
 }
 
@@ -173,32 +173,21 @@
 TEST_F(StartupControllerTest, SetupInProgressTriggerInterruptsDeferral) {
   sync_prefs()->SetFirstSetupComplete();
   SetCanStart(true);
-  controller()->TryStart();
+  controller()->TryStart(/*force_immediate=*/false);
   ExpectStartDeferred();
 
-  controller()->SetSetupInProgress(true);
+  controller()->TryStart(/*force_immediate=*/true);
   ExpectStarted();
 }
 
-// Test that immediate startup can be forced.
-TEST_F(StartupControllerTest, ForceImmediateStartup) {
+// Test that deferred startup and the FirstSetupComplete check can be bypassed.
+TEST_F(StartupControllerTest, BypassDeferredStartupAndSetupCompleteCheck) {
   SetCanStart(true);
-  controller()->TryStartImmediately();
+  controller()->SetBypassSetupCompleteAndDeferredStartup();
+  ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());
+  ExpectNotStarted();
+  controller()->TryStart(/*force_immediate=*/false);
   ExpectStarted();
 }
 
-// Test that setup-in-progress tracking is persistent across a Reset.
-TEST_F(StartupControllerTest, ResetDuringSetup) {
-  SetCanStart(true);
-
-  // Simulate UI telling us setup is in progress.
-  controller()->SetSetupInProgress(true);
-
-  // This could happen if the UI triggers a stop-syncing permanently call.
-  controller()->Reset();
-
-  // From the UI's point of view, setup is still in progress.
-  EXPECT_TRUE(controller()->IsSetupInProgress());
-}
-
 }  // namespace syncer
diff --git a/components/sync/driver/sync_service_crypto.cc b/components/sync/driver/sync_service_crypto.cc
index 9f7b641..b85865a9 100644
--- a/components/sync/driver/sync_service_crypto.cc
+++ b/components/sync/driver/sync_service_crypto.cc
@@ -344,6 +344,7 @@
   DVLOG(1) << "Passphrase type changed to " << PassphraseTypeToString(type);
   cached_passphrase_type_ = type;
   cached_explicit_passphrase_time_ = passphrase_time;
+  notify_observers_.Run();
 }
 
 void SyncServiceCrypto::OnLocalSetPassphraseEncryption(
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
index 8adc4653..51e9fba 100644
--- a/components/viz/service/display/gl_renderer.cc
+++ b/components/viz/service/display/gl_renderer.cc
@@ -763,7 +763,12 @@
     format = GLCopyTextureInternalFormat(BackbufferFormat());
   // Verify the format is valid for GLES2's glCopyTexSubImage2D.
   DCHECK(format == GL_ALPHA || format == GL_LUMINANCE ||
-         format == GL_LUMINANCE_ALPHA || format == GL_RGB || format == GL_RGBA)
+         format == GL_LUMINANCE_ALPHA || format == GL_RGB ||
+         format == GL_RGBA ||
+         (output_surface_->context_provider()
+              ->ContextCapabilities()
+              .texture_format_bgra8888 &&
+          format == GL_BGRA_EXT))
       << format;
   return format;
 }
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 6552c76e2..f45f4da 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -832,6 +832,8 @@
     "frame_host/navigator_delegate.h",
     "frame_host/navigator_impl.cc",
     "frame_host/navigator_impl.h",
+    "frame_host/origin_policy_throttle.cc",
+    "frame_host/origin_policy_throttle.h",
     "frame_host/popup_menu_helper_mac.h",
     "frame_host/popup_menu_helper_mac.mm",
     "frame_host/render_frame_host_delegate.cc",
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc
index b2369801..3873d1a 100644
--- a/content/browser/frame_host/navigation_handle_impl.cc
+++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -22,6 +22,7 @@
 #include "content/browser/frame_host/navigation_entry_impl.h"
 #include "content/browser/frame_host/navigator.h"
 #include "content/browser/frame_host/navigator_delegate.h"
+#include "content/browser/frame_host/origin_policy_throttle.h"
 #include "content/browser/frame_host/webui_navigation_throttle.h"
 #include "content/browser/loader/resource_dispatcher_host_impl.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
@@ -1309,6 +1310,9 @@
   AddThrottle(
       MixedContentNavigationThrottle::CreateThrottleForNavigation(this));
 
+  // Handle Origin Policy (if enabled)
+  AddThrottle(OriginPolicyThrottle::MaybeCreateThrottleFor(this));
+
   for (auto& throttle :
        RenderFrameDevToolsAgentHost::CreateNavigationThrottles(this)) {
     AddThrottle(std::move(throttle));
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h
index f11fe8d..fe477a94 100644
--- a/content/browser/frame_host/navigation_handle_impl.h
+++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -160,6 +160,11 @@
   bool IsDownload() override;
   bool IsFormSubmission() override;
 
+  const std::string& origin_policy() const { return origin_policy_; }
+  void set_origin_policy(const std::string& origin_policy) {
+    origin_policy_ = origin_policy;
+  }
+
   // Resume and CancelDeferredNavigation must only be called by the
   // NavigationThrottle that is currently deferring the navigation.
   // |resuming_throttle| and |cancelling_throttle| are the throttles calling
@@ -368,6 +373,10 @@
   // url we're navigating to.
   void SetExpectedProcess(RenderProcessHost* expected_process);
 
+  NavigationThrottle* GetDeferringThrottleForTesting() const {
+    return GetDeferringThrottle();
+  }
+
  private:
   friend class NavigationHandleImplTest;
 
@@ -557,6 +566,9 @@
   // in it.
   int expected_render_process_host_id_;
 
+  // The origin policy that applies to this navigation. Empty if none applies.
+  std::string origin_policy_;
+
   // Whether the navigation is in the middle of a transfer. Set to false when
   // the DidStartProvisionalLoad is received from the new renderer.
   bool is_transferring_;
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index 84789761..4341e823 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -24,6 +24,7 @@
 #include "content/browser/frame_host/navigation_request_info.h"
 #include "content/browser/frame_host/navigator.h"
 #include "content/browser/frame_host/navigator_impl.h"
+#include "content/browser/frame_host/origin_policy_throttle.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/browser/loader/navigation_url_loader.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
@@ -207,13 +208,21 @@
       }
     }
     std::string value = base::StringPrintf(
-        "cause=%s, destination=document, target=%s, site=%s",
+        "cause=\"%s\", destination=\"document\", target=\"%s\", site=\"%s\"",
         has_user_gesture ? "user-activated" : "forced",
         frame_tree_node->IsMainFrame() ? "top-level" : "nested",
         site_value.c_str());
     headers->SetHeaderIfMissing("Sec-Metadata", value);
   }
 
+  // Ask whether we should request a policy.
+  std::string origin_policy_request;
+  if (OriginPolicyThrottle::ShouldRequestOriginPolicy(url,
+                                                      &origin_policy_request)) {
+    headers->SetHeader(net::HttpRequestHeaders::kSecOriginPolicy,
+                       origin_policy_request);
+  }
+
   // Next, set the HTTP Origin if needed.
   if (!NeedsHTTPOrigin(headers, method))
     return;
@@ -1385,7 +1394,13 @@
 
   RenderFrameDevToolsAgentHost::OnNavigationRequestWillBeSent(*this);
 
-  loader_->FollowRedirect(base::nullopt, base::nullopt);
+  base::Optional<net::HttpRequestHeaders> embedder_additional_headers;
+  GetContentClient()->browser()->NavigationRequestRedirected(
+      frame_tree_node_->frame_tree_node_id(), common_params_.url,
+      &embedder_additional_headers);
+
+  loader_->FollowRedirect(base::nullopt,
+                          std::move(embedder_additional_headers));
 }
 
 void NavigationRequest::OnFailureChecksComplete(
@@ -1554,6 +1569,11 @@
          navigation_handle_->IsSameDocument());
   DCHECK(!common_params_.url.SchemeIs(url::kJavaScriptScheme));
 
+  // Send the applicable origin policy (if any) along with the request.
+  // (The policy is fetched by a throttle and is thus available only now.)
+  DCHECK(common_params_.origin_policy.empty());
+  common_params_.origin_policy = navigation_handle_->origin_policy();
+
   // Retrieve the RenderFrameHost that needs to commit the navigation.
   RenderFrameHostImpl* render_frame_host =
       navigation_handle_->GetRenderFrameHost();
diff --git a/content/browser/frame_host/origin_policy_throttle.cc b/content/browser/frame_host/origin_policy_throttle.cc
new file mode 100644
index 0000000..78a32ff
--- /dev/null
+++ b/content/browser/frame_host/origin_policy_throttle.cc
@@ -0,0 +1,244 @@
+// 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/browser/frame_host/origin_policy_throttle.h"
+
+#include "base/feature_list.h"
+#include "base/no_destructor.h"
+#include "content/browser/frame_host/navigation_handle_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/network_service_instance.h"
+#include "content/public/common/content_features.h"
+#include "net/http/http_request_headers.h"
+#include "services/network/network_context.h"
+#include "services/network/network_service.h"
+#include "services/network/public/cpp/simple_url_loader.h"
+#include "url/origin.h"
+
+namespace {
+// Constants derived from the spec, https://github.com/WICG/origin-policy
+static const char* kDefaultPolicy = "1";
+static const char* kDeletePolicy = "0";
+static const char* kWellKnown = "/.well-known/origin-policy/";
+
+// Maximum policy size (implementation-defined limit in bytes).
+// (Limit copied from network::SimpleURLLoader::kMaxBoundedStringDownloadSize.)
+static const size_t kMaxPolicySize = 1024 * 1024;
+}  // namespace
+
+namespace content {
+
+// static
+bool OriginPolicyThrottle::ShouldRequestOriginPolicy(
+    const GURL& url,
+    std::string* request_version) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  if (!base::FeatureList::IsEnabled(features::kOriginManifest))
+    return false;
+
+  if (!url.SchemeIs(url::kHttpsScheme))
+    return false;
+
+  if (request_version) {
+    const KnownVersionMap& versions = GetKnownVersions();
+    const auto iter = versions.find(url::Origin::Create(url));
+    *request_version =
+        iter == versions.end() ? std::string(kDefaultPolicy) : iter->second;
+  }
+  return true;
+}
+
+// static
+std::unique_ptr<NavigationThrottle>
+OriginPolicyThrottle::MaybeCreateThrottleFor(NavigationHandle* handle) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  DCHECK(handle);
+
+  // We use presence of the origin policy request header to determine
+  // whether we should create the throttle.
+  if (!handle->GetRequestHeaders().HasHeader(
+          net::HttpRequestHeaders::kSecOriginPolicy))
+    return nullptr;
+
+  DCHECK(base::FeatureList::IsEnabled(features::kOriginManifest));
+  return base::WrapUnique(new OriginPolicyThrottle(handle));
+}
+
+OriginPolicyThrottle::~OriginPolicyThrottle() {}
+
+NavigationThrottle::ThrottleCheckResult
+OriginPolicyThrottle::WillStartRequest() {
+  // TODO(vogelheim): It might be faster in the common case to optimistically
+  //     fetch the policy indicated in the request already here. This would
+  //     be faster if the last known version is the current version, but
+  //     slower (and wasteful of bandwidth) if the server sends us a new
+  //     version. It's unclear how much the upside is, though.
+  return NavigationThrottle::PROCEED;
+}
+
+NavigationThrottle::ThrottleCheckResult
+OriginPolicyThrottle::WillProcessResponse() {
+  DCHECK(navigation_handle());
+
+  // Per spec, Origin Policies are only fetched for https:-requests. So we
+  // should always have HTTP headers at this point.
+  // However, some unit tests generate responses without headers, so we still
+  // need to check.
+  if (!navigation_handle()->GetResponseHeaders())
+    return NavigationThrottle::PROCEED;
+
+  // This determines whether and which policy version applies and fetches it.
+  //
+  // Inputs are the kSecOriginPolicy HTTP header, and the version
+  // we've last seen from this particular origin.
+  //
+  // - header with kDeletePolicy received: No policy applies, and delete the
+  //       last-known policy for this origin.
+  // - header received: Use header version and update last-known policy.
+  // - no header received, last-known version exists: Use last-known version
+  // - no header, no last-known version: No policy applies.
+
+  std::string response_version;
+  bool header_found =
+      navigation_handle()->GetResponseHeaders()->GetNormalizedHeader(
+          net::HttpRequestHeaders::kSecOriginPolicy, &response_version);
+
+  url::Origin origin = GetRequestOrigin();
+  DCHECK(!origin.Serialize().empty());
+  DCHECK(!origin.unique());
+  KnownVersionMap& versions = GetKnownVersions();
+  KnownVersionMap::iterator iter = versions.find(origin);
+
+  // Process policy deletion first!
+  if (header_found && response_version == kDeletePolicy) {
+    if (iter != versions.end())
+      versions.erase(iter);
+    return NavigationThrottle::PROCEED;
+  }
+
+  // No policy applies to this request?
+  if (!header_found && iter == versions.end()) {
+    return NavigationThrottle::PROCEED;
+  }
+
+  if (!header_found)
+    response_version = iter->second;
+  else if (iter == versions.end())
+    versions.insert(std::make_pair(origin, response_version));
+  else
+    iter->second = response_version;
+
+  GURL policy = GURL(origin.Serialize() + kWellKnown + response_version);
+  FetchCallback done =
+      base::BindOnce(&OriginPolicyThrottle::OnTheGloriousPolicyHasArrived,
+                     base::Unretained(this));
+  FetchPolicy(policy, std::move(done));
+  return NavigationThrottle::DEFER;
+}
+
+const char* OriginPolicyThrottle::GetNameForLogging() {
+  return "OriginPolicyThrottle";
+}
+
+// static
+OriginPolicyThrottle::KnownVersionMap&
+OriginPolicyThrottle::GetKnownVersionsForTesting() {
+  return GetKnownVersions();
+}
+
+OriginPolicyThrottle::OriginPolicyThrottle(NavigationHandle* handle)
+    : NavigationThrottle(handle) {}
+
+OriginPolicyThrottle::KnownVersionMap&
+OriginPolicyThrottle::GetKnownVersions() {
+  static base::NoDestructor<KnownVersionMap> map_instance;
+  return *map_instance;
+}
+
+const url::Origin OriginPolicyThrottle::GetRequestOrigin() {
+  return url::Origin::Create(navigation_handle()->GetURL());
+}
+
+void OriginPolicyThrottle::FetchPolicy(const GURL& url, FetchCallback done) {
+  // Obtain a network context from the network service.
+  network::mojom::NetworkContextParamsPtr context_params =
+      network::mojom::NetworkContextParams::New();
+  content::GetNetworkService()->CreateNetworkContext(
+      mojo::MakeRequest(&network_context_ptr_), std::move(context_params));
+
+  // Create URLLoaderFactory
+  network::mojom::URLLoaderFactoryParamsPtr url_loader_factory_params =
+      network::mojom::URLLoaderFactoryParams::New();
+  url_loader_factory_params->process_id = network::mojom::kBrowserProcessId;
+  url_loader_factory_params->is_corb_enabled = false;
+  network_context_ptr_->CreateURLLoaderFactory(
+      mojo::MakeRequest(&url_loader_factory_),
+      std::move(url_loader_factory_params));
+
+  // Create the traffic annotation
+  net::NetworkTrafficAnnotationTag traffic_annotation =
+      net::DefineNetworkTrafficAnnotation("origin_policy_loader", R"(
+        semantics {
+          sender: "Origin Policy URL Loader Throttle"
+          description:
+            "Fetches the Origin Policy with a given version from an origin."
+          trigger:
+            "In case the Origin Policy with a given version does not "
+            "exist in the cache, it is fetched from the origin at a "
+            "well-known location."
+          data:
+            "None, the URL itself contains the origin and Origin Policy "
+            "version."
+          destination: OTHER
+        }
+        policy {
+          cookies_allowed: NO
+          setting: "This feature cannot be disabled by settings. Server "
+            "opt-in or out of this mechanism."
+          policy_exception_justification:
+            "Not implemented, considered not useful."})");
+
+  // Create the SimpleURLLoader for the policy.
+  std::unique_ptr<network::ResourceRequest> policy_request =
+      std::make_unique<network::ResourceRequest>();
+  policy_request->url = url;
+  policy_request->fetch_redirect_mode =
+      network::mojom::FetchRedirectMode::kError;
+  url_loader_ = network::SimpleURLLoader::Create(std::move(policy_request),
+                                                 traffic_annotation);
+  url_loader_->SetAllowHttpErrorResults(false);
+
+  // Start the download, and pass the callback for when we're finished.
+  url_loader_->DownloadToString(url_loader_factory_.get(), std::move(done),
+                                kMaxPolicySize);
+}
+
+void OriginPolicyThrottle::InjectPolicyForTesting(
+    const std::string& policy_content) {
+  OnTheGloriousPolicyHasArrived(std::make_unique<std::string>(policy_content));
+}
+
+void OriginPolicyThrottle::OnTheGloriousPolicyHasArrived(
+    std::unique_ptr<std::string> policy_content) {
+  // Release resources associated with the loading.
+  url_loader_.reset();
+  url_loader_factory_.reset();
+  network_context_ptr_.reset();
+
+  // Fail hard if the policy could not be loaded.
+  if (!policy_content) {
+    CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
+    return;
+  }
+
+  // TODO(vogelheim): Determine whether we need to parse or sanity check
+  //                  the policy content at this point.
+
+  static_cast<NavigationHandleImpl*>(navigation_handle())
+      ->set_origin_policy(*policy_content);
+  Resume();
+}
+
+}  // namespace content
diff --git a/content/browser/frame_host/origin_policy_throttle.h b/content/browser/frame_host/origin_policy_throttle.h
new file mode 100644
index 0000000..ac20004
--- /dev/null
+++ b/content/browser/frame_host/origin_policy_throttle.h
@@ -0,0 +1,86 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_FRAME_HOST_ORIGIN_POLICY_THROTTLE_H_
+#define CONTENT_BROWSER_FRAME_HOST_ORIGIN_POLICY_THROTTLE_H_
+
+#include <map>
+#include <string>
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "content/public/browser/navigation_throttle.h"
+#include "services/network/public/mojom/network_service.mojom.h"
+
+class GURL;
+
+namespace url {
+class Origin;
+}
+namespace network {
+class SimpleURLLoader;
+}  // namespace network
+
+namespace content {
+class NavigationHandle;
+
+// The OriginPolicyThrottle is responsible for deciding whether an origin
+// policy should be fetched, and doing so when that is positive.
+//
+// The intended use is that the navigation request will
+// - call OriginPolicyThrottle::ShouldRequestOriginPolicy to determine whether
+//   a policy should be requested and which version, and should add the
+//   appropriate SecOriginPolicy: header.
+// - call OriginPolicyThrottle::MaybeCreateThrottleFor a given navigation.
+//   This will use presence of the header to decide whether to create a
+//   throttle or not.
+class CONTENT_EXPORT OriginPolicyThrottle : public NavigationThrottle {
+ public:
+  // Determine whether to request a policy (or advertise origin policy
+  // support) and which version.
+  // Returns whether the policy header should be sent. It it returns true,
+  // |version| will contain the policy version to use.
+  static bool ShouldRequestOriginPolicy(const GURL& url, std::string* version);
+
+  // Create a throttle (if the request contains the appropriate header.
+  // The throttle will handle fetching of the policy and updating the
+  // navigation request with the result.
+  static std::unique_ptr<NavigationThrottle> MaybeCreateThrottleFor(
+      NavigationHandle* handle);
+
+  ~OriginPolicyThrottle() override;
+
+  ThrottleCheckResult WillStartRequest() override;
+  ThrottleCheckResult WillProcessResponse() override;
+  const char* GetNameForLogging() override;
+
+  using KnownVersionMap = std::map<url::Origin, std::string>;
+  static KnownVersionMap& GetKnownVersionsForTesting();
+
+  void InjectPolicyForTesting(const std::string& policy_content);
+
+ private:
+  using FetchCallback = base::OnceCallback<void(std::unique_ptr<std::string>)>;
+
+  explicit OriginPolicyThrottle(NavigationHandle* handle);
+
+  static KnownVersionMap& GetKnownVersions();
+
+  const url::Origin GetRequestOrigin();
+  void FetchPolicy(const GURL& url, FetchCallback done);
+  void OnTheGloriousPolicyHasArrived(
+      std::unique_ptr<std::string> policy_content);
+
+  // We may need the SimpleURLLoader to download the policy.
+  // The network context and url loader must be kept alive while the load is
+  // ongoing.
+  network::mojom::NetworkContextPtr network_context_ptr_;
+  network::mojom::URLLoaderFactoryPtr url_loader_factory_;
+  std::unique_ptr<network::SimpleURLLoader> url_loader_;
+
+  DISALLOW_COPY_AND_ASSIGN(OriginPolicyThrottle);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_FRAME_HOST_ORIGIN_POLICY_THROTTLE_H_
diff --git a/content/browser/frame_host/origin_policy_throttle_unittest.cc b/content/browser/frame_host/origin_policy_throttle_unittest.cc
new file mode 100644
index 0000000..e993366
--- /dev/null
+++ b/content/browser/frame_host/origin_policy_throttle_unittest.cc
@@ -0,0 +1,155 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/frame_host/origin_policy_throttle.h"
+
+#include "base/feature_list.h"
+#include "base/macros.h"
+#include "base/test/scoped_feature_list.h"
+#include "content/browser/frame_host/navigation_handle_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/common/content_features.h"
+#include "content/public/test/test_renderer_host.h"
+#include "net/http/http_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class OriginPolicyThrottleTest : public RenderViewHostTestHarness,
+                                 public testing::WithParamInterface<bool> {
+ public:
+  void SetUp() override {
+    // Some tests below should be run with the feature en- and disabled, since
+    // they test the feature functionality when enabled and feature
+    // non-funcionality (that is, that the feature is inert) when disabled.
+    // Hence, we run this test in both variants.
+    features_.InitWithFeatureState(features::kOriginManifest, GetParam());
+
+    RenderViewHostTestHarness::SetUp();
+    OriginPolicyThrottle::GetKnownVersionsForTesting().clear();
+  }
+  void TearDown() override {
+    OriginPolicyThrottle::GetKnownVersionsForTesting().clear();
+    nav_handle_.reset();
+    RenderViewHostTestHarness::TearDown();
+  }
+  bool enabled() {
+    return base::FeatureList::IsEnabled(features::kOriginManifest);
+  }
+
+  void CreateHandleFor(const GURL& url) {
+    net::HttpRequestHeaders headers;
+    if (OriginPolicyThrottle::ShouldRequestOriginPolicy(url, nullptr))
+      headers.SetHeader(net::HttpRequestHeaders::kSecOriginPolicy, "1");
+
+    // Except for url and headers (which are determined by the test case)
+    // all parameters below are cargo-culted from
+    // NavigationHandleImplTest::CreateNavigationHandle.
+    nav_handle_ = NavigationHandleImpl::Create(
+        url,                  // url, as requested by caller
+        std::vector<GURL>(),  // redirect chain
+        static_cast<WebContentsImpl*>(web_contents())
+            ->GetFrameTree()
+            ->root(),            // render_tree_node
+        true,                    // is_renderer_initialized
+        false,                   // is_same_document
+        base::TimeTicks::Now(),  // navigation_start
+        0,                       // pending_nav_entry_id
+        false,                   // started_from_context_menu
+        CSPDisposition::CHECK,   // should_check_main_world_csp
+        false,                   // is_form_submission
+        nullptr,                 // navigation_ui_data
+        "GET",                   // HTTP method
+        headers);                // headers, as created above
+  }
+
+ protected:
+  std::unique_ptr<NavigationHandleImpl> nav_handle_;
+  base::test::ScopedFeatureList features_;
+};
+
+INSTANTIATE_TEST_CASE_P(OriginPolicyThrottleTests,
+                        OriginPolicyThrottleTest,
+                        testing::Bool());
+
+TEST_P(OriginPolicyThrottleTest, ShouldRequestOriginPolicy) {
+  struct {
+    const char* url;
+    bool expect;
+  } test_cases[] = {
+      {"https://example.org/bla", true},
+      {"http://example.org/bla", false},
+      {"file:///etc/passwd", false},
+  };
+
+  for (const auto& test_case : test_cases) {
+    SCOPED_TRACE(testing::Message() << "URL: " << test_case.url);
+    EXPECT_EQ(enabled() && test_case.expect,
+              OriginPolicyThrottle::ShouldRequestOriginPolicy(
+                  GURL(test_case.url), nullptr));
+  }
+}
+
+TEST_P(OriginPolicyThrottleTest, ShouldRequestLastKnownVersion) {
+  if (!enabled())
+    return;
+
+  GURL url("https://example.org/bla");
+  EXPECT_TRUE(OriginPolicyThrottle::ShouldRequestOriginPolicy(url, nullptr));
+
+  std::string version;
+
+  OriginPolicyThrottle::ShouldRequestOriginPolicy(url, &version);
+  EXPECT_EQ(version, "1");
+
+  OriginPolicyThrottle::GetKnownVersionsForTesting()[url::Origin::Create(url)] =
+      "abcd";
+  OriginPolicyThrottle::ShouldRequestOriginPolicy(url, &version);
+  EXPECT_EQ(version, "abcd");
+}
+
+TEST_P(OriginPolicyThrottleTest, MaybeCreateThrottleFor) {
+  CreateHandleFor(GURL("https://example.org/bla"));
+  EXPECT_EQ(enabled(),
+            !!OriginPolicyThrottle::MaybeCreateThrottleFor(nav_handle_.get()));
+
+  CreateHandleFor(GURL("http://insecure.org/bla"));
+  EXPECT_FALSE(
+      !!OriginPolicyThrottle::MaybeCreateThrottleFor(nav_handle_.get()));
+}
+
+TEST_P(OriginPolicyThrottleTest, RunRequestEndToEnd) {
+  if (!enabled())
+    return;
+
+  // Create a handle and start the request.
+  CreateHandleFor(GURL("https://example.org/bla"));
+  EXPECT_EQ(NavigationThrottle::PROCEED,
+            nav_handle_->CallWillStartRequestForTesting().action());
+
+  // Fake a response with a policy header. Check whether the navigation
+  // is deferred.
+  const char* headers = "HTTP/1.1 200 OK\nSec-Origin-Policy: policy-1\n\n";
+  EXPECT_EQ(NavigationThrottle::DEFER,
+            nav_handle_
+                ->CallWillProcessResponseForTesting(
+                    main_rfh(),
+                    net::HttpUtil::AssembleRawHeaders(headers, strlen(headers)))
+                .action());
+  EXPECT_EQ(NavigationHandleImpl::DEFERRING_RESPONSE,
+            nav_handle_->state_for_testing());
+
+  // For the purpose of this unit test we don't care about policy content,
+  // only that it's non-empty. We check whether the throttle will pass it on.
+  const char* policy = "{}";
+  static_cast<OriginPolicyThrottle*>(
+      nav_handle_->GetDeferringThrottleForTesting())
+      ->InjectPolicyForTesting(policy);
+
+  // At the end of the navigation, the navigation handle should have a copy
+  // of the origin policy.
+  EXPECT_EQ(policy, nav_handle_->origin_policy());
+}
+
+}  // namespace content
diff --git a/content/browser/loader/cross_site_document_resource_handler.cc b/content/browser/loader/cross_site_document_resource_handler.cc
index baf23cba..386cf58 100644
--- a/content/browser/loader/cross_site_document_resource_handler.cc
+++ b/content/browser/loader/cross_site_document_resource_handler.cc
@@ -166,6 +166,14 @@
     }
   }
 
+  void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+                             modified_request_headers) override {
+    DCHECK(!modified_request_headers.has_value())
+        << "Redirect with modified headers was not supported yet. "
+           "crbug.com/845683";
+    Resume();
+  }
+
   void Cancel() override {
     MarkAsUsed();
     document_handler_->Cancel();
diff --git a/content/browser/loader/detachable_resource_handler.cc b/content/browser/loader/detachable_resource_handler.cc
index 94147b23..26593e97 100644
--- a/content/browser/loader/detachable_resource_handler.cc
+++ b/content/browser/loader/detachable_resource_handler.cc
@@ -38,6 +38,14 @@
     detachable_handler_->ResumeInternal();
   }
 
+  void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+                             modified_request_headers) override {
+    DCHECK(!modified_request_headers.has_value())
+        << "Redirect with modified headers was not supported yet. "
+           "crbug.com/845683";
+    Resume();
+  }
+
   void Cancel() override {
     MarkAsUsed();
     detachable_handler_->Cancel();
diff --git a/content/browser/loader/intercepting_resource_handler.cc b/content/browser/loader/intercepting_resource_handler.cc
index 0b038d2..a7c3a10 100644
--- a/content/browser/loader/intercepting_resource_handler.cc
+++ b/content/browser/loader/intercepting_resource_handler.cc
@@ -29,6 +29,14 @@
     intercepting_handler_->ResumeInternal();
   }
 
+  void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+                             modified_request_headers) override {
+    DCHECK(!modified_request_headers.has_value())
+        << "Redirect with modified headers was not supported yet. "
+           "crbug.com/845683";
+    Resume();
+  }
+
   void Cancel() override {
     MarkAsUsed();
     intercepting_handler_->Cancel();
diff --git a/content/browser/loader/mime_sniffing_resource_handler.cc b/content/browser/loader/mime_sniffing_resource_handler.cc
index b67153f..89e2c53 100644
--- a/content/browser/loader/mime_sniffing_resource_handler.cc
+++ b/content/browser/loader/mime_sniffing_resource_handler.cc
@@ -74,6 +74,14 @@
     mime_handler_->ResumeInternal();
   }
 
+  void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+                             modified_request_headers) override {
+    DCHECK(!modified_request_headers.has_value())
+        << "Redirect with modified headers was not supported yet. "
+           "crbug.com/845683";
+    Resume();
+  }
+
   void Cancel() override {
     MarkAsUsed();
     mime_handler_->Cancel();
diff --git a/content/browser/loader/mock_resource_loader.cc b/content/browser/loader/mock_resource_loader.cc
index 7444b0a..e43c857 100644
--- a/content/browser/loader/mock_resource_loader.cc
+++ b/content/browser/loader/mock_resource_loader.cc
@@ -10,6 +10,7 @@
 #include "content/browser/loader/resource_controller.h"
 #include "content/browser/loader/resource_handler.h"
 #include "net/base/io_buffer.h"
+#include "net/http/http_request_headers.h"
 #include "net/url_request/url_request_status.h"
 #include "services/network/public/cpp/resource_response.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -24,6 +25,14 @@
 
   void Resume() override { mock_loader_->OnResume(); }
 
+  void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+                             modified_request_headers) override {
+    DCHECK(!modified_request_headers.has_value())
+        << "Redirect with modified headers was not supported yet. "
+           "crbug.com/845683";
+    Resume();
+  }
+
   void Cancel() override { CancelWithError(net::ERR_ABORTED); }
 
   void CancelWithError(int error_code) override {
diff --git a/content/browser/loader/mojo_async_resource_handler.cc b/content/browser/loader/mojo_async_resource_handler.cc
index cadfcff6..55c8d8e0 100644
--- a/content/browser/loader/mojo_async_resource_handler.cc
+++ b/content/browser/loader/mojo_async_resource_handler.cc
@@ -349,9 +349,6 @@
     const base::Optional<std::vector<std::string>>&
         to_be_removed_request_headers,
     const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
-  DCHECK(!modified_request_headers.has_value()) << "Redirect with modified "
-                                                   "headers was not supported "
-                                                   "yet. crbug.com/845683";
   if (!request()->status().is_success()) {
     DVLOG(1) << "FollowRedirect for invalid request";
     return;
@@ -366,7 +363,7 @@
   DCHECK(!did_defer_on_writing_);
   did_defer_on_redirect_ = false;
   request()->LogUnblocked();
-  Resume();
+  ResumeForRedirect(modified_request_headers);
 }
 
 void MojoAsyncResourceHandler::ProceedWithResponse() {
diff --git a/content/browser/loader/null_resource_controller.cc b/content/browser/loader/null_resource_controller.cc
index da79bb5..8ac719d3 100644
--- a/content/browser/loader/null_resource_controller.cc
+++ b/content/browser/loader/null_resource_controller.cc
@@ -5,6 +5,7 @@
 #include "content/browser/loader/null_resource_controller.h"
 
 #include "base/logging.h"
+#include "net/http/http_request_headers.h"
 
 namespace content {
 
@@ -27,4 +28,12 @@
   *was_resumed_ = true;
 }
 
+void NullResourceController::ResumeForRedirect(
+    const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
+  DCHECK(!modified_request_headers.has_value()) << "Redirect with modified "
+                                                   "headers was not supported "
+                                                   "yet. crbug.com/845683";
+  Resume();
+}
+
 }  // namespace content
diff --git a/content/browser/loader/null_resource_controller.h b/content/browser/loader/null_resource_controller.h
index 8dd10f7..66c9e03 100644
--- a/content/browser/loader/null_resource_controller.h
+++ b/content/browser/loader/null_resource_controller.h
@@ -23,6 +23,8 @@
   void Cancel() override;
   void CancelWithError(int error_code) override;
   void Resume() override;
+  void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+                             modified_request_headers) override;
 
  private:
   bool* was_resumed_;
diff --git a/content/browser/loader/resource_controller.h b/content/browser/loader/resource_controller.h
index 8278534..55ecd8c 100644
--- a/content/browser/loader/resource_controller.h
+++ b/content/browser/loader/resource_controller.h
@@ -5,8 +5,13 @@
 #ifndef CONTENT_BROWSER_LOADER_RESOURCE_CONTROLLER_H_
 #define CONTENT_BROWSER_LOADER_RESOURCE_CONTROLLER_H_
 
+#include "base/optional.h"
 #include "content/common/content_export.h"
 
+namespace net {
+class HttpRequestHeaders;
+};
+
 namespace content {
 
 // Used to either resume a deferred resource load or cancel a resource load at
@@ -25,6 +30,12 @@
   // deferred. Guaranteed not to call back into the ResourceHandler, or destroy
   // it, synchronously.
   virtual void Resume() = 0;
+
+  // Similar to |Resume()| but can only be called if the request was previously
+  // redirected. |modified_request_headers| are changes applied to the request
+  // headers after updating them for the redirect.
+  virtual void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+                                     modified_request_headers) = 0;
 };
 
 }  // namespace content
diff --git a/content/browser/loader/resource_handler.cc b/content/browser/loader/resource_handler.cc
index a507567..c58d7641e 100644
--- a/content/browser/loader/resource_handler.cc
+++ b/content/browser/loader/resource_handler.cc
@@ -44,6 +44,11 @@
   ReleaseController()->Resume();
 }
 
+void ResourceHandler::ResumeForRedirect(
+    const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
+  ReleaseController()->ResumeForRedirect(modified_request_headers);
+}
+
 void ResourceHandler::Cancel() {
   ReleaseController()->Cancel();
 }
diff --git a/content/browser/loader/resource_handler.h b/content/browser/loader/resource_handler.h
index 1fac771..bb60dbe0 100644
--- a/content/browser/loader/resource_handler.h
+++ b/content/browser/loader/resource_handler.h
@@ -159,6 +159,8 @@
   // These call the corresponding methods on the ResourceController previously
   // passed to HoldController and then destroy it.
   void Resume();
+  void ResumeForRedirect(
+      const base::Optional<net::HttpRequestHeaders>& modified_request_headers);
   void Cancel();
   void CancelWithError(int error_code);
 
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc
index 41150370..95eaa9c 100644
--- a/content/browser/loader/resource_loader.cc
+++ b/content/browser/loader/resource_loader.cc
@@ -155,7 +155,15 @@
   // ResourceController implementation:
   void Resume() override {
     MarkAsUsed();
-    resource_loader_->Resume(true /* called_from_resource_controller */);
+    resource_loader_->Resume(true /* called_from_resource_controller */,
+                             base::nullopt);
+  }
+
+  void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+                             modified_request_headers) override {
+    MarkAsUsed();
+    resource_loader_->Resume(true /* called_from_resource_controller */,
+                             modified_request_headers);
   }
 
   void Cancel() override {
@@ -212,7 +220,8 @@
     // If Resume() was called, it just advanced the state without doing
     // anything. Go ahead and resume the request now.
     if (old_deferred_stage == DEFERRED_NONE)
-      resource_loader_->Resume(false /* called_from_resource_controller */);
+      resource_loader_->Resume(false /* called_from_resource_controller */,
+                               base::nullopt);
   }
 
  private:
@@ -521,9 +530,13 @@
   request_->CancelWithError(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
 }
 
-void ResourceLoader::Resume(bool called_from_resource_controller) {
+void ResourceLoader::Resume(
+    bool called_from_resource_controller,
+    const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
   DeferredStage stage = deferred_stage_;
   deferred_stage_ = DEFERRED_NONE;
+  DCHECK(!modified_request_headers.has_value() || stage == DEFERRED_REDIRECT)
+      << "modified_request_headers can only be used with redirects";
   switch (stage) {
     case DEFERRED_NONE:
       NOTREACHED();
@@ -542,7 +555,7 @@
       // URLRequest::Start completes asynchronously, so starting the request now
       // won't result in synchronously calling into a ResourceHandler, if this
       // was called from Resume().
-      FollowDeferredRedirectInternal();
+      FollowDeferredRedirectInternal(modified_request_headers);
       break;
     case DEFERRED_ON_WILL_READ:
       // Always post a task, as synchronous resumes don't go through this
@@ -670,15 +683,18 @@
   }
 }
 
-void ResourceLoader::FollowDeferredRedirectInternal() {
+void ResourceLoader::FollowDeferredRedirectInternal(
+    const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
   DCHECK(!deferred_redirect_url_.is_empty());
   GURL redirect_url = deferred_redirect_url_;
   deferred_redirect_url_ = GURL();
   if (delegate_->HandleExternalProtocol(this, redirect_url)) {
+    DCHECK(!modified_request_headers.has_value())
+        << "ResourceLoaderDelegate::HandleExternalProtocol() with modified "
+           "headers was not supported yet. crbug.com/845683";
     Cancel();
   } else {
-    request_->FollowDeferredRedirect(
-        base::nullopt /* modified_request_headers */);
+    request_->FollowDeferredRedirect(modified_request_headers);
   }
 }
 
diff --git a/content/browser/loader/resource_loader.h b/content/browser/loader/resource_loader.h
index 3830cd4..9fef84a 100644
--- a/content/browser/loader/resource_loader.h
+++ b/content/browser/loader/resource_loader.h
@@ -98,14 +98,17 @@
   // |called_from_resource_controller| is true if called directly from a
   // ResourceController, in which case |resource_handler_| must not be invoked
   // or destroyed synchronously to avoid re-entrancy issues, and false
-  // otherwise.
-  void Resume(bool called_from_resource_controller);
+  // otherwise. |modified_request_headers| is used for redirects only.
+  void Resume(
+      bool called_from_resource_controller,
+      const base::Optional<net::HttpRequestHeaders>& modified_request_headers);
   void Cancel();
   void CancelWithError(int error_code);
 
   void StartRequestInternal();
   void CancelRequestInternal(int error, bool from_renderer);
-  void FollowDeferredRedirectInternal();
+  void FollowDeferredRedirectInternal(
+      const base::Optional<net::HttpRequestHeaders>& modified_request_headers);
   void CompleteResponseStarted();
   // If |handle_result_async| is true, the result of the following read will be
   // handled asynchronously if it completes synchronously, unless it's EOF or an
diff --git a/content/browser/media/media_autoplay_browsertest.cc b/content/browser/media/media_autoplay_browsertest.cc
new file mode 100644
index 0000000..bb03034f
--- /dev/null
+++ b/content/browser/media/media_autoplay_browsertest.cc
@@ -0,0 +1,66 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/path_service.h"
+#include "content/common/media/media_player_delegate_messages.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/common/content_paths.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+
+namespace content {
+
+namespace {
+
+class WaitForMediaPlaying : public WebContentsObserver {
+ public:
+  WaitForMediaPlaying(WebContents* web_contents)
+      : WebContentsObserver(web_contents) {}
+
+  // WebContentsObserver override.
+  void MediaStartedPlaying(const MediaPlayerInfo&, const MediaPlayerId&) final {
+    run_loop_.Quit();
+  }
+
+  void Wait() { run_loop_.Run(); }
+
+ private:
+  base::RunLoop run_loop_;
+
+  DISALLOW_COPY_AND_ASSIGN(WaitForMediaPlaying);
+};
+
+}  // namespace
+
+class MediaAutoplayTest : public ContentBrowserTest {
+ public:
+  void SetUpOnMainThread() override {
+    ContentBrowserTest::SetUpOnMainThread();
+
+    base::FilePath test_data_dir;
+    ASSERT_TRUE(base::PathService::Get(content::DIR_TEST_DATA, &test_data_dir));
+    embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
+    ASSERT_TRUE(embedded_test_server()->Start());
+  }
+};
+
+// Test that playing a player from an IPC does not lead to a crash the renderer.
+// This is a regression test from a crash from autoplay_initiated_ not being set
+// in the Blink's AutoplayPolicy.
+IN_PROC_BROWSER_TEST_F(MediaAutoplayTest, Crash_AutoplayInitiated) {
+  NavigateToURL(shell(),
+                embedded_test_server()->GetURL("/media/video-player.html"));
+
+  WaitForMediaPlaying wait_for_media_playing(shell()->web_contents());
+
+  RenderFrameHost* main_frame = shell()->web_contents()->GetMainFrame();
+  main_frame->Send(
+      new MediaPlayerDelegateMsg_Play(main_frame->GetRoutingID(), 1));
+
+  wait_for_media_playing.Wait();
+}
+
+}  // namespace content
diff --git a/content/browser/notifications/notification_database_data_conversions.cc b/content/browser/notifications/notification_database_data_conversions.cc
index 9fa6169..656108ca 100644
--- a/content/browser/notifications/notification_database_data_conversions.cc
+++ b/content/browser/notifications/notification_database_data_conversions.cc
@@ -83,6 +83,8 @@
   if (payload.vibration_pattern().size() > 0) {
     notification_data->vibration_pattern.assign(
         payload.vibration_pattern().begin(), payload.vibration_pattern().end());
+  } else {
+    notification_data->vibration_pattern.clear();
   }
 
   notification_data->timestamp =
@@ -94,8 +96,12 @@
   if (payload.data().length()) {
     notification_data->data.assign(payload.data().begin(),
                                    payload.data().end());
+  } else {
+    notification_data->data.clear();
   }
 
+  notification_data->actions.clear();
+
   for (const auto& payload_action : payload.actions()) {
     PlatformNotificationAction action;
 
diff --git a/content/browser/notifications/notification_database_data_unittest.cc b/content/browser/notifications/notification_database_data_unittest.cc
index 6436f40..9de61d5 100644
--- a/content/browser/notifications/notification_database_data_unittest.cc
+++ b/content/browser/notifications/notification_database_data_unittest.cc
@@ -170,6 +170,34 @@
   }
 }
 
+TEST(NotificationDatabaseDataTest, ActionDeserializationIsNotAdditive) {
+  NotificationDatabaseData database_data;
+
+  for (size_t i = 0; i < blink::kWebNotificationMaxActions; ++i)
+    database_data.notification_data.actions.emplace_back();
+
+  std::string serialized_data;
+  NotificationDatabaseData copied_database_data;
+
+  // Serialize the data in |notification_data| to the string |serialized_data|,
+  // and then deserialize it again immediately to |copied_database_data|.
+  ASSERT_TRUE(
+      SerializeNotificationDatabaseData(database_data, &serialized_data));
+  ASSERT_TRUE(DeserializeNotificationDatabaseData(serialized_data,
+                                                  &copied_database_data));
+
+  EXPECT_EQ(copied_database_data.notification_data.actions.size(),
+            blink::kWebNotificationMaxActions);
+
+  // Deserialize it again in the same |copied_database_data|. The number of
+  // actions in the structure should not be affected.
+  ASSERT_TRUE(DeserializeNotificationDatabaseData(serialized_data,
+                                                  &copied_database_data));
+
+  EXPECT_EQ(copied_database_data.notification_data.actions.size(),
+            blink::kWebNotificationMaxActions);
+}
+
 TEST(NotificationDatabaseDataTest, SerializeAndDeserializeActionTypes) {
   PlatformNotificationActionType action_types[] = {
       PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON,
@@ -222,7 +250,7 @@
   }
 }
 
-TEST(NotificationDatabaseDataTest, SerializeAndDeserializeclosed_reasons) {
+TEST(NotificationDatabaseDataTest, SerializeAndDeserializeClosedReasons) {
   NotificationDatabaseData::ClosedReason closed_reasons[] = {
       NotificationDatabaseData::ClosedReason::USER,
       NotificationDatabaseData::ClosedReason::DEVELOPER,
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index ac367a6..5bf9580 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1151,8 +1151,19 @@
     // |visual_properties_ack_pending_| and make sure the next resize will be
     // acked if the last resize before navigation was supposed to be acked.
     visual_properties_ack_pending_ = false;
+    viz::LocalSurfaceId old_surface_id = view_->GetLocalSurfaceId();
     if (view_)
       view_->DidNavigate();
+    viz::LocalSurfaceId new_surface_id = view_->GetLocalSurfaceId();
+    // If |view_| didn't allocate a new surface id, then don't start
+    // |new_content_rendering_timeout_|. Two reasons:
+    //  1. It's not needed (because this was the first navigation event)
+    //  2. If we don't change the surface id, then we will not get the call to
+    //     OnFirstSurfaceActivation, and not stop the timer (even if we get new
+    //     frames).
+    // https://crbug.com/853651, https://crbug.com/535375
+    if (old_surface_id == new_surface_id)
+      return;
   } else {
     // It is possible for a compositor frame to arrive before the browser is
     // notified about the page being committed, in which case no timer is
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 7f532ea..3485834 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
@@ -428,7 +428,7 @@
     new_content_rendering_timeout_fired_ = true;
   }
 
-  bool new_content_rendering_timeout_fired_;
+  bool new_content_rendering_timeout_fired_ = false;
   std::unique_ptr<MockWidgetImpl> widget_impl_;
 };
 
@@ -6306,8 +6306,8 @@
   viz::LocalSurfaceId id0 = view_->GetLocalSurfaceId();
   EXPECT_TRUE(id0.is_valid());
 
-  // No new LocalSurfaceId should be allocated for the first navigation but the
-  // timer should fire.
+  // No new LocalSurfaceId should be allocated for the first navigation and the
+  // timer should not fire.
   widget_host_->DidNavigate(1);
   viz::LocalSurfaceId id1 = view_->GetLocalSurfaceId();
   EXPECT_EQ(id0, id1);
@@ -6317,7 +6317,15 @@
         FROM_HERE, run_loop.QuitClosure(), 2 * kTimeout);
     run_loop.Run();
   }
-  EXPECT_TRUE(widget_host_->new_content_rendering_timeout_fired());
+  if (base::FeatureList::IsEnabled(features::kEnableSurfaceSynchronization)) {
+    // When using surface sync, the timer should not fire, because the surface
+    // id did not change.
+    EXPECT_FALSE(widget_host_->new_content_rendering_timeout_fired());
+  } else {
+    // When not using surface sync, the timer will fire because the source id
+    // changed.
+    EXPECT_TRUE(widget_host_->new_content_rendering_timeout_fired());
+  }
   widget_host_->reset_new_content_rendering_timeout_fired();
 
   // Start the timer. Verify that a new LocalSurfaceId is allocated.
diff --git a/content/browser/snapshot_browsertest.cc b/content/browser/snapshot_browsertest.cc
index 51bf6624..e423822 100644
--- a/content/browser/snapshot_browsertest.cc
+++ b/content/browser/snapshot_browsertest.cc
@@ -252,11 +252,9 @@
 //   Linux Chromium OS ASAN LSAN Tests (1)
 //   Linux TSAN Tests
 // See crbug.com/771119
-// It's also flaky on Mac, see crbug.com/853651.
 #if (defined(OS_WIN) && !defined(NDEBUG)) ||                \
     (defined(OS_CHROMEOS) && defined(ADDRESS_SANITIZER)) || \
-    (defined(OS_LINUX) && defined(THREAD_SANITIZER)) ||     \
-    defined(OS_MACOSX)
+    (defined(OS_LINUX) && defined(THREAD_SANITIZER))
 #define MAYBE_SyncMultiWindowTest DISABLED_SyncMultiWindowTest
 #define MAYBE_AsyncMultiWindowTest DISABLED_AsyncMultiWindowTest
 #else
diff --git a/content/browser/speech/speech_recognition_dispatcher_host.cc b/content/browser/speech/speech_recognition_dispatcher_host.cc
index 24f5b22..4e8664e 100644
--- a/content/browser/speech/speech_recognition_dispatcher_host.cc
+++ b/content/browser/speech/speech_recognition_dispatcher_host.cc
@@ -200,9 +200,15 @@
     blink::mojom::SpeechRecognitionSessionClientPtrInfo client_ptr_info)
     : session_id_(SpeechRecognitionManager::kSessionIDInvalid),
       client_(std::move(client_ptr_info)),
+      stopped_(false),
       weak_factory_(this) {}
 
-SpeechRecognitionSession::~SpeechRecognitionSession() = default;
+SpeechRecognitionSession::~SpeechRecognitionSession() {
+  // If a connection error happens and the session hasn't been stopped yet,
+  // abort it.
+  if (!stopped_)
+    Abort();
+}
 
 base::WeakPtr<SpeechRecognitionSession> SpeechRecognitionSession::AsWeakPtr() {
   return weak_factory_.GetWeakPtr();
@@ -210,11 +216,13 @@
 
 void SpeechRecognitionSession::Abort() {
   SpeechRecognitionManager::GetInstance()->AbortSession(session_id_);
+  stopped_ = true;
 }
 
 void SpeechRecognitionSession::StopCapture() {
   SpeechRecognitionManager::GetInstance()->StopAudioCaptureForSession(
       session_id_);
+  stopped_ = true;
 }
 
 // -------- SpeechRecognitionEventListener interface implementation -----------
@@ -241,6 +249,8 @@
 
 void SpeechRecognitionSession::OnRecognitionEnd(int session_id) {
   client_->Ended();
+  stopped_ = true;
+  client_.reset();
 }
 
 void SpeechRecognitionSession::OnRecognitionResults(
diff --git a/content/browser/speech/speech_recognition_dispatcher_host.h b/content/browser/speech/speech_recognition_dispatcher_host.h
index b47238f2..ffa9bd51 100644
--- a/content/browser/speech/speech_recognition_dispatcher_host.h
+++ b/content/browser/speech/speech_recognition_dispatcher_host.h
@@ -111,6 +111,7 @@
  private:
   int session_id_;
   blink::mojom::SpeechRecognitionSessionClientPtr client_;
+  bool stopped_;
 
   base::WeakPtrFactory<SpeechRecognitionSession> weak_factory_;
 };
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index fc11344..85127be2 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -480,6 +480,7 @@
   IPC_STRUCT_TRAITS_MEMBER(started_from_context_menu)
   IPC_STRUCT_TRAITS_MEMBER(initiator_csp)
   IPC_STRUCT_TRAITS_MEMBER(initiator_self_source)
+  IPC_STRUCT_TRAITS_MEMBER(origin_policy)
 IPC_STRUCT_TRAITS_END()
 
 IPC_STRUCT_TRAITS_BEGIN(content::NavigationTiming)
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h
index 5ce8be8..08a7d0cf 100644
--- a/content/common/navigation_params.h
+++ b/content/common/navigation_params.h
@@ -156,6 +156,10 @@
   // We require a copy of the relevant CSP to perform navigation checks.
   std::vector<ContentSecurityPolicy> initiator_csp;
   base::Optional<CSPSource> initiator_self_source;
+
+  // The current origin policy for this request's origin.
+  // (Empty if none applies.)
+  std::string origin_policy;
 };
 
 // Provided by the browser -----------------------------------------------------
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 84c1197..4fd495cc 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -470,6 +470,14 @@
       std::unique_ptr<net::HttpRequestHeaders>* extra_headers,
       int* extra_load_flags) {}
 
+  // Allow the embedder to modify headers for a redirect. If non-nullopt,
+  // |*modified_request_headers| are applied to the request headers after
+  // updating them for the redirect.
+  virtual void NavigationRequestRedirected(
+      int frame_tree_node_id,
+      const GURL& url,
+      base::Optional<net::HttpRequestHeaders>* modified_request_headers) {}
+
   // Allow the embedder to control if the given cookie can be read.
   // This is called on the IO thread.
   virtual bool AllowGetCookie(const GURL& url,
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index bb97586..488548e 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -607,8 +607,6 @@
     "shared_worker/shared_worker_repository.h",
     "skia_benchmarking_extension.cc",
     "skia_benchmarking_extension.h",
-    "speech_recognition_dispatcher.cc",
-    "speech_recognition_dispatcher.h",
     "stats_collection_controller.cc",
     "stats_collection_controller.h",
     "stats_collection_observer.cc",
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 28c643ff..8f6bc46 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -148,7 +148,6 @@
 #include "content/renderer/service_worker/worker_fetch_context_impl.h"
 #include "content/renderer/shared_worker/shared_worker_repository.h"
 #include "content/renderer/skia_benchmarking_extension.h"
-#include "content/renderer/speech_recognition_dispatcher.h"
 #include "content/renderer/stats_collection_controller.h"
 #include "content/renderer/v8_value_converter_impl.h"
 #include "content/renderer/web_frame_utils.h"
@@ -466,6 +465,8 @@
   request.SetPreviewsState(
       static_cast<WebURLRequest::PreviewsState>(common_params.previews_state));
 
+  request.SetOriginPolicy(WebString::FromUTF8(common_params.origin_policy));
+
   auto extra_data = std::make_unique<RequestExtraData>();
   extra_data->set_navigation_response_override(std::move(response_override));
   extra_data->set_navigation_initiated_by_renderer(
@@ -3808,14 +3809,11 @@
     blink::WebDocumentLoader* document_loader) {
   bool content_initiated = !pending_navigation_params_.get();
 
-  DocumentState* document_state =
-      DocumentState::FromDocumentLoader(document_loader);
-  if (!document_state) {
-    document_state = new DocumentState;
-    document_loader->SetExtraData(document_state);
-    if (!content_initiated)
-      PopulateDocumentStateFromPending(document_state);
-  }
+  DCHECK(!DocumentState::FromDocumentLoader(document_loader));
+  DocumentState* document_state = new DocumentState;
+  document_loader->SetExtraData(document_state);
+  if (!content_initiated)
+    PopulateDocumentStateFromPending(document_state);
 
   // Carry over the user agent override flag, if it exists.
   // TODO(lukasza): https://crbug.com/426555: Need OOPIF support for propagating
@@ -4346,13 +4344,6 @@
     return;
   RecordSuffixedRendererMemoryMetrics(memory_metrics,
                                       ".MainFrameDidFinishLoad");
-  // TODO(falken): Filter out no fetch controllers. This UMA probably didn't
-  // intend to log them.
-  if (IsControlledByServiceWorker() ==
-      blink::mojom::ControllerServiceWorkerMode::kNoController)
-    return;
-  RecordSuffixedRendererMemoryMetrics(
-      memory_metrics, ".ServiceWorkerControlledMainFrameDidFinishLoad");
 }
 
 void RenderFrameImpl::DidFinishSameDocumentNavigation(
@@ -6989,12 +6980,6 @@
           .device_status());
 }
 
-blink::WebSpeechRecognizer* RenderFrameImpl::SpeechRecognizer() {
-  if (!speech_recognition_dispatcher_)
-    speech_recognition_dispatcher_ = new SpeechRecognitionDispatcher(this);
-  return speech_recognition_dispatcher_;
-}
-
 blink::mojom::PageVisibilityState RenderFrameImpl::VisibilityState() const {
   const RenderFrameImpl* local_root = GetLocalRoot();
   blink::mojom::PageVisibilityState current_state =
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 542343e..17d323e1 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -117,7 +117,6 @@
 class WebPushClient;
 class WebRelatedAppsFetcher;
 class WebSecurityOrigin;
-class WebSpeechRecognizer;
 struct FramePolicy;
 struct WebContextMenuData;
 struct WebCursorInfo;
@@ -170,7 +169,6 @@
 class RenderWidget;
 class RenderWidgetFullscreenPepper;
 class SharedWorkerRepository;
-class SpeechRecognitionDispatcher;
 class UserMediaClientImpl;
 struct CSPViolationParams;
 struct CommonNavigationParams;
@@ -746,7 +744,6 @@
   void CheckIfAudioSinkExistsAndIsAuthorized(
       const blink::WebString& sink_id,
       blink::WebSetSinkIdCallbacks* web_callbacks) override;
-  blink::WebSpeechRecognizer* SpeechRecognizer() override;
   blink::mojom::PageVisibilityState VisibilityState() const override;
   std::unique_ptr<blink::WebURLLoaderFactory> CreateURLLoaderFactory() override;
   void DraggableRegionsChanged() override;
@@ -1479,11 +1476,6 @@
   // process.
   std::unique_ptr<ManifestManager> manifest_manager_;
 
-  // The speech recognition dispatcher attached to this frame, lazily
-  // initialized. It is an observer of this frame, owning itself and managing
-  // its own lifetime.
-  SpeechRecognitionDispatcher* speech_recognition_dispatcher_ = nullptr;
-
   // The current accessibility mode.
   ui::AXMode accessibility_mode_;
 
diff --git a/content/renderer/speech_recognition_dispatcher.cc b/content/renderer/speech_recognition_dispatcher.cc
deleted file mode 100644
index 3226a568..0000000
--- a/content/renderer/speech_recognition_dispatcher.cc
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/speech_recognition_dispatcher.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <utility>
-
-#include "base/strings/utf_string_conversions.h"
-#include "build/build_config.h"
-#include "content/public/common/service_names.mojom.h"
-#include "content/public/renderer/render_thread.h"
-#include "content/renderer/render_frame_impl.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/public/web/web_speech_grammar.h"
-#include "third_party/blink/public/web/web_speech_recognition_params.h"
-#include "third_party/blink/public/web/web_speech_recognition_result.h"
-
-using blink::WebVector;
-using blink::WebString;
-using blink::WebSpeechGrammar;
-using blink::WebSpeechRecognitionHandle;
-using blink::WebSpeechRecognitionResult;
-using blink::WebSpeechRecognitionParams;
-using blink::WebSpeechRecognizerClient;
-
-namespace content {
-
-SpeechRecognitionDispatcher::SpeechRecognitionDispatcher(
-    RenderFrame* render_frame)
-    : RenderFrameObserver(render_frame) {}
-
-SpeechRecognitionDispatcher::~SpeechRecognitionDispatcher() = default;
-
-void SpeechRecognitionDispatcher::OnDestruct() {
-  delete this;
-}
-
-void SpeechRecognitionDispatcher::WasHidden() {
-#if defined(OS_ANDROID)
-  for (const auto& it : session_map_) {
-    it.second->Abort();
-  }
-#endif
-}
-
-void SpeechRecognitionDispatcher::Start(
-    const WebSpeechRecognitionHandle& handle,
-    const WebSpeechRecognitionParams& params,
-    const WebSpeechRecognizerClient& recognizer_client) {
-  DCHECK(recognizer_client_.IsNull() ||
-         recognizer_client_ == recognizer_client);
-  recognizer_client_ = recognizer_client;
-
-  blink::mojom::StartSpeechRecognitionRequestParamsPtr msg_params =
-      blink::mojom::StartSpeechRecognitionRequestParams::New();
-  for (const WebSpeechGrammar& grammar : params.Grammars()) {
-    msg_params->grammars.push_back(blink::mojom::SpeechRecognitionGrammar::New(
-        grammar.Src(), grammar.Weight()));
-  }
-  msg_params->language = params.Language().Utf8();
-  msg_params->max_hypotheses = static_cast<uint32_t>(params.MaxAlternatives());
-  msg_params->continuous = params.Continuous();
-  msg_params->interim_results = params.InterimResults();
-  msg_params->origin = params.Origin();
-
-  blink::mojom::SpeechRecognitionSessionClientPtrInfo client_ptr_info;
-  blink::mojom::SpeechRecognitionSessionClientRequest client_request =
-      mojo::MakeRequest(&client_ptr_info);
-  bindings_.AddBinding(std::make_unique<SpeechRecognitionSessionClientImpl>(
-                           this, handle, recognizer_client_),
-                       std::move(client_request));
-
-  blink::mojom::SpeechRecognitionSessionPtr session_client;
-  blink::mojom::SpeechRecognitionSessionRequest request =
-      mojo::MakeRequest(&session_client);
-
-  AddHandle(handle, std::move(session_client));
-
-  msg_params->client = std::move(client_ptr_info);
-  msg_params->session_request = std::move(request);
-
-  GetSpeechRecognitionHost().Start(std::move(msg_params));
-}
-
-void SpeechRecognitionDispatcher::Stop(
-    const WebSpeechRecognitionHandle& handle,
-    const WebSpeechRecognizerClient& recognizer_client) {
-  // Ignore a |stop| issued without a matching |start|.
-  if (recognizer_client_ != recognizer_client || !HandleExists(handle))
-    return;
-  GetSession(handle)->StopCapture();
-}
-
-void SpeechRecognitionDispatcher::Abort(
-    const WebSpeechRecognitionHandle& handle,
-    const WebSpeechRecognizerClient& recognizer_client) {
-  // Ignore an |abort| issued without a matching |start|.
-  if (recognizer_client_ != recognizer_client || !HandleExists(handle))
-    return;
-  GetSession(handle)->Abort();
-}
-
-static WebSpeechRecognizerClient::ErrorCode WebKitErrorCode(
-    blink::mojom::SpeechRecognitionErrorCode e) {
-  switch (e) {
-    case blink::mojom::SpeechRecognitionErrorCode::kNone:
-      NOTREACHED();
-      return WebSpeechRecognizerClient::kOtherError;
-    case blink::mojom::SpeechRecognitionErrorCode::kNoSpeech:
-      return WebSpeechRecognizerClient::kNoSpeechError;
-    case blink::mojom::SpeechRecognitionErrorCode::kAborted:
-      return WebSpeechRecognizerClient::kAbortedError;
-    case blink::mojom::SpeechRecognitionErrorCode::kAudioCapture:
-      return WebSpeechRecognizerClient::kAudioCaptureError;
-    case blink::mojom::SpeechRecognitionErrorCode::kNetwork:
-      return WebSpeechRecognizerClient::kNetworkError;
-    case blink::mojom::SpeechRecognitionErrorCode::kNotAllowed:
-      return WebSpeechRecognizerClient::kNotAllowedError;
-    case blink::mojom::SpeechRecognitionErrorCode::kServiceNotAllowed:
-      return WebSpeechRecognizerClient::kServiceNotAllowedError;
-    case blink::mojom::SpeechRecognitionErrorCode::kBadGrammar:
-      return WebSpeechRecognizerClient::kBadGrammarError;
-    case blink::mojom::SpeechRecognitionErrorCode::kLanguageNotSupported:
-      return WebSpeechRecognizerClient::kLanguageNotSupportedError;
-    case blink::mojom::SpeechRecognitionErrorCode::kNoMatch:
-      NOTREACHED();
-      return WebSpeechRecognizerClient::kOtherError;
-  }
-  NOTREACHED();
-  return WebSpeechRecognizerClient::kOtherError;
-}
-
-void SpeechRecognitionDispatcher::AddHandle(
-    const blink::WebSpeechRecognitionHandle& handle,
-    blink::mojom::SpeechRecognitionSessionPtr session) {
-  DCHECK(!HandleExists(handle));
-  session_map_[handle] = std::move(session);
-}
-
-bool SpeechRecognitionDispatcher::HandleExists(
-    const WebSpeechRecognitionHandle& handle) {
-  return session_map_.find(handle) != session_map_.end();
-}
-
-void SpeechRecognitionDispatcher::RemoveHandle(
-    const blink::WebSpeechRecognitionHandle& handle) {
-  session_map_.erase(handle);
-}
-
-blink::mojom::SpeechRecognitionSession* SpeechRecognitionDispatcher::GetSession(
-    const blink::WebSpeechRecognitionHandle& handle) {
-  DCHECK(HandleExists(handle));
-  return session_map_[handle].get();
-}
-
-blink::mojom::SpeechRecognizer&
-SpeechRecognitionDispatcher::GetSpeechRecognitionHost() {
-  if (!speech_recognition_host_) {
-    render_frame()->GetRemoteInterfaces()->GetInterface(
-        mojo::MakeRequest(&speech_recognition_host_));
-  }
-  return *speech_recognition_host_;
-}
-
-// ------------ SpeechRecognitionSessionClientImpl
-// ------------------------------------
-
-SpeechRecognitionSessionClientImpl::SpeechRecognitionSessionClientImpl(
-    SpeechRecognitionDispatcher* dispatcher,
-    const blink::WebSpeechRecognitionHandle& handle,
-    const blink::WebSpeechRecognizerClient& client)
-    : parent_dispatcher_(dispatcher), handle_(handle), web_client_(client) {}
-
-void SpeechRecognitionSessionClientImpl::Started() {
-  web_client_.DidStart(handle_);
-}
-
-void SpeechRecognitionSessionClientImpl::AudioStarted() {
-  web_client_.DidStartAudio(handle_);
-}
-
-void SpeechRecognitionSessionClientImpl::SoundStarted() {
-  web_client_.DidStartSound(handle_);
-}
-
-void SpeechRecognitionSessionClientImpl::SoundEnded() {
-  web_client_.DidEndSound(handle_);
-}
-
-void SpeechRecognitionSessionClientImpl::AudioEnded() {
-  web_client_.DidEndAudio(handle_);
-}
-
-void SpeechRecognitionSessionClientImpl::ErrorOccurred(
-    const blink::mojom::SpeechRecognitionErrorPtr error) {
-  if (error->code == blink::mojom::SpeechRecognitionErrorCode::kNoMatch) {
-    web_client_.DidReceiveNoMatch(handle_, WebSpeechRecognitionResult());
-  } else {
-    web_client_.DidReceiveError(handle_,
-                                WebString(),  // TODO(primiano): message?
-                                WebKitErrorCode(error->code));
-  }
-}
-
-void SpeechRecognitionSessionClientImpl::Ended() {
-  parent_dispatcher_->RemoveHandle(handle_);
-  web_client_.DidEnd(handle_);
-}
-
-void SpeechRecognitionSessionClientImpl::ResultRetrieved(
-    std::vector<blink::mojom::SpeechRecognitionResultPtr> results) {
-  size_t provisional_count =
-      std::count_if(results.begin(), results.end(),
-                    [](const blink::mojom::SpeechRecognitionResultPtr& result) {
-                      return result->is_provisional;
-                    });
-
-  WebVector<WebSpeechRecognitionResult> provisional(provisional_count);
-  WebVector<WebSpeechRecognitionResult> final(results.size() -
-                                              provisional_count);
-
-  int provisional_index = 0, final_index = 0;
-  for (const blink::mojom::SpeechRecognitionResultPtr& result : results) {
-    WebSpeechRecognitionResult* webkit_result =
-        result->is_provisional ? &provisional[provisional_index++]
-                               : &final[final_index++];
-
-    const size_t num_hypotheses = result->hypotheses.size();
-    WebVector<WebString> transcripts(num_hypotheses);
-    WebVector<float> confidences(num_hypotheses);
-    for (size_t i = 0; i < num_hypotheses; ++i) {
-      transcripts[i] = WebString::FromUTF16(result->hypotheses[i]->utterance);
-      confidences[i] = static_cast<float>(result->hypotheses[i]->confidence);
-    }
-    webkit_result->Assign(transcripts, confidences, !result->is_provisional);
-  }
-
-  web_client_.DidReceiveResults(handle_, final, provisional);
-}
-
-}  // namespace content
diff --git a/content/renderer/speech_recognition_dispatcher.h b/content/renderer/speech_recognition_dispatcher.h
deleted file mode 100644
index 697e3df..0000000
--- a/content/renderer/speech_recognition_dispatcher.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_SPEECH_RECOGNITION_DISPATCHER_H_
-#define CONTENT_RENDERER_SPEECH_RECOGNITION_DISPATCHER_H_
-
-#include <map>
-#include <memory>
-
-#include "base/macros.h"
-#include "content/public/renderer/render_frame_observer.h"
-#include "mojo/public/cpp/bindings/strong_binding_set.h"
-#include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h"
-#include "third_party/blink/public/mojom/speech/speech_recognizer.mojom.h"
-#include "third_party/blink/public/web/web_speech_recognition_handle.h"
-#include "third_party/blink/public/web/web_speech_recognizer.h"
-#include "third_party/blink/public/web/web_speech_recognizer_client.h"
-
-namespace content {
-
-// SpeechRecognitionDispatcher is a delegate for methods used by WebKit for
-// scripted JS speech APIs. It's the complement of
-// SpeechRecognitionDispatcherHost (owned by RenderFrameHost), and communicates
-// with it using two mojo interfaces (SpeechRecognizer and
-// SpeechRecognitionSession).
-class SpeechRecognitionDispatcher : public RenderFrameObserver,
-                                    public blink::WebSpeechRecognizer {
- public:
-  explicit SpeechRecognitionDispatcher(RenderFrame* render_frame);
-  ~SpeechRecognitionDispatcher() override;
-
- private:
-  // RenderFrameObserver implementation.
-  void OnDestruct() override;
-  void WasHidden() override;
-
-  // blink::WebSpeechRecognizer implementation.
-  void Start(const blink::WebSpeechRecognitionHandle&,
-             const blink::WebSpeechRecognitionParams&,
-             const blink::WebSpeechRecognizerClient&) override;
-  void Stop(const blink::WebSpeechRecognitionHandle&,
-            const blink::WebSpeechRecognizerClient&) override;
-  void Abort(const blink::WebSpeechRecognitionHandle&,
-             const blink::WebSpeechRecognizerClient&) override;
-
-  // Methods to interact with |session_map_|
-  void AddHandle(const blink::WebSpeechRecognitionHandle& handle,
-                 blink::mojom::SpeechRecognitionSessionPtr session);
-  bool HandleExists(const blink::WebSpeechRecognitionHandle& handle);
-  void RemoveHandle(const blink::WebSpeechRecognitionHandle& handle);
-  blink::mojom::SpeechRecognitionSession* GetSession(
-      const blink::WebSpeechRecognitionHandle& handle);
-
-  blink::mojom::SpeechRecognizer& GetSpeechRecognitionHost();
-
-  // InterfacePtr used to communicate with SpeechRecognitionDispatcherHost to
-  // start a session for each WebSpeechRecognitionHandle.
-  blink::mojom::SpeechRecognizerPtr speech_recognition_host_;
-
-  // The Blink client class that we use to send events back to the JS world.
-  // This is passed to each SpeechRecognitionSessionClientImpl instance.
-  blink::WebSpeechRecognizerClient recognizer_client_;
-
-  // Owns a SpeechRecognitionSessionClientImpl for each session created. The
-  // bindings are automatically cleaned up when the connection is closed by the
-  // browser process. We use mojo::StrongBindingSet instead of using
-  // mojo::MakeStrongBinding for each individual binding as
-  // SpeechRecognitionSessionClientImpl holds a pointer to its parent
-  // SpeechRecognitionDispatcher, and we need to clean up the
-  // SpeechRecognitionSessionClientImpl objects when |this| is deleted.
-  mojo::StrongBindingSet<blink::mojom::SpeechRecognitionSessionClient>
-      bindings_;
-
-  // Owns a SpeechRecognitionSessionPtr per session created. Each
-  // WebSpeechRecognitionHandle has its own speech recognition session, and is
-  // used as a key for the map.
-  using SessionMap = std::map<blink::WebSpeechRecognitionHandle,
-                              blink::mojom::SpeechRecognitionSessionPtr>;
-  SessionMap session_map_;
-
-  DISALLOW_COPY_AND_ASSIGN(SpeechRecognitionDispatcher);
-  friend class SpeechRecognitionSessionClientImpl;
-};
-
-// SpeechRecognitionSessionClientImpl is owned by SpeechRecognitionDispatcher
-// and is cleaned up either when the end point is closed by the browser process,
-// or if SpeechRecognitionDispatcher is deleted.
-class SpeechRecognitionSessionClientImpl
-    : public blink::mojom::SpeechRecognitionSessionClient {
- public:
-  SpeechRecognitionSessionClientImpl(
-      SpeechRecognitionDispatcher* dispatcher,
-      const blink::WebSpeechRecognitionHandle& handle,
-      const blink::WebSpeechRecognizerClient& client);
-  ~SpeechRecognitionSessionClientImpl() override = default;
-
-  // blink::mojom::SpeechRecognitionSessionClient implementation
-  void Started() override;
-  void AudioStarted() override;
-  void SoundStarted() override;
-  void SoundEnded() override;
-  void AudioEnded() override;
-  void ErrorOccurred(
-      const blink::mojom::SpeechRecognitionErrorPtr error) override;
-  void Ended() override;
-  void ResultRetrieved(
-      std::vector<blink::mojom::SpeechRecognitionResultPtr> results) override;
-
- private:
-  // Not owned, |parent_dispatcher_| owns |this|.
-  SpeechRecognitionDispatcher* parent_dispatcher_;
-  // WebSpeechRecognitionHandle that this instance is associated with.
-  blink::WebSpeechRecognitionHandle handle_;
-  // The Blink client class that we use to send events back to the JS world.
-  blink::WebSpeechRecognizerClient web_client_;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_SPEECH_RECOGNITION_DISPATCHER_H_
diff --git a/content/shell/test_runner/BUILD.gn b/content/shell/test_runner/BUILD.gn
index 1c2aa80..1b5c11a 100644
--- a/content/shell/test_runner/BUILD.gn
+++ b/content/shell/test_runner/BUILD.gn
@@ -42,8 +42,6 @@
     "mock_web_document_subresource_filter.h",
     "mock_web_midi_accessor.cc",
     "mock_web_midi_accessor.h",
-    "mock_web_speech_recognizer.cc",
-    "mock_web_speech_recognizer.h",
     "mock_web_theme_engine.cc",
     "mock_web_theme_engine.h",
     "pixel_dump.cc",
diff --git a/content/shell/test_runner/mock_web_speech_recognizer.cc b/content/shell/test_runner/mock_web_speech_recognizer.cc
deleted file mode 100644
index 4a0fb8a..0000000
--- a/content/shell/test_runner/mock_web_speech_recognizer.cc
+++ /dev/null
@@ -1,333 +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 "content/shell/test_runner/mock_web_speech_recognizer.h"
-
-#include <stddef.h>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "content/shell/test_runner/web_test_delegate.h"
-#include "third_party/blink/public/web/web_speech_recognition_result.h"
-#include "third_party/blink/public/web/web_speech_recognizer_client.h"
-
-namespace test_runner {
-
-namespace {
-
-// Task class for calling a client function that does not take any parameters.
-typedef void (blink::WebSpeechRecognizerClient::*ClientFunctionPointer)(
-    const blink::WebSpeechRecognitionHandle&);
-class ClientCallTask : public MockWebSpeechRecognizer::Task {
- public:
-  ClientCallTask(MockWebSpeechRecognizer* mock, ClientFunctionPointer function)
-      : MockWebSpeechRecognizer::Task(mock), function_(function) {}
-
-  ~ClientCallTask() override {}
-
-  void run() override {
-    (recognizer_->Client().*function_)(recognizer_->Handle());
-  }
-
- private:
-  ClientFunctionPointer function_;
-
-  DISALLOW_COPY_AND_ASSIGN(ClientCallTask);
-};
-
-// Task for delivering a result event.
-class ResultTask : public MockWebSpeechRecognizer::Task {
- public:
-  ResultTask(MockWebSpeechRecognizer* mock,
-             const blink::WebString transcript,
-             float confidence)
-      : MockWebSpeechRecognizer::Task(mock),
-        transcript_(transcript),
-        confidence_(confidence) {}
-
-  ~ResultTask() override {}
-
-  void run() override {
-    blink::WebVector<blink::WebString> transcripts(static_cast<size_t>(1));
-    blink::WebVector<float> confidences(static_cast<size_t>(1));
-    transcripts[0] = transcript_;
-    confidences[0] = confidence_;
-    blink::WebVector<blink::WebSpeechRecognitionResult> final_results(
-        static_cast<size_t>(1));
-    blink::WebVector<blink::WebSpeechRecognitionResult> interim_results;
-    final_results[0].Assign(transcripts, confidences, true);
-
-    recognizer_->Client().DidReceiveResults(recognizer_->Handle(),
-                                            final_results, interim_results);
-  }
-
- private:
-  blink::WebString transcript_;
-  float confidence_;
-
-  DISALLOW_COPY_AND_ASSIGN(ResultTask);
-};
-
-// Task for delivering a nomatch event.
-class NoMatchTask : public MockWebSpeechRecognizer::Task {
- public:
-  explicit NoMatchTask(MockWebSpeechRecognizer* mock)
-      : MockWebSpeechRecognizer::Task(mock) {}
-
-  ~NoMatchTask() override {}
-
-  void run() override {
-    recognizer_->Client().DidReceiveNoMatch(
-        recognizer_->Handle(), blink::WebSpeechRecognitionResult());
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NoMatchTask);
-};
-
-// Task for delivering an error event.
-class ErrorTask : public MockWebSpeechRecognizer::Task {
- public:
-  ErrorTask(MockWebSpeechRecognizer* mock,
-            blink::WebSpeechRecognizerClient::ErrorCode code,
-            const blink::WebString& message)
-      : MockWebSpeechRecognizer::Task(mock), code_(code), message_(message) {}
-
-  ~ErrorTask() override {}
-
-  void run() override {
-    recognizer_->Client().DidReceiveError(recognizer_->Handle(), message_,
-                                          code_);
-  }
-
- private:
-  blink::WebSpeechRecognizerClient::ErrorCode code_;
-  blink::WebString message_;
-
-  DISALLOW_COPY_AND_ASSIGN(ErrorTask);
-};
-
-// Task for tidying up after recognition task has ended.
-class EndedTask : public MockWebSpeechRecognizer::Task {
- public:
-  explicit EndedTask(MockWebSpeechRecognizer* mock)
-      : MockWebSpeechRecognizer::Task(mock) {}
-
-  ~EndedTask() override {}
-
-  void run() override {
-    blink::WebSpeechRecognitionHandle handle = recognizer_->Handle();
-    blink::WebSpeechRecognizerClient client = recognizer_->Client();
-    recognizer_->SetClientContext(blink::WebSpeechRecognitionHandle(),
-                                  blink::WebSpeechRecognizerClient());
-    client.DidEnd(handle);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(EndedTask);
-};
-
-// Task for switching processing to the next (handle, client) pairing.
-class SwitchClientHandleTask : public MockWebSpeechRecognizer::Task {
- public:
-  SwitchClientHandleTask(MockWebSpeechRecognizer* mock,
-                         const blink::WebSpeechRecognitionHandle& handle,
-                         const blink::WebSpeechRecognizerClient& client)
-      : MockWebSpeechRecognizer::Task(mock), handle_(handle), client_(client) {}
-
-  ~SwitchClientHandleTask() override {}
-
-  bool isNewContextTask() const override { return true; }
-
-  void run() override { recognizer_->SetClientContext(handle_, client_); }
-
- private:
-  const blink::WebSpeechRecognitionHandle handle_;
-  blink::WebSpeechRecognizerClient client_;
-
-  DISALLOW_COPY_AND_ASSIGN(SwitchClientHandleTask);
-};
-
-}  // namespace
-
-MockWebSpeechRecognizer::MockWebSpeechRecognizer()
-    : was_aborted_(false),
-      task_queue_running_(false),
-      delegate_(nullptr),
-      weak_factory_(this) {}
-
-MockWebSpeechRecognizer::~MockWebSpeechRecognizer() {
-  SetDelegate(nullptr);
-}
-
-bool MockWebSpeechRecognizer::Task::isNewContextTask() const {
-  return false;
-}
-
-void MockWebSpeechRecognizer::SetDelegate(WebTestDelegate* delegate) {
-  delegate_ = delegate;
-  // No delegate to forward to, clear out pending tasks.
-  if (!delegate_)
-    ClearTaskQueue();
-}
-
-void MockWebSpeechRecognizer::SetClientContext(
-    const blink::WebSpeechRecognitionHandle& handle,
-    const blink::WebSpeechRecognizerClient& client) {
-  handle_ = handle;
-  client_ = client;
-}
-
-void MockWebSpeechRecognizer::Start(
-    const blink::WebSpeechRecognitionHandle& handle,
-    const blink::WebSpeechRecognitionParams& params,
-    const blink::WebSpeechRecognizerClient& client) {
-  was_aborted_ = false;
-  if (client_.IsNull() && !HasPendingNewContextTasks()) {
-    handle_ = handle;
-    client_ = client;
-  } else {
-    task_queue_.push_back(new SwitchClientHandleTask(this, handle, client));
-  }
-
-  task_queue_.push_back(
-      new ClientCallTask(this, &blink::WebSpeechRecognizerClient::DidStart));
-  task_queue_.push_back(new ClientCallTask(
-      this, &blink::WebSpeechRecognizerClient::DidStartAudio));
-  task_queue_.push_back(new ClientCallTask(
-      this, &blink::WebSpeechRecognizerClient::DidStartSound));
-
-  if (!mock_transcripts_.empty()) {
-    DCHECK_EQ(mock_transcripts_.size(), mock_confidences_.size());
-
-    for (size_t i = 0; i < mock_transcripts_.size(); ++i)
-      task_queue_.push_back(
-          new ResultTask(this, mock_transcripts_[i], mock_confidences_[i]));
-
-    mock_transcripts_.clear();
-    mock_confidences_.clear();
-  } else {
-    task_queue_.push_back(new NoMatchTask(this));
-  }
-
-  task_queue_.push_back(
-      new ClientCallTask(this, &blink::WebSpeechRecognizerClient::DidEndSound));
-  task_queue_.push_back(
-      new ClientCallTask(this, &blink::WebSpeechRecognizerClient::DidEndAudio));
-  task_queue_.push_back(new EndedTask(this));
-
-  StartTaskQueue();
-}
-
-void MockWebSpeechRecognizer::Stop(
-    const blink::WebSpeechRecognitionHandle& handle,
-    const blink::WebSpeechRecognizerClient& client) {
-  SetClientContext(handle, client);
-
-  // FIXME: Implement.
-  NOTREACHED();
-}
-
-void MockWebSpeechRecognizer::Abort(
-    const blink::WebSpeechRecognitionHandle& handle,
-    const blink::WebSpeechRecognizerClient& client) {
-  was_aborted_ = true;
-  ClearTaskQueue();
-  task_queue_.push_back(new SwitchClientHandleTask(this, handle, client));
-  task_queue_.push_back(new EndedTask(this));
-
-  StartTaskQueue();
-}
-
-void MockWebSpeechRecognizer::AddMockResult(const blink::WebString& transcript,
-                                            float confidence) {
-  mock_transcripts_.push_back(transcript);
-  mock_confidences_.push_back(confidence);
-}
-
-void MockWebSpeechRecognizer::SetError(const blink::WebString& error,
-                                       const blink::WebString& message) {
-  blink::WebSpeechRecognizerClient::ErrorCode code;
-  if (error == "OtherError")
-    code = blink::WebSpeechRecognizerClient::kOtherError;
-  else if (error == "NoSpeechError")
-    code = blink::WebSpeechRecognizerClient::kNoSpeechError;
-  else if (error == "AbortedError")
-    code = blink::WebSpeechRecognizerClient::kAbortedError;
-  else if (error == "AudioCaptureError")
-    code = blink::WebSpeechRecognizerClient::kAudioCaptureError;
-  else if (error == "NetworkError")
-    code = blink::WebSpeechRecognizerClient::kNetworkError;
-  else if (error == "NotAllowedError")
-    code = blink::WebSpeechRecognizerClient::kNotAllowedError;
-  else if (error == "ServiceNotAllowedError")
-    code = blink::WebSpeechRecognizerClient::kServiceNotAllowedError;
-  else if (error == "BadGrammarError")
-    code = blink::WebSpeechRecognizerClient::kBadGrammarError;
-  else if (error == "LanguageNotSupportedError")
-    code = blink::WebSpeechRecognizerClient::kLanguageNotSupportedError;
-  else
-    return;
-
-  ClearTaskQueue();
-  task_queue_.push_back(new ErrorTask(this, code, message));
-  task_queue_.push_back(new EndedTask(this));
-
-  StartTaskQueue();
-}
-
-void MockWebSpeechRecognizer::StartTaskQueue() {
-  if (task_queue_running_)
-    return;
-  PostRunTaskFromQueue();
-}
-
-void MockWebSpeechRecognizer::ClearTaskQueue() {
-  while (!task_queue_.empty()) {
-    Task* task = task_queue_.front();
-    if (task->isNewContextTask())
-      break;
-    delete task_queue_.front();
-    task_queue_.pop_front();
-  }
-  if (task_queue_.empty())
-    task_queue_running_ = false;
-}
-
-void MockWebSpeechRecognizer::PostRunTaskFromQueue() {
-  task_queue_running_ = true;
-  delegate_->PostTask(base::BindOnce(&MockWebSpeechRecognizer::RunTaskFromQueue,
-                                     weak_factory_.GetWeakPtr()));
-}
-
-void MockWebSpeechRecognizer::RunTaskFromQueue() {
-  if (task_queue_.empty()) {
-    task_queue_running_ = false;
-    return;
-  }
-
-  MockWebSpeechRecognizer::Task* task = task_queue_.front();
-  task_queue_.pop_front();
-  task->run();
-  delete task;
-
-  if (task_queue_.empty()) {
-    task_queue_running_ = false;
-    return;
-  }
-
-  PostRunTaskFromQueue();
-}
-
-bool MockWebSpeechRecognizer::HasPendingNewContextTasks() const {
-  for (auto* task : task_queue_) {
-    if (task->isNewContextTask())
-      return true;
-  }
-  return false;
-}
-
-}  // namespace test_runner
diff --git a/content/shell/test_runner/mock_web_speech_recognizer.h b/content/shell/test_runner/mock_web_speech_recognizer.h
deleted file mode 100644
index 6c8586f3..0000000
--- a/content/shell/test_runner/mock_web_speech_recognizer.h
+++ /dev/null
@@ -1,97 +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.
-
-#ifndef CONTENT_SHELL_TEST_RUNNER_MOCK_WEB_SPEECH_RECOGNIZER_H_
-#define CONTENT_SHELL_TEST_RUNNER_MOCK_WEB_SPEECH_RECOGNIZER_H_
-
-#include <vector>
-
-#include "base/containers/circular_deque.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "third_party/blink/public/web/web_speech_recognizer.h"
-#include "third_party/blink/public/web/web_speech_recognizer_client.h"
-
-namespace blink {
-class WebSpeechRecognitionHandle;
-class WebSpeechRecognitionParams;
-class WebSpeechRecognizerClient;
-class WebString;
-}  // namespace blink
-
-namespace test_runner {
-
-class WebTestDelegate;
-
-class MockWebSpeechRecognizer : public blink::WebSpeechRecognizer {
- public:
-  MockWebSpeechRecognizer();
-  ~MockWebSpeechRecognizer() override;
-
-  void SetDelegate(WebTestDelegate* delegate);
-
-  // WebSpeechRecognizer implementation:
-  void Start(const blink::WebSpeechRecognitionHandle& handle,
-             const blink::WebSpeechRecognitionParams& params,
-             const blink::WebSpeechRecognizerClient& client) override;
-  void Stop(const blink::WebSpeechRecognitionHandle& handle,
-            const blink::WebSpeechRecognizerClient& client) override;
-  void Abort(const blink::WebSpeechRecognitionHandle& handle,
-             const blink::WebSpeechRecognizerClient& client) override;
-
-  // Methods accessed by layout tests:
-  void AddMockResult(const blink::WebString& transcript, float confidence);
-  void SetError(const blink::WebString& error, const blink::WebString& message);
-  bool WasAborted() const { return was_aborted_; }
-
-  // Methods accessed from Task objects:
-  blink::WebSpeechRecognizerClient& Client() { return client_; }
-  blink::WebSpeechRecognitionHandle& Handle() { return handle_; }
-
-  void SetClientContext(const blink::WebSpeechRecognitionHandle&,
-                        const blink::WebSpeechRecognizerClient&);
-
-  class Task {
-   public:
-    explicit Task(MockWebSpeechRecognizer* recognizer)
-        : recognizer_(recognizer) {}
-    virtual ~Task() {}
-    virtual void run() = 0;
-    virtual bool isNewContextTask() const;
-
-   protected:
-    MockWebSpeechRecognizer* recognizer_;
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(Task);
-  };
-
- private:
-  void StartTaskQueue();
-  void ClearTaskQueue();
-  void PostRunTaskFromQueue();
-  void RunTaskFromQueue();
-
-  bool HasPendingNewContextTasks() const;
-
-  blink::WebSpeechRecognitionHandle handle_;
-  blink::WebSpeechRecognizerClient client_;
-  std::vector<blink::WebString> mock_transcripts_;
-  std::vector<float> mock_confidences_;
-  bool was_aborted_;
-
-  // Queue of tasks to be run.
-  base::circular_deque<Task*> task_queue_;
-  bool task_queue_running_;
-
-  WebTestDelegate* delegate_;
-
-  base::WeakPtrFactory<MockWebSpeechRecognizer> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(MockWebSpeechRecognizer);
-};
-
-}  // namespace test_runner
-
-#endif  // CONTENT_SHELL_TEST_RUNNER_MOCK_WEB_SPEECH_RECOGNIZER_H_
diff --git a/content/shell/test_runner/test_runner.cc b/content/shell/test_runner/test_runner.cc
index ea01113..6a03a62 100644
--- a/content/shell/test_runner/test_runner.cc
+++ b/content/shell/test_runner/test_runner.cc
@@ -24,7 +24,6 @@
 #include "content/shell/test_runner/mock_content_settings_client.h"
 #include "content/shell/test_runner/mock_screen_orientation_client.h"
 #include "content/shell/test_runner/mock_web_document_subresource_filter.h"
-#include "content/shell/test_runner/mock_web_speech_recognizer.h"
 #include "content/shell/test_runner/pixel_dump.h"
 #include "content/shell/test_runner/spell_check_client.h"
 #include "content/shell/test_runner/test_common.h"
@@ -112,8 +111,6 @@
   gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
       v8::Isolate* isolate) override;
 
-  void AddMockSpeechRecognitionResult(const std::string& transcript,
-                                      double confidence);
   void AddOriginAccessWhitelistEntry(const std::string& source_origin,
                                      const std::string& destination_protocol,
                                      const std::string& destination_host,
@@ -219,8 +216,6 @@
   void SetJavaScriptCanAccessClipboard(bool can_access);
   void SetMIDIAccessorResult(bool result);
   void SetMockScreenOrientation(const std::string& orientation);
-  void SetMockSpeechRecognitionError(const std::string& error,
-                                     const std::string& message);
   void SetPOSIXLocale(const std::string& locale);
   void SetPageVisibility(const std::string& new_visibility);
   void SetPermission(const std::string& name,
@@ -364,8 +359,6 @@
   return gin::Wrappable<TestRunnerBindings>::GetObjectTemplateBuilder(isolate)
       .SetMethod("abortModal", &TestRunnerBindings::NotImplemented)
       .SetMethod("addDisallowedURL", &TestRunnerBindings::NotImplemented)
-      .SetMethod("addMockSpeechRecognitionResult",
-                 &TestRunnerBindings::AddMockSpeechRecognitionResult)
       .SetMethod("addOriginAccessWhitelistEntry",
                  &TestRunnerBindings::AddOriginAccessWhitelistEntry)
       .SetMethod("addWebPageOverlay", &TestRunnerBindings::AddWebPageOverlay)
@@ -545,8 +538,6 @@
                  &TestRunnerBindings::NotImplemented)
       .SetMethod("setMockScreenOrientation",
                  &TestRunnerBindings::SetMockScreenOrientation)
-      .SetMethod("setMockSpeechRecognitionError",
-                 &TestRunnerBindings::SetMockSpeechRecognitionError)
       .SetMethod("setPOSIXLocale", &TestRunnerBindings::SetPOSIXLocale)
       .SetMethod("setPageVisibility", &TestRunnerBindings::SetPageVisibility)
       .SetMethod("setPermission", &TestRunnerBindings::SetPermission)
@@ -1303,20 +1294,6 @@
   runner_->SimulateWebNotificationClose(title, by_user);
 }
 
-void TestRunnerBindings::AddMockSpeechRecognitionResult(
-    const std::string& transcript,
-    double confidence) {
-  if (runner_)
-    runner_->AddMockSpeechRecognitionResult(transcript, confidence);
-}
-
-void TestRunnerBindings::SetMockSpeechRecognitionError(
-    const std::string& error,
-    const std::string& message) {
-  if (runner_)
-    runner_->SetMockSpeechRecognitionError(error, message);
-}
-
 void TestRunnerBindings::AddWebPageOverlay() {
   if (view_runner_)
     view_runner_->AddWebPageOverlay();
@@ -1524,8 +1501,6 @@
   delegate_ = delegate;
   mock_content_settings_client_->SetDelegate(delegate);
   spellcheck_->SetDelegate(delegate);
-  if (speech_recognizer_)
-    speech_recognizer_->SetDelegate(delegate);
 }
 
 void TestRunner::SetMainView(WebView* web_view) {
@@ -2126,14 +2101,6 @@
   return mock_screen_orientation_client_.get();
 }
 
-MockWebSpeechRecognizer* TestRunner::getMockWebSpeechRecognizer() {
-  if (!speech_recognizer_.get()) {
-    speech_recognizer_.reset(new MockWebSpeechRecognizer());
-    speech_recognizer_->SetDelegate(delegate_);
-  }
-  return speech_recognizer_.get();
-}
-
 void TestRunner::SetMockScreenOrientation(const std::string& orientation_str) {
   blink::WebScreenOrientationType orientation;
 
@@ -2553,18 +2520,6 @@
   delegate_->SimulateWebNotificationClose(title, by_user);
 }
 
-void TestRunner::AddMockSpeechRecognitionResult(const std::string& transcript,
-                                                double confidence) {
-  getMockWebSpeechRecognizer()->AddMockResult(WebString::FromUTF8(transcript),
-                                              confidence);
-}
-
-void TestRunner::SetMockSpeechRecognitionError(const std::string& error,
-                                               const std::string& message) {
-  getMockWebSpeechRecognizer()->SetError(WebString::FromUTF8(error),
-                                         WebString::FromUTF8(message));
-}
-
 void TestRunner::OnLayoutTestRuntimeFlagsChanged() {
   if (layout_test_runtime_flags_.tracked_dictionary().changed_values().empty())
     return;
diff --git a/content/shell/test_runner/test_runner.h b/content/shell/test_runner/test_runner.h
index a0cd25d..ba93c77 100644
--- a/content/shell/test_runner/test_runner.h
+++ b/content/shell/test_runner/test_runner.h
@@ -45,7 +45,6 @@
 
 class MockContentSettingsClient;
 class MockScreenOrientationClient;
-class MockWebSpeechRecognizer;
 class SpellCheckClient;
 class TestInterfaces;
 class TestRunnerForSpecificView;
@@ -104,7 +103,6 @@
   std::string GetAcceptLanguages() const;
   bool shouldStayOnPageAfterHandlingBeforeUnload() const;
   MockScreenOrientationClient* getMockScreenOrientationClient();
-  MockWebSpeechRecognizer* getMockWebSpeechRecognizer();
   bool isPrinting() const;
   bool shouldDumpAsCustomText() const;
   std::string customDumpText() const;
@@ -500,12 +498,6 @@
   // Simulates closing a Web Notification.
   void SimulateWebNotificationClose(const std::string& title, bool by_user);
 
-  // Speech recognition related functions.
-  void AddMockSpeechRecognitionResult(const std::string& transcript,
-                                      double confidence);
-  void SetMockSpeechRecognitionError(const std::string& error,
-                                     const std::string& message);
-
   // Takes care of notifying the delegate after a change to layout test runtime
   // flags.
   void OnLayoutTestRuntimeFlagsChanged();
@@ -579,7 +571,6 @@
   bool use_mock_theme_;
 
   std::unique_ptr<MockScreenOrientationClient> mock_screen_orientation_client_;
-  std::unique_ptr<MockWebSpeechRecognizer> speech_recognizer_;
   std::unique_ptr<SpellCheckClient> spellcheck_;
 
   // Number of currently active color choosers.
diff --git a/content/shell/test_runner/test_runner_for_specific_view.cc b/content/shell/test_runner/test_runner_for_specific_view.cc
index 5fb17cd..ea3bc54 100644
--- a/content/shell/test_runner/test_runner_for_specific_view.cc
+++ b/content/shell/test_runner/test_runner_for_specific_view.cc
@@ -18,7 +18,6 @@
 #include "content/shell/test_runner/layout_dump.h"
 #include "content/shell/test_runner/mock_content_settings_client.h"
 #include "content/shell/test_runner/mock_screen_orientation_client.h"
-#include "content/shell/test_runner/mock_web_speech_recognizer.h"
 #include "content/shell/test_runner/pixel_dump.h"
 #include "content/shell/test_runner/spell_check_client.h"
 #include "content/shell/test_runner/test_common.h"
diff --git a/content/shell/test_runner/web_frame_test_client.cc b/content/shell/test_runner/web_frame_test_client.cc
index 3a3d3f0..34c3985a 100644
--- a/content/shell/test_runner/web_frame_test_client.cc
+++ b/content/shell/test_runner/web_frame_test_client.cc
@@ -14,7 +14,6 @@
 #include "content/shell/test_runner/accessibility_controller.h"
 #include "content/shell/test_runner/event_sender.h"
 #include "content/shell/test_runner/mock_screen_orientation_client.h"
-#include "content/shell/test_runner/mock_web_speech_recognizer.h"
 #include "content/shell/test_runner/test_common.h"
 #include "content/shell/test_runner/test_interfaces.h"
 #include "content/shell/test_runner/test_plugin.h"
@@ -679,10 +678,6 @@
     callback->OnError(blink::WebSetSinkIdError::kNotFound);
 }
 
-blink::WebSpeechRecognizer* WebFrameTestClient::SpeechRecognizer() {
-  return test_runner()->getMockWebSpeechRecognizer();
-}
-
 void WebFrameTestClient::DidClearWindowObject() {
   blink::WebLocalFrame* frame = web_frame_test_proxy_base_->web_frame();
   web_view_test_proxy_base_->test_interfaces()->BindTo(frame);
diff --git a/content/shell/test_runner/web_frame_test_client.h b/content/shell/test_runner/web_frame_test_client.h
index 9226f0a..d1be7f1b 100644
--- a/content/shell/test_runner/web_frame_test_client.h
+++ b/content/shell/test_runner/web_frame_test_client.h
@@ -84,7 +84,6 @@
   void CheckIfAudioSinkExistsAndIsAuthorized(
       const blink::WebString& sink_id,
       blink::WebSetSinkIdCallbacks* web_callbacks) override;
-  blink::WebSpeechRecognizer* SpeechRecognizer() override;
   void DidClearWindowObject() override;
   bool RunFileChooser(const blink::WebFileChooserParams& params,
                       blink::WebFileChooserCompletion* completion) override;
diff --git a/content/shell/test_runner/web_frame_test_proxy.h b/content/shell/test_runner/web_frame_test_proxy.h
index 637926a..f90ef443 100644
--- a/content/shell/test_runner/web_frame_test_proxy.h
+++ b/content/shell/test_runner/web_frame_test_proxy.h
@@ -248,10 +248,6 @@
                                                          web_callbacks);
   }
 
-  blink::WebSpeechRecognizer* SpeechRecognizer() override {
-    return test_client()->SpeechRecognizer();
-  }
-
   void DidClearWindowObject() override {
     test_client()->DidClearWindowObject();
     Base::DidClearWindowObject();
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index e016b21..119866a 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -758,6 +758,7 @@
     "../browser/loader/resource_scheduler_browsertest.cc",
     "../browser/manifest/manifest_browsertest.cc",
     "../browser/media/encrypted_media_browsertest.cc",
+    "../browser/media/media_autoplay_browsertest.cc",
     "../browser/media/media_browsertest.cc",
     "../browser/media/media_browsertest.h",
     "../browser/media/media_canplaytype_browsertest.cc",
@@ -1316,6 +1317,7 @@
     "../browser/frame_host/navigation_entry_impl_unittest.cc",
     "../browser/frame_host/navigation_handle_impl_unittest.cc",
     "../browser/frame_host/navigator_impl_unittest.cc",
+    "../browser/frame_host/origin_policy_throttle_unittest.cc",
     "../browser/frame_host/render_frame_host_feature_policy_unittest.cc",
     "../browser/frame_host/render_frame_host_manager_unittest.cc",
     "../browser/frame_host/render_widget_host_view_guest_unittest.cc",
diff --git a/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py b/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py
index a3a8f3b7..c3328e6 100644
--- a/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py
+++ b/content/test/gpu/gpu_tests/screenshot_sync_integration_test.py
@@ -118,7 +118,7 @@
     tab.EvaluateJavaScript(
         "window.draw({{ red }}, {{ green }}, {{ blue }});",
         red=canvasRGB.r, green=canvasRGB.g, blue=canvasRGB.b)
-    screenshot = tab.Screenshot(5)
+    screenshot = tab.Screenshot(10)
     start_x = 10
     start_y = 0
     outer_size = 256
@@ -131,7 +131,7 @@
     browser_arg = args[0]
     self.RestartBrowserIfNecessaryWithArgs(self._AddDefaultArgs([browser_arg]))
     self._Navigate(test_path)
-    repetitions = 10
+    repetitions = 20
     for _ in range(0, repetitions):
       self._CheckScreenshot()
 
diff --git a/gpu/ipc/common/gpu_memory_buffer_support.h b/gpu/ipc/common/gpu_memory_buffer_support.h
index 885208bc..eed5cd1 100644
--- a/gpu/ipc/common/gpu_memory_buffer_support.h
+++ b/gpu/ipc/common/gpu_memory_buffer_support.h
@@ -12,7 +12,6 @@
 #include "build/build_config.h"
 #include "gpu/gpu_export.h"
 #include "gpu/ipc/common/gpu_memory_buffer_impl.h"
-#include "gpu/ipc/common/gpu_memory_buffer_support.h"
 #include "ui/gfx/buffer_types.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/gpu_memory_buffer.h"
diff --git a/headless/OWNERS b/headless/OWNERS
index 0771e4f..0d4b109 100644
--- a/headless/OWNERS
+++ b/headless/OWNERS
@@ -1,5 +1,4 @@
 skyostil@chromium.org
-alexclarke@chromium.org
 eseckler@chromium.org
 
 # PST
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg
index 21ac7b05..e55cb34 100644
--- a/infra/config/global/cr-buildbucket.cfg
+++ b/infra/config/global/cr-buildbucket.cfg
@@ -2396,7 +2396,11 @@
     builders { mixins: "chromeos-try" name: "chromeos-daisy-rel" }
     builders { mixins: "chromeos-try" name: "linux-chromeos-compile-dbg" }
     builders { mixins: "chromeos-try" name: "linux-chromeos-dbg" }
-    builders { mixins: "chromeos-try" name: "linux-chromeos-rel" }
+    builders {
+      mixins: "chromeos-try"
+      mixins: "goma-j150"
+      name: "linux-chromeos-rel"
+    }
 
     builders { mixins: "linux-angle-try" name: "linux_angle_compile_dbg_ng" }
     builders { mixins: "linux-angle-try" name: "linux_angle_dbg_ng" }
@@ -2598,7 +2602,11 @@
       execution_timeout_secs: 10800  # 3h
     }
     builders { mixins: "win-try" name: "win10_chromium_x64_dbg_ng" }
-    builders { mixins: "win-try" name: "win10_chromium_x64_rel_ng" }
+    builders {
+      mixins: "win-try"
+      mixins: "goma-j150"
+      name: "win10_chromium_x64_rel_ng"
+    }
     builders { mixins: "win-try" name: "win10_chromium_x64_rel_ng_exp" }
     builders { mixins: "win-try" mixins: "gn_upload" name: "win8_chromium_gn_upload" }
     builders {
diff --git a/ios/chrome/browser/ui/autofill/save_card_infobar_view.mm b/ios/chrome/browser/ui/autofill/save_card_infobar_view.mm
index ef75f76..0cd96eb 100644
--- a/ios/chrome/browser/ui/autofill/save_card_infobar_view.mm
+++ b/ios/chrome/browser/ui/autofill/save_card_infobar_view.mm
@@ -29,14 +29,16 @@
 // Padding used on the edges of the infobar.
 const CGFloat kPadding = 16;
 
+// Line height for the title message.
+const CGFloat kTitleLineHeight = 24;
+
+// Line height for the description and legal messages.
+const CGFloat kDescriptionLineHeight = 20;
+
 // Padding used on the close button to increase the touchable area. This added
 // to the close button icon's intrinsic padding equals kPadding.
 const CGFloat kCloseButtonPadding = 12;
 
-// Intrinsic padding of the icon. Used to set a padding on the icon that equals
-// kPadding.
-const CGFloat kIconIntrinsicPadding = 6;
-
 // Color in RGB to be used as tint color on the icon.
 const CGFloat kIconTintColor = 0x1A73E8;
 
@@ -226,10 +228,10 @@
     [NSLayoutConstraint activateConstraints:@[
       [iconContainerView.leadingAnchor
           constraintEqualToAnchor:safeAreaLayoutGuide.leadingAnchor
-                         constant:kPadding - kIconIntrinsicPadding],
+                         constant:kPadding],
       [iconContainerView.topAnchor
           constraintEqualToAnchor:safeAreaLayoutGuide.topAnchor
-                         constant:kPadding - kIconIntrinsicPadding],
+                         constant:kPadding],
     ]];
   }
 
@@ -248,8 +250,7 @@
   NSLayoutConstraint* headerViewLeadingConstraint =
       self.icon ? [headerView.leadingAnchor
                       constraintEqualToAnchor:iconContainerView.trailingAnchor
-                                     constant:kHorizontalSpacing -
-                                              kIconIntrinsicPadding]
+                                     constant:kHorizontalSpacing]
                 : [headerView.leadingAnchor
                       constraintEqualToAnchor:safeAreaLayoutGuide.leadingAnchor
                                      constant:kPadding];
@@ -427,7 +428,15 @@
   NSMutableParagraphStyle* paragraphStyle =
       [[NSMutableParagraphStyle alloc] init];
   paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
-  paragraphStyle.lineSpacing = 1.5;
+
+  // Set the line height and vertically center the text.
+  UIFont* font = InfoBarMessageFont();
+  paragraphStyle.lineSpacing =
+      (kTitleLineHeight - (font.ascender - font.descender)) / 2;
+  paragraphStyle.minimumLineHeight =
+      kTitleLineHeight - paragraphStyle.lineSpacing;
+  paragraphStyle.maximumLineHeight = paragraphStyle.minimumLineHeight;
+
   NSDictionary* attributes = @{
     NSParagraphStyleAttributeName : paragraphStyle,
     NSFontAttributeName : InfoBarMessageFont(),
@@ -487,7 +496,8 @@
     NSMutableParagraphStyle* paragraphStyle =
         [[NSMutableParagraphStyle alloc] init];
     paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
-    paragraphStyle.lineSpacing = 1.4;
+    paragraphStyle.minimumLineHeight = kDescriptionLineHeight;
+    paragraphStyle.maximumLineHeight = paragraphStyle.minimumLineHeight;
     NSDictionary* attributes = @{
       NSParagraphStyleAttributeName : paragraphStyle,
       NSFontAttributeName : [MDCTypography body1Font],
@@ -554,7 +564,8 @@
     NSMutableParagraphStyle* paragraphStyle =
         [[NSMutableParagraphStyle alloc] init];
     paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
-    paragraphStyle.lineSpacing = 1.4;
+    paragraphStyle.minimumLineHeight = kDescriptionLineHeight;
+    paragraphStyle.maximumLineHeight = paragraphStyle.minimumLineHeight;
     NSDictionary* attributes = @{
       NSParagraphStyleAttributeName : paragraphStyle,
       NSFontAttributeName : [MDCTypography body1Font],
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index d567c952..de313ee 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -5170,6 +5170,10 @@
   } else {
     UIImageView* pageScreenshot = [self pageOpenCloseAnimationView];
     tab.view.frame = self.contentArea.bounds;
+    // Setting the frame here doesn't trigger a layout pass. Trigger it manually
+    // if needed. Not triggering it can create problem if the previous frame
+    // wasn't the right one, for example in https://crbug.com/852106.
+    [tab.view layoutIfNeeded];
     pageScreenshot.image = SnapshotTabHelper::FromWebState(tab.webState)
                                ->UpdateSnapshot(/*with_overlays=*/true,
                                                 /*visible_frame_only=*/true);
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm
index af12fe82..a76686f 100644
--- a/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm
@@ -427,6 +427,12 @@
 // Tests that the header is shown when loading an error page in a native view
 // even if fullscreen was enabled previously.
 - (void)testShowHeaderOnErrorPage {
+#if TARGET_OS_SIMULATOR
+  if (!base::ios::IsRunningOnIOS11OrLater()) {
+    // TODO(crbug.com/855368): Reenable this test.
+    EARL_GREY_TEST_DISABLED(@"Test failing on iOS 10 devices");
+  }
+#endif  // TARGET_OS_SIMULATOR
   std::map<GURL, std::string> responses;
   const GURL URL = web::test::HttpServer::MakeUrl("http://origin");
   // A long page with some simple text -- a long page is necessary so that
diff --git a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn
index 65d6473..6bed79b 100644
--- a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn
+++ b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn
@@ -34,6 +34,7 @@
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/omnibox:omnibox_popup_shared",
     "//ios/chrome/browser/ui/omnibox:omnibox_util",
+    "//ios/chrome/browser/ui/toolbar/buttons",
     "//ios/chrome/browser/ui/toolbar/public:feature_flags",
     "//ios/chrome/browser/ui/toolbar/public:public",
     "//ios/chrome/browser/ui/util:util",
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm
index 87f4e569..5012569 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm
@@ -59,12 +59,14 @@
   self.popupViewController = [[OmniboxPopupViewController alloc] init];
   self.popupViewController.incognito = self.browserState->IsOffTheRecord();
 
-  self.mediator.incognito = self.browserState->IsOffTheRecord();
+  BOOL isIncognito = self.browserState->IsOffTheRecord();
+  self.mediator.incognito = isIncognito;
   self.mediator.consumer = self.popupViewController;
   if (IsUIRefreshPhase1Enabled()) {
     self.mediator.presenter = [[OmniboxPopupPresenter alloc]
         initWithPopupPositioner:self.positioner
-            popupViewController:self.popupViewController];
+            popupViewController:self.popupViewController
+                      incognito:isIncognito];
   } else {
     self.mediator.presenter = [[OmniboxPopupLegacyPresenter alloc]
         initWithPopupPositioner:self.positioner
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h
index 8018fcc..4a5eb47 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h
@@ -11,7 +11,8 @@
 @interface OmniboxPopupPresenter : NSObject<OmniboxPopupGenericPresenter>
 
 - (instancetype)initWithPopupPositioner:(id<OmniboxPopupPositioner>)positioner
-                    popupViewController:(UIViewController*)viewController;
+                    popupViewController:(UIViewController*)viewController
+                              incognito:(BOOL)incognito;
 
 @end
 
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm
index 5ba907f..739ee66e 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm
@@ -5,6 +5,7 @@
 #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h"
 
 #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_positioner.h"
+#import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h"
 #import "ios/chrome/browser/ui/toolbar/public/features.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
@@ -19,11 +20,7 @@
 namespace {
 const CGFloat kExpandAnimationDuration = 0.1;
 const CGFloat kCollapseAnimationDuration = 0.05;
-const CGFloat kShadowHeight = 10;
 const CGFloat kVerticalOffset = 6;
-NS_INLINE CGFloat BottomPadding() {
-  return IsIPadIdiom() ? kShadowHeight : 0;
-}
 }  // namespace
 
 @interface OmniboxPopupPresenter ()
@@ -42,42 +39,35 @@
 @synthesize bottomConstraint = _bottomConstraint;
 
 - (instancetype)initWithPopupPositioner:(id<OmniboxPopupPositioner>)positioner
-                    popupViewController:(UIViewController*)viewController {
+                    popupViewController:(UIViewController*)viewController
+                              incognito:(BOOL)incognito {
   self = [super init];
   if (self) {
     _positioner = positioner;
     _viewController = viewController;
 
-    // Set up a container for presentation.
-    UIView* popupContainer = [[UIView alloc] init];
-    _popupContainerView = popupContainer;
-    popupContainer.translatesAutoresizingMaskIntoConstraints = NO;
-    popupContainer.layoutMargins = UIEdgeInsetsMake(0, 0, BottomPadding(), 0);
+    // Popup uses same colors as the toolbar, so the ToolbarConfiguration is
+    // used to get the style.
+    ToolbarConfiguration* configuration = [[ToolbarConfiguration alloc]
+        initWithStyle:incognito ? INCOGNITO : NORMAL];
 
-    // Add the view controller's view to the container.
-    [popupContainer addSubview:viewController.view];
+    UIBlurEffect* effect = [configuration blurEffect];
+
+    if (effect) {
+      UIVisualEffectView* effectView =
+          [[UIVisualEffectView alloc] initWithEffect:effect];
+      [effectView.contentView addSubview:viewController.view];
+      _popupContainerView = effectView;
+
+    } else {
+      UIView* containerView = [[UIView alloc] init];
+      [containerView addSubview:viewController.view];
+      _popupContainerView = containerView;
+    }
+    _popupContainerView.backgroundColor = [configuration blurBackgroundColor];
+    _popupContainerView.translatesAutoresizingMaskIntoConstraints = NO;
     viewController.view.translatesAutoresizingMaskIntoConstraints = NO;
-    AddSameConstraintsToSidesWithInsets(
-        viewController.view, popupContainer,
-        LayoutSides::kLeading | LayoutSides::kTrailing | LayoutSides::kBottom |
-            LayoutSides::kTop,
-        ChromeDirectionalEdgeInsetsMake(0, 0, BottomPadding(), 0));
-
-    // Add a shadow.
-    UIImageView* shadowView = [[UIImageView alloc]
-        initWithImage:NativeImage(IDR_IOS_TOOLBAR_SHADOW_FULL_BLEED)];
-    [shadowView setUserInteractionEnabled:NO];
-    [shadowView setTranslatesAutoresizingMaskIntoConstraints:NO];
-    [popupContainer addSubview:shadowView];
-
-    // On iPhone, the shadow is on the top of the popup, as if it's cast by
-    // the omnibox; on iPad, the shadow is cast by the popup instead, so it's
-    // below the popup.
-    AddSameConstraintsToSides(shadowView, popupContainer,
-                              LayoutSides::kLeading | LayoutSides::kTrailing);
-    AddSameConstraintsToSides(
-        shadowView, popupContainer,
-        IsIPadIdiom() ? LayoutSides::kBottom : LayoutSides::kTop);
+    AddSameConstraints(viewController.view, _popupContainerView);
   }
   return self;
 }
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
index fc03a5c..dfb95ce 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
@@ -14,6 +14,7 @@
 #import "ios/chrome/browser/ui/omnibox/popup/self_sizing_table_view.h"
 #import "ios/chrome/browser/ui/omnibox/truncating_attributed_label.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
+#import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_theme_resources.h"
@@ -127,6 +128,7 @@
     self.view.backgroundColor =
         IsIPadIdiom() ? BackgroundColorTablet() : BackgroundColorPhone();
   }
+
   [self.view setAutoresizingMask:(UIViewAutoresizingFlexibleWidth |
                                   UIViewAutoresizingFlexibleHeight)];
 
@@ -168,7 +170,21 @@
 }
 
 - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection {
+  [super traitCollectionDidChange:previousTraitCollection];
   [self layoutRows];
+
+  if (!IsUIRefreshPhase1Enabled()) {
+    return;
+  }
+
+  ToolbarConfiguration* configuration = [[ToolbarConfiguration alloc]
+      initWithStyle:self.incognito ? INCOGNITO : NORMAL];
+
+  if (IsRegularXRegularSizeClass(self)) {
+    self.view.backgroundColor = configuration.backgroundColor;
+  } else {
+    self.view.backgroundColor = [UIColor clearColor];
+  }
 }
 
 - (void)viewWillTransitionToSize:(CGSize)size
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index 7e01705..58b4ff0 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -3823,14 +3823,19 @@
   // This will be resized later, but matching the final frame will minimize
   // re-rendering. Use the screen size because the application's key window
   // may still be nil.
+  CGRect containerViewFrame = CGRectZero;
+  if (UIApplication.sharedApplication.keyWindow) {
+    containerViewFrame = UIApplication.sharedApplication.keyWindow.bounds;
+  } else {
+    containerViewFrame = UIScreen.mainScreen.bounds;
+  }
   if (base::FeatureList::IsEnabled(
           web::features::kBrowserContainerFullscreen)) {
-    _containerView.frame = [UIScreen mainScreen].bounds;
+    _containerView.frame = containerViewFrame;
   } else {
     // TODO(crbug.com/688259): Stop subtracting status bar height.
     CGFloat statusBarHeight =
         [[UIApplication sharedApplication] statusBarFrame].size.height;
-    CGRect containerViewFrame = [UIScreen mainScreen].bounds;
     containerViewFrame.origin.y += statusBarHeight;
     containerViewFrame.size.height -= statusBarHeight;
     _containerView.frame = containerViewFrame;
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm
index ba23358..a00e185 100644
--- a/ios/web/web_state/ui/crw_web_controller_unittest.mm
+++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -94,7 +94,8 @@
       @"<html><head><meta name='viewport' content="
        "'width=%f,minimum-scale=%f,maximum-scale=%f,initial-scale=%f,"
        "user-scalable=%@'/></head><body>Test</body></html>";
-  CGFloat width = CGRectGetWidth([UIScreen mainScreen].bounds) /
+  CGFloat width =
+      CGRectGetWidth(UIApplication.sharedApplication.keyWindow.bounds) /
       zoom_state.minimum_zoom_scale();
   BOOL scalability_enabled = scalability_type == PAGE_SCALABILITY_ENABLED;
   return [NSString
@@ -147,7 +148,8 @@
 
   // The value for web view OCMock objects to expect for |-setFrame:|.
   CGRect GetExpectedWebViewFrame() const {
-    CGSize container_view_size = [UIScreen mainScreen].bounds.size;
+    CGSize container_view_size =
+        UIApplication.sharedApplication.keyWindow.bounds.size;
     container_view_size.height -=
         CGRectGetHeight([UIApplication sharedApplication].statusBarFrame);
     return {CGPointZero, container_view_size};
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 1d9dc06e..e738a10 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -2126,8 +2126,12 @@
   // for validity.
   DCHECK(pip_surface_id_.is_valid());
 
-  if (client_)
+  // It is possible for |pip_surface_id_| to be valid when |client_| is not in
+  // Picture-in-Picture mode. In this case, do nothing.
+  if (client_ && client_->DisplayType() ==
+                     WebMediaPlayer::DisplayType::kPictureInPicture) {
     client_->PictureInPictureStopped();
+  }
 }
 
 void WebMediaPlayerImpl::ScheduleRestart() {
diff --git a/media/cdm/cdm_proxy.h b/media/cdm/cdm_proxy.h
index d735d20..000b974 100644
--- a/media/cdm/cdm_proxy.h
+++ b/media/cdm/cdm_proxy.h
@@ -45,10 +45,10 @@
     // No supported protocol. Used in failure cases.
     kNone,
     // Method using Intel CSME.
-    kIntelConvergedSecurityAndManageabilityEngine,
+    kIntel,
     // There will be more values in the future e.g. kD3D11RsaHardware,
     // kD3D11RsaSoftware to use the D3D11 RSA method.
-    kMax = kIntelConvergedSecurityAndManageabilityEngine,
+    kMax = kIntel,
   };
 
   enum class Function {
diff --git a/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm_proxy.cc b/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm_proxy.cc
index 67f6038..833fb33e 100644
--- a/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm_proxy.cc
+++ b/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm_proxy.cc
@@ -43,9 +43,8 @@
 void ClearKeyCdmProxy::Initialize(Client* client, InitializeCB init_cb) {
   DVLOG(1) << __func__;
 
-  std::move(init_cb).Run(
-      Status::kOk, Protocol::kIntelConvergedSecurityAndManageabilityEngine,
-      kClearKeyCdmProxyCryptoSessionId);
+  std::move(init_cb).Run(Status::kOk, Protocol::kIntel,
+                         kClearKeyCdmProxyCryptoSessionId);
 }
 
 void ClearKeyCdmProxy::Process(Function function,
diff --git a/media/gpu/windows/d3d11_cdm_proxy_unittest.cc b/media/gpu/windows/d3d11_cdm_proxy_unittest.cc
index d0829867..f0bda5e 100644
--- a/media/gpu/windows/d3d11_cdm_proxy_unittest.cc
+++ b/media/gpu/windows/d3d11_cdm_proxy_unittest.cc
@@ -53,8 +53,7 @@
 
 // The values doesn't matter as long as this is consistently used thruout the
 // test.
-const CdmProxy::Protocol kTestProtocol =
-    CdmProxy::Protocol::kIntelConvergedSecurityAndManageabilityEngine;
+const CdmProxy::Protocol kTestProtocol = CdmProxy::Protocol::kIntel;
 const CdmProxy::Function kTestFunction =
     CdmProxy::Function::kIntelNegotiateCryptoSessionKeyExchange;
 const uint32_t kTestFunctionId = 123;
diff --git a/media/mojo/services/mojo_cdm_proxy.cc b/media/mojo/services/mojo_cdm_proxy.cc
index d5161b59..95a1e6ee 100644
--- a/media/mojo/services/mojo_cdm_proxy.cc
+++ b/media/mojo/services/mojo_cdm_proxy.cc
@@ -43,9 +43,8 @@
   switch (protocol) {
     case CdmProxy::Protocol::kNone:
       return cdm::CdmProxyClient::Protocol::kNone;
-    case CdmProxy::Protocol::kIntelConvergedSecurityAndManageabilityEngine:
-      return cdm::CdmProxyClient::Protocol::
-          kIntelConvergedSecurityAndManageabilityEngine;
+    case CdmProxy::Protocol::kIntel:
+      return cdm::CdmProxyClient::Protocol::kIntel;
   }
 
   NOTREACHED() << "Unexpected protocol: " << static_cast<int32_t>(protocol);
diff --git a/net/BUILD.gn b/net/BUILD.gn
index faa1f0f1..79a9220 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -2481,6 +2481,7 @@
     "data/ssl/certificates/start_after_expiry.pem",
     "data/ssl/certificates/subjectAltName_sanity_check.pem",
     "data/ssl/certificates/subjectAltName_www_example_com.pem",
+    "data/ssl/certificates/test_can_sign_http_exchanges_extension.pem",
     "data/ssl/certificates/thawte.single.pem",
     "data/ssl/certificates/tls_feature_extension.pem",
     "data/ssl/certificates/trustcenter.websecurity.symantec.com.pem",
diff --git a/net/cert/asn1_util.cc b/net/cert/asn1_util.cc
index abba2d55..6acc61e7 100644
--- a/net/cert/asn1_util.cc
+++ b/net/cert/asn1_util.cc
@@ -147,6 +147,30 @@
   return true;
 }
 
+bool HasExtensionWithOID(base::StringPiece cert, der::Input extension_oid) {
+  bool present;
+  der::Parser extensions_parser;
+  if (!SeekToExtensions(der::Input(cert), &present, &extensions_parser))
+    return false;
+  if (!present)
+    return false;
+
+  while (extensions_parser.HasMore()) {
+    der::Parser extension_parser;
+    if (!extensions_parser.ReadSequence(&extension_parser))
+      return false;
+
+    der::Input oid;
+    if (!extension_parser.ReadTag(der::kOid, &oid))
+      return false;
+
+    if (oid == extension_oid)
+      return true;
+  }
+
+  return false;
+}
+
 }  // namespace
 
 bool ExtractSubjectFromDERCert(base::StringPiece cert,
@@ -203,31 +227,22 @@
 }
 
 bool HasTLSFeatureExtension(base::StringPiece cert) {
-  bool present;
-  der::Parser extensions_parser;
-  if (!SeekToExtensions(der::Input(cert), &present, &extensions_parser))
-    return false;
-  if (!present)
-    return false;
+  // kTLSFeatureExtensionOID is the DER encoding of the OID for the
+  // X.509 TLS Feature Extension.
+  static const uint8_t kTLSFeatureExtensionOID[] = {0x2B, 0x06, 0x01, 0x05,
+                                                    0x05, 0x07, 0x01, 0x18};
 
-  while (extensions_parser.HasMore()) {
-    der::Parser extension_parser;
-    if (!extensions_parser.ReadSequence(&extension_parser))
-      return false;
+  return HasExtensionWithOID(cert, der::Input(kTLSFeatureExtensionOID));
+}
 
-    der::Input oid;
-    if (!extension_parser.ReadTag(der::kOid, &oid))
-      return false;
+bool HasTestCanSignHttpExchangesExtension(base::StringPiece cert) {
+  // kTestCanSignHttpExchangesOid is the DER encoding of the OID for
+  // testCanSignHttpExchanges defined in:
+  // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html
+  static const uint8_t kTestCanSignHttpExchangesOid[] = {
+      0x2B, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x16};
 
-    // kTLSFeatureExtensionOID is the DER encoding of the OID for the
-    // X.509 TLS Feature Extension.
-    static const uint8_t kTLSFeatureExtensionOID[] = {0x2B, 0x06, 0x01, 0x05,
-                                                      0x05, 0x07, 0x01, 0x18};
-    if (oid == der::Input(kTLSFeatureExtensionOID))
-      return true;
-  }
-
-  return false;
+  return HasExtensionWithOID(cert, der::Input(kTestCanSignHttpExchangesOid));
 }
 
 bool ExtractSignatureAlgorithmsFromDERCert(
diff --git a/net/cert/asn1_util.h b/net/cert/asn1_util.h
index 96f3d2ab..1a57628b 100644
--- a/net/cert/asn1_util.h
+++ b/net/cert/asn1_util.h
@@ -41,6 +41,13 @@
 // present or if there was a parsing failure.
 NET_EXPORT_PRIVATE bool HasTLSFeatureExtension(base::StringPiece cert);
 
+// HasTestCanSignHttpExchangesExtension parses the DER encoded certificate
+// in |cert| and extracts the testCanSignHttpExchangesExtension extension
+// (https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html)
+// if present. Returns true if the extension was present, and false if
+// the extension was not present or if there was a parsing failure.
+NET_EXPORT bool HasTestCanSignHttpExchangesExtension(base::StringPiece cert);
+
 // Extracts the two (SEQUENCE) tag-length-values for the signature
 // AlgorithmIdentifiers in a DER encoded certificate. Does not use strict
 // parsing or validate the resulting AlgorithmIdentifiers.
diff --git a/net/cert/x509_certificate_unittest.cc b/net/cert/x509_certificate_unittest.cc
index 59142896..6eeb774 100644
--- a/net/cert/x509_certificate_unittest.cc
+++ b/net/cert/x509_certificate_unittest.cc
@@ -605,6 +605,26 @@
       x509_util::CryptoBufferAsStringPiece(cert->cert_buffer())));
 }
 
+TEST(X509CertificateTest, HasTestCanSignHttpExchangesExtension) {
+  base::FilePath certs_dir = GetTestCertsDirectory();
+  scoped_refptr<X509Certificate> cert = ImportCertFromFile(
+      certs_dir, "test_can_sign_http_exchanges_extension.pem");
+  ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
+
+  EXPECT_TRUE(asn1::HasTestCanSignHttpExchangesExtension(
+      x509_util::CryptoBufferAsStringPiece(cert->cert_buffer())));
+}
+
+TEST(X509CertificateTest, DoesNotHaveTestCanSignHttpExchangesExtension) {
+  base::FilePath certs_dir = GetTestCertsDirectory();
+  scoped_refptr<X509Certificate> cert =
+      ImportCertFromFile(certs_dir, "ok_cert.pem");
+  ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
+
+  EXPECT_FALSE(asn1::HasTestCanSignHttpExchangesExtension(
+      x509_util::CryptoBufferAsStringPiece(cert->cert_buffer())));
+}
+
 // Tests CRYPTO_BUFFER deduping via X509Certificate::CreateFromBuffer.  We
 // call X509Certificate::CreateFromBuffer several times and observe whether
 // it returns a cached or new CRYPTO_BUFFER.
diff --git a/net/data/ssl/certificates/test_can_sign_http_exchanges_extension.pem b/net/data/ssl/certificates/test_can_sign_http_exchanges_extension.pem
new file mode 100644
index 0000000..00f61ce
--- /dev/null
+++ b/net/data/ssl/certificates/test_can_sign_http_exchanges_extension.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDazCCAlOgAwIBAgIJAIymUztkzWQvMA0GCSqGSIb3DQEBCwUAMGAxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW
+aWV3MRAwDgYDVQQKDAdUZXN0IENBMRIwEAYDVQQDDAkxMjcuMC4wLjEwHhcNMTgw
+NjE4MDM1NjMxWhcNMTkwNjE4MDM1NjMxWjBgMQswCQYDVQQGEwJVUzETMBEGA1UE
+CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwH
+VGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4xMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAq3WemlGl/h0AYRAiQeLWG51rXk2ayySal/Dp9ovOsKqLarcZ
+JJiNFWhq71Aw3Mqu5pzdN10BMBIxSoBQXWU28XcjiZtIhqhQYyKUmEHJtkas3p4a
+V16MeG2SciwF9XpqBR8BGOTxsGclH1+qK0UgnCeLfwYjqxyATSl2UJF+ZeHvLaYl
+Z1MfuMUzt2mTILxg/7dblHuFcFiPvjcfNiQ6RdxC7y2SBnPL2us0AgJKm3n1/w5S
+zlf5PYccat7qdYe9BgQGWDa9pMQKGO6+9rm7SI8bt2cdUgnqS3ODHV5y5SnS3IjF
+KGBNujSyhIsJqNExjTKRw3nfI4E7b8NPO1mJCwIDAQABoygwJjAPBgNVHREECDAG
+hwR/AAABMBMGCisGAQQB1nkCARYBAf8EAgUAMA0GCSqGSIb3DQEBCwUAA4IBAQAM
+QDGGqhPiwz1OpJjzYBX5ruUu42mlxkkqdVKnEceLi9c4L1lFSpSSoowxWcpeBelG
+mqXxwVTYkrpN5+4sUexMBcIt8Lsd+po0XPN/JY9Tr2xC10jzQ+7fYaXH9l+38OaP
+Ne4lWjpgF2eUizJweFTugivnU1+7oRYoP9FibN7Oa/CX50eZL5onLkHka8LeOToF
+BlRIrk75U3JNyS+X5jN194tEJ+W0ZYGr955CTOpAmRH90pWcbUO991Zbuj2Sjidb
+WE7SHqatZ1wf7YNDN+hXYHOMl2YuiZ8Y7jQXJnXv5SW3EKKaPIv1kuOEOSXQcZ1Y
+jHLdGk8wx0wnZclbn5LK
+-----END CERTIFICATE-----
diff --git a/net/data/ssl/scripts/ee.cnf b/net/data/ssl/scripts/ee.cnf
index 1b0dd4c2..c6f09f0 100644
--- a/net/data/ssl/scripts/ee.cnf
+++ b/net/data/ssl/scripts/ee.cnf
@@ -65,6 +65,10 @@
 subjectAltName = IP:127.0.0.1
 1.3.6.1.5.5.7.1.24=DER:30:03:02:01:05
 
+[req_extensions_with_test_can_sign_http_exchanges]
+subjectAltName = IP:127.0.0.1
+1.3.6.1.4.1.11129.2.1.22 = critical,ASN1:NULL
+
 [req_localhost_san]
 subjectAltName = DNS:localhost
 
diff --git a/net/data/ssl/scripts/generate-test-certs.sh b/net/data/ssl/scripts/generate-test-certs.sh
index c5b4fe9..43c38aaa 100755
--- a/net/data/ssl/scripts/generate-test-certs.sh
+++ b/net/data/ssl/scripts/generate-test-certs.sh
@@ -472,6 +472,14 @@
   -extensions req_extensions_with_tls_feature \
   -nodes -config ee.cnf
 
+# Includes the testCanSignHttpExchanges extension
+openssl req -x509 -newkey rsa:2048 \
+  -keyout out/test_can_sign_http_exchanges_extension.key \
+  -out ../certificates/test_can_sign_http_exchanges_extension.pem \
+  -days 365 \
+  -extensions req_extensions_with_test_can_sign_http_exchanges \
+  -nodes -config ee.cnf
+
 # SHA-1 certificate issued by locally trusted CA
 openssl req \
   -config ../scripts/ee.cnf \
diff --git a/net/http/http_request_headers.cc b/net/http/http_request_headers.cc
index 49881ea..ec77236 100644
--- a/net/http/http_request_headers.cc
+++ b/net/http/http_request_headers.cc
@@ -40,6 +40,7 @@
 const char HttpRequestHeaders::kProxyConnection[] = "Proxy-Connection";
 const char HttpRequestHeaders::kRange[] = "Range";
 const char HttpRequestHeaders::kReferer[] = "Referer";
+const char HttpRequestHeaders::kSecOriginPolicy[] = "Sec-Origin-Policy";
 const char HttpRequestHeaders::kTransferEncoding[] = "Transfer-Encoding";
 const char HttpRequestHeaders::kTokenBinding[] = "Sec-Token-Binding";
 const char HttpRequestHeaders::kUserAgent[] = "User-Agent";
@@ -75,8 +76,14 @@
 HttpRequestHeaders::HttpRequestHeaders() = default;
 HttpRequestHeaders::HttpRequestHeaders(const HttpRequestHeaders& other) =
     default;
+HttpRequestHeaders::HttpRequestHeaders(HttpRequestHeaders&& other) = default;
 HttpRequestHeaders::~HttpRequestHeaders() = default;
 
+HttpRequestHeaders& HttpRequestHeaders::operator=(
+    const HttpRequestHeaders& other) = default;
+HttpRequestHeaders& HttpRequestHeaders::operator=(HttpRequestHeaders&& other) =
+    default;
+
 bool HttpRequestHeaders::GetHeader(const base::StringPiece& key,
                                    std::string* out) const {
   HeaderVector::const_iterator it = FindHeader(key);
diff --git a/net/http/http_request_headers.h b/net/http/http_request_headers.h
index c246f4f..acdbc8e 100644
--- a/net/http/http_request_headers.h
+++ b/net/http/http_request_headers.h
@@ -84,14 +84,19 @@
   static const char kProxyConnection[];
   static const char kRange[];
   static const char kReferer[];
+  static const char kSecOriginPolicy[];
   static const char kTransferEncoding[];
   static const char kTokenBinding[];
   static const char kUserAgent[];
 
   HttpRequestHeaders();
   HttpRequestHeaders(const HttpRequestHeaders& other);
+  HttpRequestHeaders(HttpRequestHeaders&& other);
   ~HttpRequestHeaders();
 
+  HttpRequestHeaders& operator=(const HttpRequestHeaders& other);
+  HttpRequestHeaders& operator=(HttpRequestHeaders&& other);
+
   bool IsEmpty() const { return headers_.empty(); }
 
   bool HasHeader(const base::StringPiece& key) const {
diff --git a/services/device/device_service.cc b/services/device/device_service.cc
index e080614..4a04fc5 100644
--- a/services/device/device_service.cc
+++ b/services/device/device_service.cc
@@ -235,7 +235,7 @@
 #if defined(OS_CHROMEOS)
 void DeviceService::BindMtpManagerRequest(mojom::MtpManagerRequest request) {
   if (!mtp_device_manager_)
-    mtp_device_manager_ = std::make_unique<MtpDeviceManager>();
+    mtp_device_manager_ = MtpDeviceManager::Initialize();
   mtp_device_manager_->AddBinding(std::move(request));
 }
 #endif
diff --git a/services/device/media_transfer_protocol/BUILD.gn b/services/device/media_transfer_protocol/BUILD.gn
index cd4fb27..8b23da5 100644
--- a/services/device/media_transfer_protocol/BUILD.gn
+++ b/services/device/media_transfer_protocol/BUILD.gn
@@ -26,8 +26,6 @@
   sources = [
     "media_transfer_protocol_daemon_client.cc",
     "media_transfer_protocol_daemon_client.h",
-    "media_transfer_protocol_manager.cc",
-    "media_transfer_protocol_manager.h",
     "mtp_device_manager.cc",
     "mtp_device_manager.h",
   ]
diff --git a/services/device/media_transfer_protocol/media_transfer_protocol_manager.cc b/services/device/media_transfer_protocol/media_transfer_protocol_manager.cc
deleted file mode 100644
index bb833e9a..0000000
--- a/services/device/media_transfer_protocol/media_transfer_protocol_manager.cc
+++ /dev/null
@@ -1,633 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "services/device/media_transfer_protocol/media_transfer_protocol_manager.h"
-
-#include <algorithm>
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/containers/flat_map.h"
-#include "base/containers/flat_set.h"
-#include "base/containers/queue.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequenced_task_runner.h"
-#include "base/stl_util.h"
-#include "base/threading/thread_checker.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "dbus/bus.h"
-#include "services/device/media_transfer_protocol/media_transfer_protocol_daemon_client.h"
-#include "third_party/cros_system_api/dbus/service_constants.h"
-
-namespace device {
-
-namespace {
-
-#if DCHECK_IS_ON()
-MediaTransferProtocolManager* g_media_transfer_protocol_manager = nullptr;
-#endif
-
-// The MediaTransferProtocolManager implementation.
-class MediaTransferProtocolManagerImpl : public MediaTransferProtocolManager {
- public:
-  MediaTransferProtocolManagerImpl()
-      : bus_(chromeos::DBusThreadManager::Get()->GetSystemBus()),
-        weak_ptr_factory_(this) {
-    // Listen for future mtpd service owner changes, in case it is not
-    // available right now. There is no guarantee that mtpd is running already.
-    mtpd_owner_changed_callback_ =
-        base::Bind(&MediaTransferProtocolManagerImpl::FinishSetupOnOriginThread,
-                   weak_ptr_factory_.GetWeakPtr());
-    if (bus_) {
-      bus_->ListenForServiceOwnerChange(mtpd::kMtpdServiceName,
-                                        mtpd_owner_changed_callback_);
-      bus_->GetServiceOwner(mtpd::kMtpdServiceName,
-                            mtpd_owner_changed_callback_);
-    }
-  }
-
-  ~MediaTransferProtocolManagerImpl() override {
-#if DCHECK_IS_ON()
-    DCHECK(g_media_transfer_protocol_manager);
-    g_media_transfer_protocol_manager = nullptr;
-#endif
-
-    if (bus_) {
-      bus_->UnlistenForServiceOwnerChange(mtpd::kMtpdServiceName,
-                                          mtpd_owner_changed_callback_);
-    }
-
-    VLOG(1) << "MediaTransferProtocolManager Shutdown completed";
-  }
-  // MediaTransferProtocolManager override.
-  void EnumerateStoragesAndSetClient(
-      mojom::MtpManagerClientAssociatedPtrInfo client,
-      mojom::MtpManager::EnumerateStoragesAndSetClientCallback callback)
-      override {
-    DCHECK(thread_checker_.CalledOnValidThread());
-
-    // Return all available storage info.
-    std::vector<mojom::MtpStorageInfoPtr> storage_info_ptr_list;
-    storage_info_ptr_list.reserve(storage_info_map_.size());
-    for (const auto& info : storage_info_map_)
-      storage_info_ptr_list.push_back(info.second.Clone());
-    std::move(callback).Run(std::move(storage_info_ptr_list));
-
-    // Set client.
-    if (!client.is_valid())
-      return;
-
-    client_.Bind(std::move(client));
-  }
-
-  // MediaTransferProtocolManager override.
-  void GetStorages(GetStoragesCallback callback) const override {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    std::vector<std::string> storages;
-    storages.reserve(storage_info_map_.size());
-    for (const auto& info : storage_info_map_)
-      storages.push_back(info.first);
-    std::move(callback).Run(storages);
-  }
-
-  // MediaTransferProtocolManager override.
-  void GetStorageInfo(
-      const std::string& storage_name,
-      mojom::MtpManager::GetStorageInfoCallback callback) const override {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    const auto it = storage_info_map_.find(storage_name);
-    mojom::MtpStorageInfoPtr storage_info =
-        it != storage_info_map_.end() ? it->second.Clone() : nullptr;
-    std::move(callback).Run(std::move(storage_info));
-  }
-
-  // MediaTransferProtocolManager override.
-  void GetStorageInfoFromDevice(
-      const std::string& storage_name,
-      mojom::MtpManager::GetStorageInfoFromDeviceCallback callback) override {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    if (!base::ContainsKey(storage_info_map_, storage_name) || !mtp_client_) {
-      std::move(callback).Run(nullptr, true /* error */);
-      return;
-    }
-    get_storage_info_from_device_callbacks_.push(std::move(callback));
-    mtp_client_->GetStorageInfoFromDevice(
-        storage_name,
-        base::Bind(
-            &MediaTransferProtocolManagerImpl::OnGetStorageInfoFromDevice,
-            weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(
-            &MediaTransferProtocolManagerImpl::OnGetStorageInfoFromDeviceError,
-            weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  // MediaTransferProtocolManager override.
-  void OpenStorage(const std::string& storage_name,
-                   const std::string& mode,
-                   const OpenStorageCallback& callback) override {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    if (!base::ContainsKey(storage_info_map_, storage_name) || !mtp_client_) {
-      callback.Run(std::string(), true);
-      return;
-    }
-    open_storage_callbacks_.push(callback);
-    mtp_client_->OpenStorage(
-        storage_name,
-        mode,
-        base::Bind(&MediaTransferProtocolManagerImpl::OnOpenStorage,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&MediaTransferProtocolManagerImpl::OnOpenStorageError,
-                   weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  // MediaTransferProtocolManager override.
-  void CloseStorage(const std::string& storage_handle,
-                    const CloseStorageCallback& callback) override {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
-      callback.Run(true);
-      return;
-    }
-    close_storage_callbacks_.push(std::make_pair(callback, storage_handle));
-    mtp_client_->CloseStorage(
-        storage_handle,
-        base::Bind(&MediaTransferProtocolManagerImpl::OnCloseStorage,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&MediaTransferProtocolManagerImpl::OnCloseStorageError,
-                   weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  void CreateDirectory(const std::string& storage_handle,
-                       uint32_t parent_id,
-                       const std::string& directory_name,
-                       const CreateDirectoryCallback& callback) override {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
-      callback.Run(true /* error */);
-      return;
-    }
-    create_directory_callbacks_.push(callback);
-    mtp_client_->CreateDirectory(
-        storage_handle, parent_id, directory_name,
-        base::Bind(&MediaTransferProtocolManagerImpl::OnCreateDirectory,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&MediaTransferProtocolManagerImpl::OnCreateDirectoryError,
-                   weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  // MediaTransferProtocolManager override.
-  void ReadDirectoryEntryIds(
-      const std::string& storage_handle,
-      uint32_t file_id,
-      mojom::MtpManager::ReadDirectoryEntryIdsCallback callback) override {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
-      std::move(callback).Run(std::vector<uint32_t>(), /*error=*/true);
-      return;
-    }
-    read_directory_callbacks_.push(std::move(callback));
-    mtp_client_->ReadDirectoryEntryIds(
-        storage_handle, file_id,
-        base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryEntryIds,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryError,
-                   weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  // MediaTransferProtocolManager override.
-  void ReadFileChunk(const std::string& storage_handle,
-                     uint32_t file_id,
-                     uint32_t offset,
-                     uint32_t count,
-                     const ReadFileCallback& callback) override {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
-      callback.Run(std::string(), true);
-      return;
-    }
-    read_file_callbacks_.push(callback);
-    mtp_client_->ReadFileChunk(
-        storage_handle, file_id, offset, count,
-        base::Bind(&MediaTransferProtocolManagerImpl::OnReadFile,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&MediaTransferProtocolManagerImpl::OnReadFileError,
-                   weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  void GetFileInfo(const std::string& storage_handle,
-                   const std::vector<uint32_t>& file_ids,
-                   mojom::MtpManager::GetFileInfoCallback callback) override {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
-      std::move(callback).Run(std::vector<device::mojom::MtpFileEntryPtr>(),
-                              /*error=*/true);
-      return;
-    }
-    get_file_info_callbacks_.push(std::move(callback));
-    mtp_client_->GetFileInfo(
-        storage_handle, file_ids,
-        base::Bind(&MediaTransferProtocolManagerImpl::OnGetFileInfo,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&MediaTransferProtocolManagerImpl::OnGetFileInfoError,
-                   weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  void RenameObject(const std::string& storage_handle,
-                    uint32_t object_id,
-                    const std::string& new_name,
-                    const RenameObjectCallback& callback) override {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
-      callback.Run(true /* error */);
-      return;
-    }
-    rename_object_callbacks_.push(callback);
-    mtp_client_->RenameObject(
-        storage_handle, object_id, new_name,
-        base::Bind(&MediaTransferProtocolManagerImpl::OnRenameObject,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&MediaTransferProtocolManagerImpl::OnRenameObjectError,
-                   weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  void CopyFileFromLocal(const std::string& storage_handle,
-                         const int source_file_descriptor,
-                         uint32_t parent_id,
-                         const std::string& file_name,
-                         const CopyFileFromLocalCallback& callback) override {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
-      callback.Run(true /* error */);
-      return;
-    }
-    copy_file_from_local_callbacks_.push(callback);
-    mtp_client_->CopyFileFromLocal(
-        storage_handle, source_file_descriptor, parent_id, file_name,
-        base::Bind(&MediaTransferProtocolManagerImpl::OnCopyFileFromLocal,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&MediaTransferProtocolManagerImpl::OnCopyFileFromLocalError,
-                   weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  void DeleteObject(const std::string& storage_handle,
-                    uint32_t object_id,
-                    const DeleteObjectCallback& callback) override {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
-      callback.Run(true /* error */);
-      return;
-    }
-    delete_object_callbacks_.push(callback);
-    mtp_client_->DeleteObject(
-        storage_handle, object_id,
-        base::Bind(&MediaTransferProtocolManagerImpl::OnDeleteObject,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&MediaTransferProtocolManagerImpl::OnDeleteObjectError,
-                   weak_ptr_factory_.GetWeakPtr()));
-  }
-
- private:
-  // Map of storage names to storage info.
-  using GetStorageInfoFromDeviceCallbackQueue =
-      base::queue<mojom::MtpManager::GetStorageInfoFromDeviceCallback>;
-  // Callback queues - DBus communication is in-order, thus callbacks are
-  // received in the same order as the requests.
-  using OpenStorageCallbackQueue = base::queue<OpenStorageCallback>;
-  // (callback, handle)
-  using CloseStorageCallbackQueue =
-      base::queue<std::pair<CloseStorageCallback, std::string>>;
-  using CreateDirectoryCallbackQueue = base::queue<CreateDirectoryCallback>;
-  using ReadDirectoryCallbackQueue =
-      base::queue<mojom::MtpManager::ReadDirectoryEntryIdsCallback>;
-  using ReadFileCallbackQueue = base::queue<ReadFileCallback>;
-  using GetFileInfoCallbackQueue =
-      base::queue<mojom::MtpManager::GetFileInfoCallback>;
-  using RenameObjectCallbackQueue = base::queue<RenameObjectCallback>;
-  using CopyFileFromLocalCallbackQueue = base::queue<CopyFileFromLocalCallback>;
-  using DeleteObjectCallbackQueue = base::queue<DeleteObjectCallback>;
-
-  void OnStorageAttached(const std::string& storage_name) {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    mtp_client_->GetStorageInfo(
-        storage_name,
-        base::Bind(&MediaTransferProtocolManagerImpl::OnGetStorageInfo,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::DoNothing());
-  }
-
-  void OnStorageDetached(const std::string& storage_name) {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    if (storage_info_map_.erase(storage_name) == 0) {
-      // This can happen for a storage where
-      // MediaTransferProtocolDaemonClient::GetStorageInfo() failed.
-      // Return to avoid giving client phantom detach events.
-      return;
-    }
-
-    // Notify the bound MtpManagerClient.
-    if (client_) {
-      client_->StorageDetached(storage_name);
-    }
-  }
-
-  void OnStorageChanged(bool is_attach, const std::string& storage_name) {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    DCHECK(mtp_client_);
-    if (is_attach)
-      OnStorageAttached(storage_name);
-    else
-      OnStorageDetached(storage_name);
-  }
-
-  void OnEnumerateStorages(const std::vector<std::string>& storage_names) {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    DCHECK(mtp_client_);
-    for (const auto& name : storage_names) {
-      if (base::ContainsKey(storage_info_map_, name)) {
-        // OnStorageChanged() might have gotten called first.
-        continue;
-      }
-      OnStorageAttached(name);
-    }
-  }
-
-  void OnGetStorageInfo(const mojom::MtpStorageInfo& storage_info) {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    const std::string& storage_name = storage_info.storage_name;
-    if (base::ContainsKey(storage_info_map_, storage_name)) {
-      // This should not happen, since MediaTransferProtocolManagerImpl should
-      // only call EnumerateStorages() once, which populates |storage_info_map_|
-      // with the already-attached devices.
-      // After that, all incoming signals are either for new storage
-      // attachments, which should not be in |storage_info_map_|, or for
-      // storage detachments, which do not add to |storage_info_map_|.
-      // Return to avoid giving client phantom detach events.
-      NOTREACHED();
-      return;
-    }
-
-    // New storage. Add it and let the bound client know.
-    storage_info_map_.insert(std::make_pair(storage_name, storage_info));
-
-    if (client_) {
-      client_->StorageAttached(storage_info.Clone());
-    }
-  }
-
-  void OnGetStorageInfoFromDevice(const mojom::MtpStorageInfo& storage_info) {
-    std::move(get_storage_info_from_device_callbacks_.front())
-        .Run(storage_info.Clone(), false /* no error */);
-    get_storage_info_from_device_callbacks_.pop();
-  }
-
-  void OnGetStorageInfoFromDeviceError() {
-    std::move(get_storage_info_from_device_callbacks_.front())
-        .Run(nullptr, true /* error */);
-    get_storage_info_from_device_callbacks_.pop();
-  }
-
-  void OnOpenStorage(const std::string& handle) {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    if (!base::ContainsKey(handles_, handle)) {
-      handles_.insert(handle);
-      open_storage_callbacks_.front().Run(handle, false);
-    } else {
-      NOTREACHED();
-      open_storage_callbacks_.front().Run(std::string(), true);
-    }
-    open_storage_callbacks_.pop();
-  }
-
-  void OnOpenStorageError() {
-    open_storage_callbacks_.front().Run(std::string(), true);
-    open_storage_callbacks_.pop();
-  }
-
-  void OnCloseStorage() {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    const std::string& handle = close_storage_callbacks_.front().second;
-    if (base::ContainsKey(handles_, handle)) {
-      handles_.erase(handle);
-      close_storage_callbacks_.front().first.Run(false);
-    } else {
-      NOTREACHED();
-      close_storage_callbacks_.front().first.Run(true);
-    }
-    close_storage_callbacks_.pop();
-  }
-
-  void OnCloseStorageError() {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    close_storage_callbacks_.front().first.Run(true);
-    close_storage_callbacks_.pop();
-  }
-
-  void OnCreateDirectory() {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    create_directory_callbacks_.front().Run(false /* no error */);
-    create_directory_callbacks_.pop();
-  }
-
-  void OnCreateDirectoryError() {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    create_directory_callbacks_.front().Run(true /* error */);
-    create_directory_callbacks_.pop();
-  }
-
-  void OnReadDirectoryEntryIds(const std::vector<uint32_t>& file_ids) {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    std::move(read_directory_callbacks_.front()).Run(file_ids, /*error=*/false);
-    read_directory_callbacks_.pop();
-  }
-
-  void OnReadDirectoryError() {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    std::move(read_directory_callbacks_.front())
-        .Run(std::vector<uint32_t>(), /*error=*/true);
-    read_directory_callbacks_.pop();
-  }
-
-  void OnReadFile(const std::string& data) {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    read_file_callbacks_.front().Run(data, false);
-    read_file_callbacks_.pop();
-  }
-
-  void OnReadFileError() {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    read_file_callbacks_.front().Run(std::string(), true);
-    read_file_callbacks_.pop();
-  }
-
-  void OnGetFileInfo(const std::vector<mojom::MtpFileEntry>& entries) {
-    DCHECK(thread_checker_.CalledOnValidThread());
-
-    std::vector<device::mojom::MtpFileEntryPtr> ret(entries.size());
-    for (size_t i = 0; i < entries.size(); ++i)
-      ret[i] = entries[i].Clone();
-    std::move(get_file_info_callbacks_.front())
-        .Run(std::move(ret), /*error=*/false);
-    get_file_info_callbacks_.pop();
-  }
-
-  void OnGetFileInfoError() {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    std::move(get_file_info_callbacks_.front())
-        .Run(std::vector<device::mojom::MtpFileEntryPtr>(), /*error=*/true);
-    get_file_info_callbacks_.pop();
-  }
-
-  void OnRenameObject() {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    rename_object_callbacks_.front().Run(false /* no error */);
-    rename_object_callbacks_.pop();
-  }
-
-  void OnRenameObjectError() {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    rename_object_callbacks_.front().Run(true /* error */);
-    rename_object_callbacks_.pop();
-  }
-
-  void OnCopyFileFromLocal() {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    copy_file_from_local_callbacks_.front().Run(false /* no error */);
-    copy_file_from_local_callbacks_.pop();
-  }
-
-  void OnCopyFileFromLocalError() {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    copy_file_from_local_callbacks_.front().Run(true /* error */);
-    copy_file_from_local_callbacks_.pop();
-  }
-
-  void OnDeleteObject() {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    delete_object_callbacks_.front().Run(false /* no error */);
-    delete_object_callbacks_.pop();
-  }
-
-  void OnDeleteObjectError() {
-    DCHECK(thread_checker_.CalledOnValidThread());
-    delete_object_callbacks_.front().Run(true /* error */);
-    delete_object_callbacks_.pop();
-  }
-
-  // Callback to finish initialization after figuring out if the mtpd service
-  // has an owner, or if the service owner has changed.
-  // |mtpd_service_owner| contains the name of the current owner, if any.
-  void FinishSetupOnOriginThread(const std::string& mtpd_service_owner) {
-    DCHECK(thread_checker_.CalledOnValidThread());
-
-    if (mtpd_service_owner == current_mtpd_owner_)
-      return;
-
-    // In the case of a new service owner, clear |storage_info_map_|.
-    // Assume all storages have been disconnected. If there is a new service
-    // owner, reconnecting to it will reconnect all the storages as well.
-
-    // Save a copy of |storage_info_map_| keys as |storage_info_map_| can
-    // change in OnStorageDetached().
-    std::vector<std::string> storage_names;
-    storage_names.reserve(storage_info_map_.size());
-    for (const auto& info : storage_info_map_)
-      storage_names.push_back(info.first);
-
-    for (const auto& name : storage_names)
-      OnStorageDetached(name);
-
-    if (mtpd_service_owner.empty()) {
-      current_mtpd_owner_.clear();
-      mtp_client_.reset();
-      return;
-    }
-
-    current_mtpd_owner_ = mtpd_service_owner;
-
-    // |bus_| must be valid here. Otherwise, how did this method get called as a
-    // callback in the first place?
-    DCHECK(bus_);
-    mtp_client_ = MediaTransferProtocolDaemonClient::Create(bus_.get());
-
-    // Set up signals and start initializing |storage_info_map_|.
-    mtp_client_->ListenForChanges(
-        base::Bind(&MediaTransferProtocolManagerImpl::OnStorageChanged,
-                   weak_ptr_factory_.GetWeakPtr()));
-    mtp_client_->EnumerateStorages(
-        base::Bind(&MediaTransferProtocolManagerImpl::OnEnumerateStorages,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::DoNothing());
-  }
-
-  // Mtpd DBus client.
-  std::unique_ptr<MediaTransferProtocolDaemonClient> mtp_client_;
-
-  // And a D-Bus session for talking to mtpd. Note: In production, this is never
-  // a nullptr, but in tests it oftentimes is. It may be too much work for
-  // DBusThreadManager to provide a bus in unit tests.
-  scoped_refptr<dbus::Bus> const bus_;
-
-  // MtpManager client who keeps tuned on attachment / detachment events.
-  // Currently, storage_monitor::StorageMonitorCros is supposed to be the
-  // only client.
-  mojom::MtpManagerClientAssociatedPtr client_;
-
-  // Map to keep track of attached storages by name.
-  base::flat_map<std::string, mojom::MtpStorageInfo> storage_info_map_;
-
-  // Set of open storage handles.
-  base::flat_set<std::string> handles_;
-
-  dbus::Bus::GetServiceOwnerCallback mtpd_owner_changed_callback_;
-
-  std::string current_mtpd_owner_;
-
-  // Queued callbacks.
-  // These queues are needed becasue MediaTransferProtocolDaemonClient provides
-  // different callbacks for result(success_callback, error_callback) with
-  // MediaTransferProtocolManager, so a passed callback for a method in this
-  // class will be referred in both success_callback and error_callback for
-  // underline MediaTransferProtocolDaemonClient, and it is also the case for
-  // mojom interfaces, as all mojom methods are defined as OnceCallback.
-  GetStorageInfoFromDeviceCallbackQueue get_storage_info_from_device_callbacks_;
-  OpenStorageCallbackQueue open_storage_callbacks_;
-  CloseStorageCallbackQueue close_storage_callbacks_;
-  CreateDirectoryCallbackQueue create_directory_callbacks_;
-  ReadDirectoryCallbackQueue read_directory_callbacks_;
-  ReadFileCallbackQueue read_file_callbacks_;
-  GetFileInfoCallbackQueue get_file_info_callbacks_;
-  RenameObjectCallbackQueue rename_object_callbacks_;
-  CopyFileFromLocalCallbackQueue copy_file_from_local_callbacks_;
-  DeleteObjectCallbackQueue delete_object_callbacks_;
-
-  base::ThreadChecker thread_checker_;
-
-  base::WeakPtrFactory<MediaTransferProtocolManagerImpl> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaTransferProtocolManagerImpl);
-};
-
-}  // namespace
-
-// static
-std::unique_ptr<MediaTransferProtocolManager>
-MediaTransferProtocolManager::Initialize() {
-  auto manager = std::make_unique<MediaTransferProtocolManagerImpl>();
-
-  VLOG(1) << "MediaTransferProtocolManager initialized";
-
-#if DCHECK_IS_ON()
-  DCHECK(!g_media_transfer_protocol_manager);
-  g_media_transfer_protocol_manager = manager.get();
-#endif
-
-  return manager;
-}
-
-}  // namespace device
diff --git a/services/device/media_transfer_protocol/media_transfer_protocol_manager.h b/services/device/media_transfer_protocol/media_transfer_protocol_manager.h
deleted file mode 100644
index 64bbc90..0000000
--- a/services/device/media_transfer_protocol/media_transfer_protocol_manager.h
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SERVICES_DEVICE_MEDIA_TRANSFER_PROTOCOL_MEDIA_TRANSFER_PROTOCOL_MANAGER_H_
-#define SERVICES_DEVICE_MEDIA_TRANSFER_PROTOCOL_MEDIA_TRANSFER_PROTOCOL_MANAGER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/memory/ref_counted.h"
-#include "build/build_config.h"
-#include "services/device/public/mojom/mtp_file_entry.mojom.h"
-#include "services/device/public/mojom/mtp_manager.mojom.h"
-#include "services/device/public/mojom/mtp_storage_info.mojom.h"
-
-#if !defined(OS_CHROMEOS)
-#error "Only used on ChromeOS"
-#endif
-
-namespace device {
-
-// This class handles the interaction with mtpd.
-class MediaTransferProtocolManager {
- public:
-  // A callback to handle the result of GetStorages().
-  // The argument is the returned vector of available MTP storage names.
-  using GetStoragesCallback =
-      base::OnceCallback<void(const std::vector<std::string>& storages)>;
-
-  // A callback to handle the result of OpenStorage.
-  // The first argument is the returned handle.
-  // The second argument is true if there was an error.
-  using OpenStorageCallback =
-      base::Callback<void(const std::string& handle, bool error)>;
-
-  // A callback to handle the result of CloseStorage.
-  // The argument is true if there was an error.
-  using CloseStorageCallback = base::Callback<void(bool error)>;
-
-  // A callback to handle the result of CreateDirectory.
-  // The first argument is true if there was an error.
-  using CreateDirectoryCallback = base::Callback<void(bool error)>;
-
-  // A callback to handle the result of ReadFileChunk.
-  // The first argument is a string containing the file data.
-  // The second argument is true if there was an error.
-  using ReadFileCallback =
-      base::Callback<void(const std::string& data, bool error)>;
-
-  // A callback to handle the result of RenameObject.
-  // The first argument is true if there was an error.
-  using RenameObjectCallback = base::Callback<void(bool error)>;
-
-  // A callback to handle the result of CopyFileFromLocal.
-  // The first argument is true if there was an error.
-  using CopyFileFromLocalCallback = base::Callback<void(bool error)>;
-
-  // A callback to handle the result of DeleteObject.
-  // The first argument is true if there was an error.
-  using DeleteObjectCallback = base::Callback<void(bool error)>;
-
-  virtual ~MediaTransferProtocolManager() {}
-
-  // This is a combined interface to get existing storages and set a
-  // client for incoming storage change events. It is designed to reduce
-  // async calls and eliminate a potential race condition between
-  // the client being set and storage updates being made.
-  virtual void EnumerateStoragesAndSetClient(
-      mojom::MtpManagerClientAssociatedPtrInfo client,
-      mojom::MtpManager::EnumerateStoragesAndSetClientCallback callback) = 0;
-
-  // Gets all available MTP storages and runs |callback|.
-  virtual void GetStorages(GetStoragesCallback callback) const = 0;
-
-  // Gets the metadata for |storage_name| and runs |callback|.
-  virtual void GetStorageInfo(
-      const std::string& storage_name,
-      mojom::MtpManager::GetStorageInfoCallback callback) const = 0;
-
-  // Read the metadata of |storage_name| from device and runs |callback|.
-  virtual void GetStorageInfoFromDevice(
-      const std::string& storage_name,
-      mojom::MtpManager::GetStorageInfoFromDeviceCallback callback) = 0;
-
-  // Opens |storage_name| in |mode| and runs |callback|.
-  virtual void OpenStorage(const std::string& storage_name,
-                           const std::string& mode,
-                           const OpenStorageCallback& callback) = 0;
-
-  // Close |storage_handle| and runs |callback|.
-  virtual void CloseStorage(const std::string& storage_handle,
-                            const CloseStorageCallback& callback) = 0;
-
-  // Creates |directory_name| in |parent_id|.
-  virtual void CreateDirectory(const std::string& storage_handle,
-                               uint32_t parent_id,
-                               const std::string& directory_name,
-                               const CreateDirectoryCallback& callback) = 0;
-
-  // Reads IDs of directory entries from |file_id| on |storage_handle| and runs
-  // |callback|.
-  virtual void ReadDirectoryEntryIds(
-      const std::string& storage_handle,
-      uint32_t file_id,
-      mojom::MtpManager::ReadDirectoryEntryIdsCallback callback) = 0;
-
-  // Reads file data from |file_id| on |storage_handle| and runs |callback|.
-  // Reads |count| bytes of data starting at |offset|.
-  virtual void ReadFileChunk(const std::string& storage_handle,
-                             uint32_t file_id,
-                             uint32_t offset,
-                             uint32_t count,
-                             const ReadFileCallback& callback) = 0;
-
-  // Gets the metadata for files on |storage_handle| with |file_ids|.
-  // Runs |callback| with the results.
-  // Use mojom::MtpManager::GetFileInfoCallback directly to get prepared for
-  // future merge.
-  virtual void GetFileInfo(const std::string& storage_handle,
-                           const std::vector<uint32_t>& file_ids,
-                           mojom::MtpManager::GetFileInfoCallback callback) = 0;
-
-  // Renames |object_id| to |new_name|.
-  virtual void RenameObject(const std::string& storage_handle,
-                            uint32_t object_id,
-                            const std::string& new_name,
-                            const RenameObjectCallback& callback) = 0;
-
-  // Copies the file from |source_file_descriptor| to |file_name| on
-  // |parent_id|.
-  virtual void CopyFileFromLocal(const std::string& storage_handle,
-                                 const int source_file_descriptor,
-                                 uint32_t parent_id,
-                                 const std::string& file_name,
-                                 const CopyFileFromLocalCallback& callback) = 0;
-
-  // Deletes |object_id|.
-  virtual void DeleteObject(const std::string& storage_handle,
-                            uint32_t object_id,
-                            const DeleteObjectCallback& callback) = 0;
-
-  // Creates and returns the global MediaTransferProtocolManager instance.
-  static std::unique_ptr<MediaTransferProtocolManager> Initialize();
-};
-
-}  // namespace device
-
-#endif  // SERVICES_DEVICE_MEDIA_TRANSFER_PROTOCOL_MEDIA_TRANSFER_PROTOCOL_MANAGER_H_
diff --git a/services/device/media_transfer_protocol/mtp_device_manager.cc b/services/device/media_transfer_protocol/mtp_device_manager.cc
index 6fa8ba2..18ab3b4 100644
--- a/services/device/media_transfer_protocol/mtp_device_manager.cc
+++ b/services/device/media_transfer_protocol/mtp_device_manager.cc
@@ -4,16 +4,50 @@
 
 #include "services/device/media_transfer_protocol/mtp_device_manager.h"
 
-#include <utility>
-#include <vector>
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "dbus/bus.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace device {
 
-MtpDeviceManager::MtpDeviceManager()
-    : media_transfer_protocol_manager_(
-          MediaTransferProtocolManager::Initialize()) {}
+namespace {
 
-MtpDeviceManager::~MtpDeviceManager() {}
+#if DCHECK_IS_ON()
+MtpDeviceManager* g_mtp_device_manager = nullptr;
+#endif
+
+}  // namespace
+
+MtpDeviceManager::MtpDeviceManager()
+    : bus_(chromeos::DBusThreadManager::Get()->GetSystemBus()),
+      weak_ptr_factory_(this) {
+  // Listen for future mtpd service owner changes, in case it is not
+  // available right now. There is no guarantee that mtpd is running already.
+  dbus::Bus::GetServiceOwnerCallback mtpd_owner_changed_callback =
+      base::Bind(&MtpDeviceManager::FinishSetupOnOriginThread,
+                 weak_ptr_factory_.GetWeakPtr());
+  if (bus_) {
+    bus_->ListenForServiceOwnerChange(mtpd::kMtpdServiceName,
+                                      mtpd_owner_changed_callback);
+    bus_->GetServiceOwner(mtpd::kMtpdServiceName, mtpd_owner_changed_callback);
+  }
+}
+
+MtpDeviceManager::~MtpDeviceManager() {
+#if DCHECK_IS_ON()
+  DCHECK(g_mtp_device_manager);
+  g_mtp_device_manager = nullptr;
+#endif
+
+  if (bus_) {
+    bus_->UnlistenForServiceOwnerChange(
+        mtpd::kMtpdServiceName,
+        base::Bind(&MtpDeviceManager::FinishSetupOnOriginThread,
+                   weak_ptr_factory_.GetWeakPtr()));
+  }
+
+  VLOG(1) << "MtpDeviceManager Shutdown completed";
+}
 
 void MtpDeviceManager::AddBinding(mojom::MtpManagerRequest request) {
   bindings_.AddBinding(this, std::move(request));
@@ -22,51 +56,114 @@
 void MtpDeviceManager::EnumerateStoragesAndSetClient(
     mojom::MtpManagerClientAssociatedPtrInfo client,
     EnumerateStoragesAndSetClientCallback callback) {
-  media_transfer_protocol_manager_->EnumerateStoragesAndSetClient(
-      std::move(client), std::move(callback));
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  // Return all available storage info.
+  std::vector<mojom::MtpStorageInfoPtr> storage_info_ptr_list;
+  storage_info_ptr_list.reserve(storage_info_map_.size());
+  for (const auto& info : storage_info_map_)
+    storage_info_ptr_list.push_back(info.second.Clone());
+  std::move(callback).Run(std::move(storage_info_ptr_list));
+
+  // Set client.
+  if (!client.is_valid())
+    return;
+
+  client_.Bind(std::move(client));
 }
 
 void MtpDeviceManager::GetStorageInfo(const std::string& storage_name,
                                       GetStorageInfoCallback callback) {
-  media_transfer_protocol_manager_->GetStorageInfo(storage_name,
-                                                   std::move(callback));
+  DCHECK(thread_checker_.CalledOnValidThread());
+  const auto it = storage_info_map_.find(storage_name);
+  mojom::MtpStorageInfoPtr storage_info =
+      it != storage_info_map_.end() ? it->second.Clone() : nullptr;
+  std::move(callback).Run(std::move(storage_info));
 }
 
 void MtpDeviceManager::GetStorageInfoFromDevice(
     const std::string& storage_name,
     GetStorageInfoFromDeviceCallback callback) {
-  media_transfer_protocol_manager_->GetStorageInfoFromDevice(
-      storage_name, std::move(callback));
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!base::ContainsKey(storage_info_map_, storage_name) || !mtp_client_) {
+    std::move(callback).Run(nullptr, true /* error */);
+    return;
+  }
+  get_storage_info_from_device_callbacks_.push(std::move(callback));
+  mtp_client_->GetStorageInfoFromDevice(
+      storage_name,
+      base::Bind(&MtpDeviceManager::OnGetStorageInfoFromDevice,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&MtpDeviceManager::OnGetStorageInfoFromDeviceError,
+                 weak_ptr_factory_.GetWeakPtr()));
 }
 
 void MtpDeviceManager::OpenStorage(const std::string& storage_name,
                                    const std::string& mode,
                                    OpenStorageCallback callback) {
-  media_transfer_protocol_manager_->OpenStorage(
-      storage_name, mode, base::AdaptCallbackForRepeating(std::move(callback)));
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!base::ContainsKey(storage_info_map_, storage_name) || !mtp_client_) {
+    std::move(callback).Run(std::string(), true);
+    return;
+  }
+  open_storage_callbacks_.push(std::move(callback));
+  mtp_client_->OpenStorage(storage_name, mode,
+                           base::Bind(&MtpDeviceManager::OnOpenStorage,
+                                      weak_ptr_factory_.GetWeakPtr()),
+                           base::Bind(&MtpDeviceManager::OnOpenStorageError,
+                                      weak_ptr_factory_.GetWeakPtr()));
 }
 
 void MtpDeviceManager::CloseStorage(const std::string& storage_handle,
                                     CloseStorageCallback callback) {
-  media_transfer_protocol_manager_->CloseStorage(
-      storage_handle, base::AdaptCallbackForRepeating(std::move(callback)));
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
+    std::move(callback).Run(true);
+    return;
+  }
+  close_storage_callbacks_.push(
+      std::make_pair(std::move(callback), storage_handle));
+  mtp_client_->CloseStorage(storage_handle,
+                            base::Bind(&MtpDeviceManager::OnCloseStorage,
+                                       weak_ptr_factory_.GetWeakPtr()),
+                            base::Bind(&MtpDeviceManager::OnCloseStorageError,
+                                       weak_ptr_factory_.GetWeakPtr()));
 }
 
 void MtpDeviceManager::CreateDirectory(const std::string& storage_handle,
                                        uint32_t parent_id,
                                        const std::string& directory_name,
                                        CreateDirectoryCallback callback) {
-  media_transfer_protocol_manager_->CreateDirectory(
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
+    std::move(callback).Run(true /* error */);
+    return;
+  }
+  create_directory_callbacks_.push(std::move(callback));
+  mtp_client_->CreateDirectory(
       storage_handle, parent_id, directory_name,
-      base::AdaptCallbackForRepeating(std::move(callback)));
+      base::Bind(&MtpDeviceManager::OnCreateDirectory,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&MtpDeviceManager::OnCreateDirectoryError,
+                 weak_ptr_factory_.GetWeakPtr()));
 }
 
 void MtpDeviceManager::ReadDirectoryEntryIds(
     const std::string& storage_handle,
     uint32_t file_id,
     ReadDirectoryEntryIdsCallback callback) {
-  media_transfer_protocol_manager_->ReadDirectoryEntryIds(
-      storage_handle, file_id, std::move(callback));
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
+    std::move(callback).Run(std::vector<uint32_t>(), /*error=*/true);
+    return;
+  }
+  read_directory_callbacks_.push(std::move(callback));
+  mtp_client_->ReadDirectoryEntryIds(
+      storage_handle, file_id,
+      base::Bind(&MtpDeviceManager::OnReadDirectoryEntryIds,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&MtpDeviceManager::OnReadDirectoryError,
+                 weak_ptr_factory_.GetWeakPtr()));
 }
 
 void MtpDeviceManager::ReadFileChunk(const std::string& storage_handle,
@@ -74,25 +171,51 @@
                                      uint32_t offset,
                                      uint32_t count,
                                      ReadFileChunkCallback callback) {
-  media_transfer_protocol_manager_->ReadFileChunk(
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
+    std::move(callback).Run(std::string(), true);
+    return;
+  }
+  read_file_callbacks_.push(std::move(callback));
+  mtp_client_->ReadFileChunk(
       storage_handle, file_id, offset, count,
-      base::AdaptCallbackForRepeating(std::move(callback)));
+      base::Bind(&MtpDeviceManager::OnReadFile, weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&MtpDeviceManager::OnReadFileError,
+                 weak_ptr_factory_.GetWeakPtr()));
 }
 
 void MtpDeviceManager::GetFileInfo(const std::string& storage_handle,
                                    const std::vector<uint32_t>& file_ids,
                                    GetFileInfoCallback callback) {
-  media_transfer_protocol_manager_->GetFileInfo(storage_handle, file_ids,
-                                                std::move(callback));
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
+    std::move(callback).Run(std::vector<device::mojom::MtpFileEntryPtr>(),
+                            /*error=*/true);
+    return;
+  }
+  get_file_info_callbacks_.push(std::move(callback));
+  mtp_client_->GetFileInfo(storage_handle, file_ids,
+                           base::Bind(&MtpDeviceManager::OnGetFileInfo,
+                                      weak_ptr_factory_.GetWeakPtr()),
+                           base::Bind(&MtpDeviceManager::OnGetFileInfoError,
+                                      weak_ptr_factory_.GetWeakPtr()));
 }
 
 void MtpDeviceManager::RenameObject(const std::string& storage_handle,
                                     uint32_t object_id,
                                     const std::string& new_name,
                                     RenameObjectCallback callback) {
-  media_transfer_protocol_manager_->RenameObject(
-      storage_handle, object_id, new_name,
-      base::AdaptCallbackForRepeating(std::move(callback)));
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
+    std::move(callback).Run(true /* error */);
+    return;
+  }
+  rename_object_callbacks_.push(std::move(callback));
+  mtp_client_->RenameObject(storage_handle, object_id, new_name,
+                            base::Bind(&MtpDeviceManager::OnRenameObject,
+                                       weak_ptr_factory_.GetWeakPtr()),
+                            base::Bind(&MtpDeviceManager::OnRenameObjectError,
+                                       weak_ptr_factory_.GetWeakPtr()));
 }
 
 void MtpDeviceManager::CopyFileFromLocal(const std::string& storage_handle,
@@ -100,17 +223,304 @@
                                          uint32_t parent_id,
                                          const std::string& file_name,
                                          CopyFileFromLocalCallback callback) {
-  media_transfer_protocol_manager_->CopyFileFromLocal(
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
+    std::move(callback).Run(true /* error */);
+    return;
+  }
+  copy_file_from_local_callbacks_.push(std::move(callback));
+  mtp_client_->CopyFileFromLocal(
       storage_handle, source_file_descriptor, parent_id, file_name,
-      base::AdaptCallbackForRepeating(std::move(callback)));
+      base::Bind(&MtpDeviceManager::OnCopyFileFromLocal,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&MtpDeviceManager::OnCopyFileFromLocalError,
+                 weak_ptr_factory_.GetWeakPtr()));
 }
 
 void MtpDeviceManager::DeleteObject(const std::string& storage_handle,
                                     uint32_t object_id,
                                     DeleteObjectCallback callback) {
-  media_transfer_protocol_manager_->DeleteObject(
-      storage_handle, object_id,
-      base::AdaptCallbackForRepeating(std::move(callback)));
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) {
+    std::move(callback).Run(true /* error */);
+    return;
+  }
+  delete_object_callbacks_.push(std::move(callback));
+  mtp_client_->DeleteObject(storage_handle, object_id,
+                            base::Bind(&MtpDeviceManager::OnDeleteObject,
+                                       weak_ptr_factory_.GetWeakPtr()),
+                            base::Bind(&MtpDeviceManager::OnDeleteObjectError,
+                                       weak_ptr_factory_.GetWeakPtr()));
+}
+
+// private methods
+void MtpDeviceManager::OnStorageAttached(const std::string& storage_name) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  mtp_client_->GetStorageInfo(storage_name,
+                              base::Bind(&MtpDeviceManager::OnGetStorageInfo,
+                                         weak_ptr_factory_.GetWeakPtr()),
+                              base::DoNothing());
+}
+
+void MtpDeviceManager::OnStorageDetached(const std::string& storage_name) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (storage_info_map_.erase(storage_name) == 0) {
+    // This can happen for a storage where
+    // MediaTransferProtocolDaemonClient::GetStorageInfo() failed.
+    // Return to avoid giving client phantom detach events.
+    return;
+  }
+
+  // Notify the bound MtpManagerClient.
+  if (client_) {
+    client_->StorageDetached(storage_name);
+  }
+}
+
+void MtpDeviceManager::OnStorageChanged(bool is_attach,
+                                        const std::string& storage_name) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(mtp_client_);
+  if (is_attach)
+    OnStorageAttached(storage_name);
+  else
+    OnStorageDetached(storage_name);
+}
+
+void MtpDeviceManager::OnEnumerateStorages(
+    const std::vector<std::string>& storage_names) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(mtp_client_);
+  for (const auto& name : storage_names) {
+    if (base::ContainsKey(storage_info_map_, name)) {
+      // OnStorageChanged() might have gotten called first.
+      continue;
+    }
+    OnStorageAttached(name);
+  }
+}
+
+void MtpDeviceManager::OnGetStorageInfo(
+    const mojom::MtpStorageInfo& storage_info) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  const std::string& storage_name = storage_info.storage_name;
+  if (base::ContainsKey(storage_info_map_, storage_name)) {
+    // This should not happen, since MtpDeviceManager should
+    // only call EnumerateStorages() once, which populates |storage_info_map_|
+    // with the already-attached devices.
+    // After that, all incoming signals are either for new storage
+    // attachments, which should not be in |storage_info_map_|, or for
+    // storage detachments, which do not add to |storage_info_map_|.
+    // Return to avoid giving client phantom detach events.
+    NOTREACHED();
+    return;
+  }
+
+  // New storage. Add it and let the bound client know.
+  storage_info_map_.insert(std::make_pair(storage_name, storage_info));
+
+  if (client_) {
+    client_->StorageAttached(storage_info.Clone());
+  }
+}
+
+void MtpDeviceManager::OnGetStorageInfoFromDevice(
+    const mojom::MtpStorageInfo& storage_info) {
+  std::move(get_storage_info_from_device_callbacks_.front())
+      .Run(storage_info.Clone(), false /* no error */);
+  get_storage_info_from_device_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnGetStorageInfoFromDeviceError() {
+  std::move(get_storage_info_from_device_callbacks_.front())
+      .Run(nullptr, true /* error */);
+  get_storage_info_from_device_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnOpenStorage(const std::string& handle) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!base::ContainsKey(handles_, handle)) {
+    handles_.insert(handle);
+    std::move(open_storage_callbacks_.front()).Run(handle, false);
+  } else {
+    NOTREACHED();
+    std::move(open_storage_callbacks_.front()).Run(std::string(), true);
+  }
+  open_storage_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnOpenStorageError() {
+  std::move(open_storage_callbacks_.front()).Run(std::string(), true);
+  open_storage_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnCloseStorage() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  const std::string& handle = close_storage_callbacks_.front().second;
+  if (base::ContainsKey(handles_, handle)) {
+    handles_.erase(handle);
+    std::move(close_storage_callbacks_.front().first).Run(false);
+  } else {
+    NOTREACHED();
+    std::move(close_storage_callbacks_.front().first).Run(true);
+  }
+  close_storage_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnCloseStorageError() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(close_storage_callbacks_.front()).first.Run(true);
+  close_storage_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnCreateDirectory() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(create_directory_callbacks_.front()).Run(false /* no error */);
+  create_directory_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnCreateDirectoryError() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(create_directory_callbacks_.front()).Run(true /* error */);
+  create_directory_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnReadDirectoryEntryIds(
+    const std::vector<uint32_t>& file_ids) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(read_directory_callbacks_.front()).Run(file_ids, /*error=*/false);
+  read_directory_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnReadDirectoryError() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(read_directory_callbacks_.front())
+      .Run(std::vector<uint32_t>(), /*error=*/true);
+  read_directory_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnReadFile(const std::string& data) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(read_file_callbacks_.front()).Run(data, false);
+  read_file_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnReadFileError() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(read_file_callbacks_.front()).Run(std::string(), true);
+  read_file_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnGetFileInfo(
+    const std::vector<mojom::MtpFileEntry>& entries) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  std::vector<device::mojom::MtpFileEntryPtr> ret(entries.size());
+  for (size_t i = 0; i < entries.size(); ++i)
+    ret[i] = entries[i].Clone();
+  std::move(get_file_info_callbacks_.front())
+      .Run(std::move(ret), /*error=*/false);
+  get_file_info_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnGetFileInfoError() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(get_file_info_callbacks_.front())
+      .Run(std::vector<device::mojom::MtpFileEntryPtr>(), /*error=*/true);
+  get_file_info_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnRenameObject() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(rename_object_callbacks_.front()).Run(false /* no error */);
+  rename_object_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnRenameObjectError() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(rename_object_callbacks_.front()).Run(true /* error */);
+  rename_object_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnCopyFileFromLocal() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(copy_file_from_local_callbacks_.front()).Run(false /* no error */);
+  copy_file_from_local_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnCopyFileFromLocalError() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(copy_file_from_local_callbacks_.front()).Run(true /* error */);
+  copy_file_from_local_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnDeleteObject() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(delete_object_callbacks_.front()).Run(false /* no error */);
+  delete_object_callbacks_.pop();
+}
+
+void MtpDeviceManager::OnDeleteObjectError() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  std::move(delete_object_callbacks_.front()).Run(true /* error */);
+  delete_object_callbacks_.pop();
+}
+
+void MtpDeviceManager::FinishSetupOnOriginThread(
+    const std::string& mtpd_service_owner) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  if (mtpd_service_owner == current_mtpd_owner_)
+    return;
+
+  // In the case of a new service owner, clear |storage_info_map_|.
+  // Assume all storages have been disconnected. If there is a new service
+  // owner, reconnecting to it will reconnect all the storages as well.
+
+  // Save a copy of |storage_info_map_| keys as |storage_info_map_| can
+  // change in OnStorageDetached().
+  std::vector<std::string> storage_names;
+  storage_names.reserve(storage_info_map_.size());
+  for (const auto& info : storage_info_map_)
+    storage_names.push_back(info.first);
+
+  for (const auto& name : storage_names)
+    OnStorageDetached(name);
+
+  if (mtpd_service_owner.empty()) {
+    current_mtpd_owner_.clear();
+    mtp_client_.reset();
+    return;
+  }
+
+  current_mtpd_owner_ = mtpd_service_owner;
+
+  // |bus_| must be valid here. Otherwise, how did this method get called as a
+  // callback in the first place?
+  DCHECK(bus_);
+  mtp_client_ = MediaTransferProtocolDaemonClient::Create(bus_.get());
+
+  // Set up signals and start initializing |storage_info_map_|.
+  mtp_client_->ListenForChanges(base::Bind(&MtpDeviceManager::OnStorageChanged,
+                                           weak_ptr_factory_.GetWeakPtr()));
+  mtp_client_->EnumerateStorages(
+      base::Bind(&MtpDeviceManager::OnEnumerateStorages,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::DoNothing());
+}
+
+// static
+std::unique_ptr<MtpDeviceManager> MtpDeviceManager::Initialize() {
+  auto manager = std::make_unique<MtpDeviceManager>();
+
+  VLOG(1) << "MtpDeviceManager initialized";
+
+#if DCHECK_IS_ON()
+  DCHECK(!g_mtp_device_manager);
+  g_mtp_device_manager = manager.get();
+#endif
+
+  return manager;
 }
 
 }  // namespace device
diff --git a/services/device/media_transfer_protocol/mtp_device_manager.h b/services/device/media_transfer_protocol/mtp_device_manager.h
index 12afa11..b358381 100644
--- a/services/device/media_transfer_protocol/mtp_device_manager.h
+++ b/services/device/media_transfer_protocol/mtp_device_manager.h
@@ -7,16 +7,29 @@
 
 #include <memory>
 #include <string>
+#include <utility>
+#include <vector>
 
+#include "base/containers/flat_map.h"
+#include "base/containers/flat_set.h"
+#include "base/containers/queue.h"
+#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequenced_task_runner.h"
+#include "base/threading/thread_checker.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
 #include "mojo/public/cpp/bindings/interface_ptr_set.h"
-#include "services/device/media_transfer_protocol/media_transfer_protocol_manager.h"
+#include "services/device/media_transfer_protocol/media_transfer_protocol_daemon_client.h"
 #include "services/device/public/mojom/mtp_manager.mojom.h"
 
 #if !defined(OS_CHROMEOS)
 #error "Only used on ChromeOS"
 #endif
 
+namespace dbus {
+class DBus;
+}
+
 namespace device {
 
 // This is the implementation of device::mojom::MtpManager which provides
@@ -70,11 +83,125 @@
                     uint32_t object_id,
                     DeleteObjectCallback callback) override;
 
+  // Creates and returns the global MtpDeviceManager instance.
+  static std::unique_ptr<MtpDeviceManager> Initialize();
+
  private:
-  std::unique_ptr<MediaTransferProtocolManager>
-      media_transfer_protocol_manager_;
+  // Map of storage names to storage info.
+  using GetStorageInfoFromDeviceCallbackQueue =
+      base::queue<GetStorageInfoFromDeviceCallback>;
+  // Callback queues - DBus communication is in-order, thus callbacks are
+  // received in the same order as the requests.
+  using OpenStorageCallbackQueue = base::queue<OpenStorageCallback>;
+  // (callback, handle)
+  using CloseStorageCallbackQueue =
+      base::queue<std::pair<CloseStorageCallback, std::string>>;
+  using CreateDirectoryCallbackQueue = base::queue<CreateDirectoryCallback>;
+  using ReadDirectoryCallbackQueue = base::queue<ReadDirectoryEntryIdsCallback>;
+  using ReadFileCallbackQueue = base::queue<ReadFileChunkCallback>;
+  using GetFileInfoCallbackQueue = base::queue<GetFileInfoCallback>;
+  using RenameObjectCallbackQueue = base::queue<RenameObjectCallback>;
+  using CopyFileFromLocalCallbackQueue = base::queue<CopyFileFromLocalCallback>;
+  using DeleteObjectCallbackQueue = base::queue<DeleteObjectCallback>;
+
+  void OnStorageAttached(const std::string& storage_name);
+
+  void OnStorageDetached(const std::string& storage_name);
+
+  void OnStorageChanged(bool is_attach, const std::string& storage_name);
+
+  void OnEnumerateStorages(const std::vector<std::string>& storage_names);
+
+  void OnGetStorageInfo(const mojom::MtpStorageInfo& storage_info);
+
+  void OnGetStorageInfoFromDevice(const mojom::MtpStorageInfo& storage_info);
+
+  void OnGetStorageInfoFromDeviceError();
+
+  void OnOpenStorage(const std::string& handle);
+
+  void OnOpenStorageError();
+
+  void OnCloseStorage();
+
+  void OnCloseStorageError();
+
+  void OnCreateDirectory();
+
+  void OnCreateDirectoryError();
+
+  void OnReadDirectoryEntryIds(const std::vector<uint32_t>& file_ids);
+
+  void OnReadDirectoryError();
+
+  void OnReadFile(const std::string& data);
+
+  void OnReadFileError();
+
+  void OnGetFileInfo(const std::vector<mojom::MtpFileEntry>& entries);
+
+  void OnGetFileInfoError();
+
+  void OnRenameObject();
+
+  void OnRenameObjectError();
+
+  void OnCopyFileFromLocal();
+
+  void OnCopyFileFromLocalError();
+
+  void OnDeleteObject();
+
+  void OnDeleteObjectError();
+
+  // Callback to finish initialization after figuring out if the mtpd service
+  // has an owner, or if the service owner has changed.
+  // |mtpd_service_owner| contains the name of the current owner, if any.
+  void FinishSetupOnOriginThread(const std::string& mtpd_service_owner);
+
+  // Mtpd DBus client.
+  std::unique_ptr<MediaTransferProtocolDaemonClient> mtp_client_;
+
+  // And a D-Bus session for talking to mtpd. Note: In production, this is never
+  // a nullptr, but in tests it oftentimes is. It may be too much work for
+  // DBusThreadManager to provide a bus in unit tests.
+  scoped_refptr<dbus::Bus> const bus_;
 
   mojo::BindingSet<mojom::MtpManager> bindings_;
+  // MtpManager client who keeps tuned on attachment / detachment events.
+  // Currently, storage_monitor::StorageMonitorCros is supposed to be the
+  // only client.
+  mojom::MtpManagerClientAssociatedPtr client_;
+
+  // Map to keep track of attached storages by name.
+  base::flat_map<std::string, mojom::MtpStorageInfo> storage_info_map_;
+
+  // Set of open storage handles.
+  base::flat_set<std::string> handles_;
+
+  std::string current_mtpd_owner_;
+
+  // Queued callbacks.
+  // These queues are needed becasue MediaTransferProtocolDaemonClient provides
+  // different callbacks for result(success_callback, error_callback) with
+  // MediaTransferProtocolManager, so a passed callback for a method in this
+  // class will be referred in both success_callback and error_callback for
+  // underline MediaTransferProtocolDaemonClient, and it is also the case for
+  // mojom interfaces, as all mojom methods are defined as OnceCallback.
+  GetStorageInfoFromDeviceCallbackQueue get_storage_info_from_device_callbacks_;
+  OpenStorageCallbackQueue open_storage_callbacks_;
+  CloseStorageCallbackQueue close_storage_callbacks_;
+  CreateDirectoryCallbackQueue create_directory_callbacks_;
+  ReadDirectoryCallbackQueue read_directory_callbacks_;
+  ReadFileCallbackQueue read_file_callbacks_;
+  GetFileInfoCallbackQueue get_file_info_callbacks_;
+  RenameObjectCallbackQueue rename_object_callbacks_;
+  CopyFileFromLocalCallbackQueue copy_file_from_local_callbacks_;
+  DeleteObjectCallbackQueue delete_object_callbacks_;
+
+  base::ThreadChecker thread_checker_;
+
+  base::WeakPtrFactory<MtpDeviceManager> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(MtpDeviceManager);
 };
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
index 5c227426..729c85e 100644
--- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
+++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -370,11 +370,6 @@
 -PredictorBrowserTest.SubframeInitiatesPreconnects
 -PredictorBrowserTest.SubframeLearning
 
-# https://crbug.com/832749
-# Add DMServer header
--ChromeResourceDispatcherHostDelegateBrowserTest.PolicyHeader
--ChromeResourceDispatcherHostDelegateBrowserTest.PolicyHeaderForRedirect
-
 # Requires a replacement for ChromeNetworkDelegate.
 # http://crbug.com/841309
 -VariationsHttpHeadersBrowserTest.TestStrippingHeadersFromInternalRequest
diff --git a/testing/buildbot/filters/surface_sync.content_browsertests.filter b/testing/buildbot/filters/surface_sync.content_browsertests.filter
index 7470995..dca9230 100644
--- a/testing/buildbot/filters/surface_sync.content_browsertests.filter
+++ b/testing/buildbot/filters/surface_sync.content_browsertests.filter
@@ -1,10 +1,7 @@
-# Android failures
-# TODO(jonross): Triage these
--CompositorEventAckBrowserTest.*
--NavigationHandleImplBrowserTest.BlockCredentialedSubresources
+# Frame submission failures, and invalid compositor locking state.
+# https://crbug.com/855533
 -*CompositorImplLowEndBrowserTest.*
--SitePerProcessHit*
--ScrollLatencyBrowserTest.SmoothWheelScroll
+
+# Flaky failures with incorrect Input event acks. https://crbug.com/855532
 -TouchInputBrowserTest.TouchHandlerConsume
 -TouchInputBrowserTest.TouchHandlerNoConsume
--TouchSelectionControllerClientAndroidSiteIsolationTest.BasicSelectionIsolatedIframe
diff --git a/testing/buildbot/filters/viz.android.content_browsertests.filter b/testing/buildbot/filters/viz.android.content_browsertests.filter
index d65aa1f3..d030a55 100644
--- a/testing/buildbot/filters/viz.android.content_browsertests.filter
+++ b/testing/buildbot/filters/viz.android.content_browsertests.filter
@@ -1,6 +1,5 @@
 # Android Failures
 # TODO(jonross): Triage these
--CompositorEventAckBrowserTest.*
 -ContentBrowserTestSanityTest.SingleProcess
 -DomSerializerTests.SerializeHTMLDOMWithAddingMOTW
 -DomSerializerTests.SerializeHTMLDOMWithBaseTag
@@ -12,7 +11,6 @@
 -DomSerializerTests.SerializeXMLDocWithBuiltInEntities
 -DomSerializerTests.SubResourceForElementsInNonHTMLNamespace
 -IndexedDBBrowserTestSingleProcess.RenderThreadShutdownTest
--P/CompositorImplLowEndBrowserTest.CompositorImplDropsResourcesOnBackground/0
 -RenderThreadImplDiscardableMemoryBrowserTest.DiscardableMemoryAddressSpace
 -RenderThreadImplDiscardableMemoryBrowserTest.LockDiscardableMemory
 -RenderThreadImplDiscardableMemoryBrowserTest.ReleaseFreeDiscardableMemory
@@ -29,30 +27,13 @@
 -SavableResourcesTest.GetSavableResourceLinksWithPageHasInvalidLinks
 -SavableResourcesTest.GetSavableResourceLinksWithPageHasValidLinks
 -SavableResourcesTest.GetSavableResourceLinksWithPageHasValidStyleLink
--ScrollLatencyBrowserTest.SmoothWheelScroll
 -SingleProcessMemoryTracingTest.BrowserInitiatedSingleDump
 -SingleProcessMemoryTracingTest.ManyInterleavedDumps
 -SingleProcessMemoryTracingTest.RendererInitiatedSingleDump
--SitePerProcessHitTestBrowserTest.CrossProcessTooltipTestAndroid/1
--SitePerProcessHitTestBrowserTest.CrossProcessTooltipTestAndroid/2
+
+# GL initiazation failures. https://crbug.com/855554
+-P/CompositorImplLowEndBrowserTest.CompositorImplDropsResourcesOnBackground/0
+
+# Flaky failures with incorrect Input event acks. https://crbug.com/855532
 -TouchInputBrowserTest.TouchHandlerConsume
 -TouchInputBrowserTest.TouchHandlerNoConsume
--TouchSelectionControllerClientAndroidSiteIsolationTest.BasicSelectionIsolatedIframe
--WebContentsImplBrowserTest.NotifyFullscreenAcquired_Navigate
-
-## Base viz.content_browsertests.filter since we cannot chain filter files
-# SynchronizeVisualPropertiesMessageFilter::WaitForRect() times out.
-# https://crbug.com/848825
--SitePerProcessBrowserTest.ViewBoundsInNestedFrameTest
-
-#### Hit Testing
-# Test failure: https://crbug.com/848325
--SitePerProcessHitTestBrowserTest.RootConsumesScrollDuringOverscrollGesture*
-
-# InputEventAckWaiter never receives the event: https://crbug.com/848348
--SitePerProcessHitTestBrowserTest.CrossProcessMouseEnterAndLeaveTest*
--SitePerProcessHitTestBrowserTest.CrossProcessMouseCapture*
--SitePerProcessHitTestBrowserTest.TouchpadPinchOverOOPIF*
-
-# /2 Variant does not handle overlapping surfaces: https://crbug.com/846798
--SitePerProcessHitTestBrowserTest.HitTestStaleDataDeletedView*
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 5986102..06b1836 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -854,7 +854,7 @@
   "monochrome_apk_checker": {
     "label": "//chrome/android/monochrome:monochrome_apk_checker",
     "type": "script",
-    "script": "//chrome/android/monochrome/scripts/monochrome_apk_checker_wrapper.py",
+    "script": "//testing/scripts/monochrome_apk_checker_wrapper.py",
     "args": [
       "--script",
       "../../chrome/android/monochrome/scripts/monochrome_apk_checker.py",
diff --git a/testing/scripts/monochrome_apk_checker_wrapper.py b/testing/scripts/monochrome_apk_checker_wrapper.py
new file mode 100755
index 0000000..4a1e8e5
--- /dev/null
+++ b/testing/scripts/monochrome_apk_checker_wrapper.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+#
+# 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.
+
+# This is just a wrapper script around monochrome_apk_checker.py that
+# understands and uses the isolated-script arguments
+
+import argparse
+import json
+import sys
+import subprocess
+import time
+
+
+import common
+
+
+def main():
+  parser = argparse.ArgumentParser(prog='monochrome_apk_checker_wrapper')
+
+  parser.add_argument('--script',
+                      required=True,
+                      help='The path to the monochrome_apk_checker.py script')
+  parser.add_argument('--isolated-script-test-output',
+                      required=True)
+  # Only run one test, we check that it's the test we expect.
+  parser.add_argument('--isolated-script-test-filter')
+  # Ignored, but required to satisfy the isolated_script interface.
+  # We aren't a perf test, so don't have any perf output.
+  parser.add_argument('--isolated-script-test-perf-output')
+  args, extra = parser.parse_known_args(sys.argv[1:])
+
+  if args.isolated_script_test_filter and (
+      'monochrome_apk_checker' not in args.isolated_script_test_filter):
+      parser.error('isolated-script-test-filter has invalid test: %s' % (
+          args.isolated_script_test_filter))
+
+  cmd = [args.script] + extra
+
+  start_time = time.time()
+  ret = subprocess.call(cmd)
+  success = ret == 0
+
+  # Schema is at //docs/testing/json_test_results_format.md
+  with open(args.isolated_script_test_output, 'w') as fp:
+    test = {
+      'expected': 'PASS',
+      'actual': 'PASS' if success else 'FAIL',
+    }
+    if not success:
+      test['unexpected'] = True
+
+    json.dump({
+      'version': 3,
+      'interrupted': False,
+      'path_delimiter': '/',
+      'seconds_since_epoch': start_time,
+      'num_failures_by_type': {
+        'PASS': int(success),
+        'FAIL': int(not success),
+      },
+      'tests': {
+        'monochrome_apk_checker': test,
+      }
+    }, fp)
+
+  return ret
+
+# This is not really a "script test" so does not need to manually add
+# any additional compile targets.
+def main_compile_targets(args):
+  json.dump([], args.output)
+
+if __name__ == '__main__':
+  # Conform minimally to the protocol defined by ScriptTest.
+  if 'compile_targets' in sys.argv:
+    funcs = {
+      'run': None,
+      'compile_targets': main_compile_targets,
+    }
+    sys.exit(common.run_script(sys.argv[1:], funcs))
+
+  sys.exit(main())
diff --git a/testing/scripts/run_performance_tests.py b/testing/scripts/run_performance_tests.py
index 01af149..a491fcd 100755
--- a/testing/scripts/run_performance_tests.py
+++ b/testing/scripts/run_performance_tests.py
@@ -49,6 +49,7 @@
 import os
 import shutil
 import sys
+import time
 import tempfile
 import traceback
 
@@ -82,8 +83,13 @@
     f.write(benchmark_log)
 
 
+def print_duration(step, start):
+  print 'Duration of %s: %d seconds' % (step, time.time() - start)
+
+
 def execute_benchmark(benchmark, isolated_out_dir,
                       args, rest_args, is_reference, stories=None):
+  start = time.time()
   # While we are between chartjson and histogram set we need
   # to determine which output format to look for or see if it was
   # already passed in in which case that format applies to all benchmarks
@@ -128,6 +134,8 @@
   write_results(
       benchmark_name, perf_results, json_test_results, benchmark_log,
       isolated_out_dir, False)
+
+  print_duration('executing benchmark %s' % benchmark_name, start)
   return rc
 
 
diff --git a/testing/scripts/test_traffic_annotation_auditor.py b/testing/scripts/test_traffic_annotation_auditor.py
index 06ee6c6..279d020 100755
--- a/testing/scripts/test_traffic_annotation_auditor.py
+++ b/testing/scripts/test_traffic_annotation_auditor.py
@@ -35,13 +35,7 @@
 
 
 def main_compile_targets(args):
-  # TODO(https://crbug.com/844014): Merge windows and non-windows cases after
-  # finding the minimum set of sufficient build targets.
-  if sys.platform == 'cygwin' or sys.platform.startswith('win'):
-    json.dump(['chrome', 'remoting/host:host', 'remoting/client:client'],
-              args.output)
-  else:
-    json.dump(['all'], args.output)
+  json.dump(['all'], args.output)
 
 
 if __name__ == '__main__':
diff --git a/testing/trigger_scripts/perf_device_trigger.py b/testing/trigger_scripts/perf_device_trigger.py
index 29fb973..ed794a0 100755
--- a/testing/trigger_scripts/perf_device_trigger.py
+++ b/testing/trigger_scripts/perf_device_trigger.py
@@ -128,19 +128,21 @@
                        'pool. Contact labs to rack in more hardware')
 
     shard_to_bot_assignment_map = {}
-    unallocated_bots = set(self._eligible_bots_by_ids.values())
+    unallocated_bots_by_ids = self._eligible_bots_by_ids.copy()
     for shard_index in xrange(args.shards):
       bot_id = self._query_swarming_for_last_shard_id(shard_index)
-      if bot_id:
+      if bot_id and bot_id in unallocated_bots_by_ids:
         bot = self._eligible_bots_by_ids[bot_id]
         shard_to_bot_assignment_map[shard_index] = bot
-        unallocated_bots.discard(bot)
+        unallocated_bots_by_ids.pop(bot_id)
       else:
         shard_to_bot_assignment_map[shard_index] = None
 
     # Now create sets of remaining healthy and bad bots
-    unallocated_healthy_bots = {b for b in unallocated_bots if b.is_alive()}
-    unallocated_bad_bots = {b for b in unallocated_bots if not b.is_alive()}
+    unallocated_healthy_bots = {
+        b for b in unallocated_bots_by_ids.values() if b.is_alive()}
+    unallocated_bad_bots = {
+        b for b in unallocated_bots_by_ids.values() if not b.is_alive()}
 
     # Try assigning healthy bots for new shards first.
     for shard_index, bot in sorted(shard_to_bot_assignment_map.iteritems()):
diff --git a/testing/trigger_scripts/perf_device_trigger_unittest.py b/testing/trigger_scripts/perf_device_trigger_unittest.py
index b583cfe..4ba1e2bb 100755
--- a/testing/trigger_scripts/perf_device_trigger_unittest.py
+++ b/testing/trigger_scripts/perf_device_trigger_unittest.py
@@ -264,5 +264,21 @@
     self.assertIn(expected_task_assignment.get(1), new_healthy_bots)
     self.assertIn(expected_task_assignment.get(2), new_healthy_bots)
 
+  def test_previously_duplicate_task_assignemnts(self):
+    triggerer = self.setup_and_trigger(
+        previous_task_assignment_map={0: 'build3', 1: 'build3', 2: 'build5',
+                                      3: 'build6'},
+        alive_bots=['build3', 'build4', 'build5', 'build7'],
+        dead_bots=['build1', 'build6'])
+    expected_task_assignment = self.get_triggered_shard_to_bot(
+        triggerer, num_shards=3)
+
+    # Test that the new assignment will add a new bot to avoid
+    # assign 'build3' to both shard 0 & shard 1 as before.
+    # It also replaces the dead 'build6' bot.
+    self.assertEquals(set(expected_task_assignment.values()),
+        {'build3', 'build4', 'build5', 'build7'})
+
+
 if __name__ == '__main__':
   unittest.main()
diff --git a/third_party/.gitignore b/third_party/.gitignore
index e7bc01e..6c8cf51 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -6,6 +6,9 @@
 /adobe/flash/binaries
 /adobe/flash/symbols
 /amd/
+/android_build_tools/aapt2/aapt2
+/android_build_tools/aapt2/lib64/*.so
+/android_build_tools/bundletool/*.jar
 /android_ndk/
 /android_sdk/public/
 /android_sdk/sources/
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 4100b24..377b36ab 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -1,9 +1,6 @@
 # These tests currently fail when they run with --enable-blink-features=LayoutNG
 # See https://crbug.com/591099.
 
-# Need support for Range.getClientRects() and Range.getBoundingClientRect()
-crbug.com/755750 accessibility/selection-affinity.html [ Failure ]
-
 # Non-interoperable behavior not worth to fix.
 crbug.com/591099 fast/text/apply-start-width-after-skipped-text.html [ Skip ]
 
@@ -58,9 +55,6 @@
 crbug.com/591099 fast/dom/inner-text-first-letter.html [ Pass ]
 
 # New failures are appended below by the script.
-crbug.com/591099 accessibility/inline-text-bidi-bounds-for-range.html [ Failure ]
-crbug.com/714962 accessibility/inline-text-bounds-for-range-br.html [ Failure ]
-crbug.com/591099 accessibility/inline-text-bounds-for-range.html [ Failure ]
 crbug.com/591099 animations/cross-fade-list-style-image.html [ Failure ]
 crbug.com/591099 animations/rotate-transform-equivalent.html [ Failure ]
 crbug.com/714962 compositing/background-color/view-blending-base-background.html [ Failure ]
@@ -446,7 +440,6 @@
 crbug.com/591099 fast/dom/Window/window-lookup-precedence.html [ Failure ]
 crbug.com/714962 fast/dom/elementFromPoint-relative-to-viewport.html [ Failure ]
 crbug.com/714962 fast/dom/elementsFromPoint/elementsFromPoint-inline.html [ Failure ]
-crbug.com/714962 fast/dom/inert/inert-inlines.html [ Failure ]
 crbug.com/591099 fast/dom/nodesFromRect/nodesFromRect-basic.html [ Failure ]
 crbug.com/714962 fast/dom/nodesFromRect/nodesFromRect-culled-inline-with-linebreak.html [ Failure ]
 crbug.com/714962 fast/dom/nodesFromRect/nodesFromRect-culled-inlines.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index d46a084..afecd79 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -3665,9 +3665,6 @@
 crbug.com/655458 external/wpt/workers/semantics/multiple-workers/006.html [ Failure Timeout ]
 crbug.com/655458 external/wpt/workers/semantics/multiple-workers/007.html [ Failure Timeout ]
 
-crbug.com/655458 external/wpt/workers/semantics/structured-clone/dedicated.html [ Crash Failure Timeout ]
-crbug.com/655458 external/wpt/workers/semantics/structured-clone/shared.html [ Crash Failure Timeout ]
-
 crbug.com/490511 external/wpt/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-networkState.html [ Timeout ]
 
 crbug.com/435547 http/tests/cachestorage/serviceworker/ignore-search-with-credentials.html [ Skip ]
@@ -3835,8 +3832,6 @@
 crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/size.attributes.parse.percent.worker.html [ Failure ]
 crbug.com/709227 external/wpt/offscreen-canvas/the-offscreen-canvas/size.attributes.parse.trailingjunk.worker.html [ Failure ]
 crbug.com/709227 external/wpt/user-timing/invoke_with_timing_attributes.worker.html [ Failure ]
-crbug.com/706804 external/wpt/console/console-tests-historical.any.html [ Skip ]
-crbug.com/706804 external/wpt/console/console-tests-historical.any.worker.html [ Skip ]
 
 # Crashes
 crbug.com/709227 external/wpt/offscreen-canvas/fill-and-stroke-styles/2d.pattern.basic.nocontext.worker.html [ Crash ]
@@ -3852,6 +3847,11 @@
 
 # ====== End of display: contents tests ======
 
+# Temporarily disabled tests that will pass once deprecated console methods are removed, see crrev.com/c/1082112
+crbug.com/706804 external/wpt/console/console-tests-historical.any.html [ Skip ]
+crbug.com/706804 external/wpt/console/console-tests-historical.any.worker.html [ Skip ]
+crbug.com/706804 fast/workers/chromium/worker-console-log.html [ Skip ]
+
 crbug.com/676229 [ Win Linux Mac ] plugins/mouse-click-plugin-clears-selection.html [ Failure Pass ]
 crbug.com/736333 [ Win7 Linux ] plugins/iframe-plugin-bgcolor.html [ Failure Pass ]
 crbug.com/742670 [ Mac ] plugins/iframe-plugin-bgcolor.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index 8f17b3fa..0c6f190 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -52597,6 +52597,30 @@
      {}
     ]
    ],
+   "css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html": [
+    [
+     "/css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html",
+     [
+      [
+       "/css/css-scoping/reference/green-box.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-scoping/shadow-link-rel-stylesheet.html": [
+    [
+     "/css/css-scoping/shadow-link-rel-stylesheet.html",
+     [
+      [
+       "/css/css-scoping/reference/green-box.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-scoping/shadow-reassign-dynamic-001.html": [
     [
      "/css/css-scoping/shadow-reassign-dynamic-001.html",
@@ -129923,7 +129947,7 @@
      {}
     ]
    ],
-   "css/css-ui/parsing/resources/parsing-testcommon.js": [
+   "css/css-ui/parsing/support/parsing-testcommon.js": [
     [
      {}
     ]
@@ -155663,16 +155687,6 @@
      {}
     ]
    ],
-   "html/semantics/scripting-1/the-template-element/template-element/template-as-a-descendant-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "html/semantics/scripting-1/the-template-element/template-element/template-descendant-frameset-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "html/semantics/sections/.gitkeep": [
     [
      {}
@@ -156368,21 +156382,6 @@
      {}
     ]
    ],
-   "html/syntax/parsing/html5lib_template_run_type=uri-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "html/syntax/parsing/html5lib_template_run_type=write-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "html/syntax/parsing/html5lib_template_run_type=write_single-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "html/syntax/parsing/html5lib_tests11-expected.txt": [
     [
      {}
@@ -156458,11 +156457,6 @@
      {}
     ]
    ],
-   "html/syntax/parsing/template/additions-to-the-in-frameset-insertion-mode/end-tag-frameset-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "html/syntax/parsing/test.js": [
     [
      {}
@@ -157328,6 +157322,16 @@
      {}
     ]
    ],
+   "infrastructure/server/title.any.sharedworker-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "infrastructure/server/title.any.worker-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "infrastructure/server/wpt-server-http.sub-expected.txt": [
     [
      {}
@@ -157448,6 +157452,11 @@
      {}
     ]
    ],
+   "interfaces/beacon.idl": [
+    [
+     {}
+    ]
+   ],
    "interfaces/budget-api.idl": [
     [
      {}
@@ -173108,6 +173117,16 @@
      {}
     ]
    ],
+   "workers/semantics/structured-clone/dedicated-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "workers/semantics/structured-clone/shared-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "workers/semantics/xhr/001-1.xml": [
     [
      {}
@@ -182650,6 +182669,16 @@
      {}
     ]
    ],
+   "beacon/idlharness.any.js": [
+    [
+     "/beacon/idlharness.any.html",
+     {}
+    ],
+    [
+     "/beacon/idlharness.any.worker.html",
+     {}
+    ]
+   ],
    "bluetooth/characteristic/characteristicProperties.https.html": [
     [
      "/bluetooth/characteristic/characteristicProperties.https.html",
@@ -223066,6 +223095,20 @@
      {}
     ]
    ],
+   "infrastructure/server/title.any.js": [
+    [
+     "/infrastructure/server/title.any.html",
+     {}
+    ],
+    [
+     "/infrastructure/server/title.any.sharedworker.html",
+     {}
+    ],
+    [
+     "/infrastructure/server/title.any.worker.html",
+     {}
+    ]
+   ],
    "infrastructure/server/wpt-server-http.sub.html": [
     [
      "/infrastructure/server/wpt-server-http.sub.html",
@@ -246811,7 +246854,9 @@
    "service-workers/service-worker/navigation-redirect.https.html": [
     [
      "/service-workers/service-worker/navigation-redirect.https.html",
-     {}
+     {
+      "timeout": "long"
+     }
     ]
    ],
    "service-workers/service-worker/navigation-timing.https.html": [
@@ -272415,6 +272460,10 @@
    "8185d2b31fbf67a573444d3c8f828f96422526f5",
    "support"
   ],
+  "beacon/idlharness.any.js": [
+   "eee7ad4981ba48eef9df1f61b5d4d9ce39bc684d",
+   "testharness"
+  ],
   "beacon/navigate.iFrame.sub.html": [
    "03a7f2477d3efef7572b1c45a6ed113350aec948",
    "support"
@@ -314575,6 +314624,14 @@
    "99af6e29e69b3131b59dbdc2b0eead52931123c2",
    "reftest"
   ],
+  "css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html": [
+   "a46be006762a16c2deb3d1d3a760e3c4e348668c",
+   "reftest"
+  ],
+  "css/css-scoping/shadow-link-rel-stylesheet.html": [
+   "07862ce7d2a954988bdbce882869a4c5f097089a",
+   "reftest"
+  ],
   "css/css-scoping/shadow-reassign-dynamic-001.html": [
    "11ed4da2e6ce88d8a2b98a8f1c814417ef7770dd",
    "reftest"
@@ -330172,35 +330229,35 @@
    "reftest"
   ],
   "css/css-ui/parsing/box-sizing-invalid.html": [
-   "f6d47c2136afc9b6538e2dfc5b8f1f13efd51359",
+   "d6c0f262fc9194e92627062a02db9bc2300976f5",
    "testharness"
   ],
   "css/css-ui/parsing/box-sizing-valid.html": [
-   "ae42aa258f80502238e4106c5aad8cd3a86b67be",
+   "cdea435ef74fdb66bc9b480bd23771f918da6db0",
    "testharness"
   ],
   "css/css-ui/parsing/caret-color-invalid.html": [
-   "4f661bf5354591a4763dc0e2e24262135274e851",
+   "d094b012b055649557e2db27c4a41084b5504ff4",
    "testharness"
   ],
   "css/css-ui/parsing/caret-color-valid.html": [
-   "43e5e627b82425fe9b5f2e8aa631a3e29076a894",
+   "9499e106fbc910331750f1580e296feb141caa39",
    "testharness"
   ],
   "css/css-ui/parsing/cursor-invalid.html": [
-   "9dc6470ff66b178b131df50baa4983e9c268f150",
+   "34a18b4943bc71be6e4537800cae3bfed0b924a0",
    "testharness"
   ],
   "css/css-ui/parsing/cursor-valid.html": [
-   "b0a45e0783e4fc8d238941add086337a26352f97",
+   "2cc358e954aaa33bcf87ae410e3d65ee672ace17",
    "testharness"
   ],
   "css/css-ui/parsing/outline-color-invalid.html": [
-   "c2c76b237c6a3cb3e6c739b46907afb3b168a00c",
+   "edf914872ef9267b25ec2ab9a0f1c58159341694",
    "testharness"
   ],
   "css/css-ui/parsing/outline-color-valid-mandatory.html": [
-   "d4353c1c614c9352636351fd4f6060d5ebdf2551",
+   "dd895036c95d84f9c9d6f7632eafd9a1b7aecb8d",
    "testharness"
   ],
   "css/css-ui/parsing/outline-color-valid-optional-expected.txt": [
@@ -330208,31 +330265,31 @@
    "support"
   ],
   "css/css-ui/parsing/outline-color-valid-optional.html": [
-   "b68ab57f63120ae95944c55e0ea52d3155573267",
+   "f77a0c9af4c627fbf59e2c55b4bcc3dfb49b9771",
    "testharness"
   ],
   "css/css-ui/parsing/outline-invalid.html": [
-   "e579a7ab952531873dea0ea2c1b749949336024c",
+   "8ba3081d8628a487310c9d7acda70c6c76158857",
    "testharness"
   ],
   "css/css-ui/parsing/outline-offset-invalid.html": [
-   "924035eac723af4bf4712c3786543306ae6fcc10",
+   "e1587c0a9fefe8eeec8325ed6bb2b7c2d6b4428c",
    "testharness"
   ],
   "css/css-ui/parsing/outline-offset-valid.html": [
-   "1f0e8b438dec00532cc115f959db11b77cedfb31",
+   "361108b768a172752c85f4b2794a511d464e745e",
    "testharness"
   ],
   "css/css-ui/parsing/outline-style-invalid.html": [
-   "3f6a0a0842d5ca76c481eb92269fff221c8386c9",
+   "14ca6f72222fbb551b85cef7c8c5d9da3788c139",
    "testharness"
   ],
   "css/css-ui/parsing/outline-style-valid.html": [
-   "a72005f961c1aad7ef1244541193e4959e496a71",
+   "74997c2c984b523229f4f68e534aeb6e2b2725d9",
    "testharness"
   ],
   "css/css-ui/parsing/outline-valid-mandatory.html": [
-   "567b86da51778fc5350d11288dbd3e3f3e12bada",
+   "647d29a5fdd7b352a2d1fbbfa4bb0436e2eaa784",
    "testharness"
   ],
   "css/css-ui/parsing/outline-valid-optional-expected.txt": [
@@ -330240,15 +330297,15 @@
    "support"
   ],
   "css/css-ui/parsing/outline-valid-optional.html": [
-   "aa6ea1da3f43ca74a44527e84cee0ab8d2e4b091",
+   "9fc8bd366735dd05cc37c1497c7aed6a91e32630",
    "testharness"
   ],
   "css/css-ui/parsing/outline-width-invalid.html": [
-   "78e0dc7d541e7000d507a4773908ca851c50a5cb",
+   "0403c9910c17f76da0e834d2c9263898b405d049",
    "testharness"
   ],
   "css/css-ui/parsing/outline-width-valid.html": [
-   "a31c9f3572566e75dce6a36d58f9e21aaa727405",
+   "b902d6da35d6dac8d0e08fe99760434294311263",
    "testharness"
   ],
   "css/css-ui/parsing/resize-invalid-expected.txt": [
@@ -330256,23 +330313,23 @@
    "support"
   ],
   "css/css-ui/parsing/resize-invalid.html": [
-   "972f102e81b150ea63b9616728aa0c27b6f31dfb",
+   "fd6f661bc65d483cf2136d4d889f3778d5012ddf",
    "testharness"
   ],
   "css/css-ui/parsing/resize-valid.html": [
-   "f10a19dae64b6b8d02bc188dc2bb7df778fa4d60",
+   "70bff9554807d01fdf39b1c8566a24ea864aca58",
    "testharness"
   ],
-  "css/css-ui/parsing/resources/parsing-testcommon.js": [
+  "css/css-ui/parsing/support/parsing-testcommon.js": [
    "14f32b772f27a9bc75fe90e2ea1d8e4fb3649e95",
    "support"
   ],
   "css/css-ui/parsing/text-overflow-invalid.html": [
-   "576fd63bd6455a8e0e3623e853dfc260662d3a86",
+   "d0cf5f82994d7004d27a57adf9caa8981220847a",
    "testharness"
   ],
   "css/css-ui/parsing/text-overflow-valid.html": [
-   "79c05636c160aa39475e059ede5de6b60afafaca",
+   "cb1d4d0815d3e7b55c5adf33dae95cedcdcf75ae",
    "testharness"
   ],
   "css/css-ui/reference/box-sizing-001-ref.html": [
@@ -345600,7 +345657,7 @@
    "testharness"
   ],
   "custom-elements/Document-createElement.html": [
-   "5beef262e1e1a1c98eb320019c88d9a7bda02ba5",
+   "095cf0b0907bcd53ba8f0b655ec1655329959a98",
    "testharness"
   ],
   "custom-elements/Document-createElementNS.html": [
@@ -352544,7 +352601,7 @@
    "support"
   ],
   "fetch/sec-metadata/fetch.tentative.https.sub.html": [
-   "39325c2758284c6d36d996c21cdb7e8845a17ea3",
+   "80ed267f8a5a8aa6bf7e146af4836b2b56430721",
    "testharness"
   ],
   "fetch/sec-metadata/iframe.tentative.https.sub.html": [
@@ -352564,7 +352621,7 @@
    "support"
   ],
   "fetch/sec-metadata/resources/helper.js": [
-   "64d204e36b6ab3b7268d6fd8e0694081222b98ee",
+   "ee91fc4ff739485eed66c7ebc8fb19311f205536",
    "support"
   ],
   "fetch/sec-metadata/resources/post-to-owner.py": [
@@ -371191,10 +371248,6 @@
    "d27951d4a4cbe43f37f259563ba36f3561077d71",
    "testharness"
   ],
-  "html/semantics/scripting-1/the-template-element/template-element/template-as-a-descendant-expected.txt": [
-   "dbcf6fa179367b2e649a447f1f2a46ee6cd2b02d",
-   "support"
-  ],
   "html/semantics/scripting-1/the-template-element/template-element/template-as-a-descendant.html": [
    "661adb3f098161bf4535d9184e175612cfcab886",
    "testharness"
@@ -371215,10 +371268,6 @@
    "546e0eb799aff1ab94e85d56674074f9dfc17e41",
    "testharness"
   ],
-  "html/semantics/scripting-1/the-template-element/template-element/template-descendant-frameset-expected.txt": [
-   "9e5fc514cc830707cd15e5beaf36168a108faf6b",
-   "support"
-  ],
   "html/semantics/scripting-1/the-template-element/template-element/template-descendant-frameset.html": [
    "cda202e09a0d5f89e72984e2bfba4307d4a65647",
    "testharness"
@@ -372307,18 +372356,6 @@
    "022886883adbc6ec84d32eb50e0202c2f3f0bd7c",
    "testharness"
   ],
-  "html/syntax/parsing/html5lib_template_run_type=uri-expected.txt": [
-   "b8e02d39f2c2b67ec726b1310ab46fcf05db1f0b",
-   "support"
-  ],
-  "html/syntax/parsing/html5lib_template_run_type=write-expected.txt": [
-   "b8e02d39f2c2b67ec726b1310ab46fcf05db1f0b",
-   "support"
-  ],
-  "html/syntax/parsing/html5lib_template_run_type=write_single-expected.txt": [
-   "b8e02d39f2c2b67ec726b1310ab46fcf05db1f0b",
-   "support"
-  ],
   "html/syntax/parsing/html5lib_tests1.html": [
    "ba8d3374c33a5aa566751e1890f03af1a5ea01f9",
    "testharness"
@@ -372539,10 +372576,6 @@
    "767b31417493fc2b45498677830ea04a7a22cf61",
    "testharness"
   ],
-  "html/syntax/parsing/template/additions-to-the-in-frameset-insertion-mode/end-tag-frameset-expected.txt": [
-   "149750460e75ef8ad8b84e3a8c1ac4a35ea36860",
-   "support"
-  ],
   "html/syntax/parsing/template/additions-to-the-in-frameset-insertion-mode/end-tag-frameset.html": [
    "9295e29e9e1ea13de8a25dd34637fa016b45d437",
    "testharness"
@@ -373899,6 +373932,18 @@
    "6f246bdc6d67a92a6518870542c20d2f8b2b5f5d",
    "testharness"
   ],
+  "infrastructure/server/title.any.js": [
+   "d1220af2e8cc4fab720497311064666393eea7c8",
+   "testharness"
+  ],
+  "infrastructure/server/title.any.sharedworker-expected.txt": [
+   "ed264873e16d5144ff72d947466a9b5efa9af299",
+   "support"
+  ],
+  "infrastructure/server/title.any.worker-expected.txt": [
+   "ed264873e16d5144ff72d947466a9b5efa9af299",
+   "support"
+  ],
   "infrastructure/server/wpt-server-http.sub-expected.txt": [
    "f43e81e2a389b59723ff9787014c6d96a030e13b",
    "support"
@@ -374039,6 +374084,10 @@
    "37550560186be55b56d226be2fdecc1e36574a6d",
    "support"
   ],
+  "interfaces/beacon.idl": [
+   "0c44727b2685654751d2927f9c384f7e05cc7cf3",
+   "support"
+  ],
   "interfaces/budget-api.idl": [
    "caba22c23688d761adef48dae1b58cc13a3e90ea",
    "support"
@@ -394516,7 +394565,7 @@
    "support"
   ],
   "scroll-animations/META.yml": [
-   "fab0b68ec248d2d69cdcec6085c07c6c6004b0a4",
+   "df377d2d8c7e81a85e1676b0ca9dd186837710a6",
    "support"
   ],
   "scroll-animations/idlharness-expected.txt": [
@@ -396596,7 +396645,7 @@
    "testharness"
   ],
   "service-workers/service-worker/navigation-redirect.https.html": [
-   "109f463deeaad2d60d4dab644c782ad633e97a7d",
+   "92638db88808806e49a648c55749f23af4bf8cc1",
    "testharness"
   ],
   "service-workers/service-worker/navigation-timing.https-expected.txt": [
@@ -399152,7 +399201,7 @@
    "support"
   ],
   "streams/readable-byte-streams/construct-byob-request.dedicatedworker-expected.txt": [
-   "07843a51f04d08f676337702f7ce30eab839498b",
+   "b039d0b4295a73aa40761431b97c1da410477fac",
    "support"
   ],
   "streams/readable-byte-streams/construct-byob-request.dedicatedworker.html": [
@@ -399176,7 +399225,7 @@
    "testharness"
   ],
   "streams/readable-byte-streams/construct-byob-request.sharedworker-expected.txt": [
-   "07843a51f04d08f676337702f7ce30eab839498b",
+   "b039d0b4295a73aa40761431b97c1da410477fac",
    "support"
   ],
   "streams/readable-byte-streams/construct-byob-request.sharedworker.html": [
@@ -410064,7 +410113,7 @@
    "testharness"
   ],
   "workers/interfaces/WorkerUtils/importScripts/002.worker-expected.txt": [
-   "50b2e70ef5908dc31626a950f89120dffa2eb4e0",
+   "102367f27e8fc00e19fdc6c6f9eb56a258890be4",
    "support"
   ],
   "workers/interfaces/WorkerUtils/importScripts/002.worker.js": [
@@ -410591,10 +410640,18 @@
    "2d4308cba02b09c6f583783312317b885089e78c",
    "testharness"
   ],
+  "workers/semantics/structured-clone/dedicated-expected.txt": [
+   "ebf9dae9ab2a8d642a485f7b07b1a9bbae0a4414",
+   "support"
+  ],
   "workers/semantics/structured-clone/dedicated.html": [
    "2b779dd62c6ee6fbd17a312ab21e822fd07b9bd6",
    "testharness"
   ],
+  "workers/semantics/structured-clone/shared-expected.txt": [
+   "ebf9dae9ab2a8d642a485f7b07b1a9bbae0a4414",
+   "support"
+  ],
   "workers/semantics/structured-clone/shared.html": [
    "7db4e83fc461c0e331dac2807bd4d7c86ceb5b81",
    "testharness"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/beacon/idlharness.any.js b/third_party/WebKit/LayoutTests/external/wpt/beacon/idlharness.any.js
new file mode 100644
index 0000000..958daf4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/beacon/idlharness.any.js
@@ -0,0 +1,17 @@
+// META: script=/resources/WebIDLParser.js
+// META: script=/resources/idlharness.js
+
+// https://w3c.github.io/beacon/
+
+promise_test(async () => {
+  const idl = await fetch('/interfaces/beacon.idl').then(r => r.text());
+  const html = await fetch('/interfaces/html.idl').then(r => r.text());
+
+  const idl_array = new IdlArray();
+  idl_array.add_idls(idl);
+  idl_array.add_dependency_idls(html);
+  idl_array.add_objects({
+    Navigator: ['navigator'],
+  });
+  idl_array.test();
+}, 'beacon interfaces');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/subsumption_algorithm-unsafe_hashed_attributes.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/subsumption_algorithm-unsafe_hashes.html
similarity index 69%
rename from third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/subsumption_algorithm-unsafe_hashed_attributes.html
rename to third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/subsumption_algorithm-unsafe_hashes.html
index 889210c..2d5fa157 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/subsumption_algorithm-unsafe_hashed_attributes.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/embedded-enforcement/subsumption_algorithm-unsafe_hashes.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <head>
-<title>Embedded Enforcement: Subsumption Algorithm - 'unsafe-hashed-attributes' keyword.</title>
+<title>Embedded Enforcement: Subsumption Algorithm - 'unsafe-hashes' keyword.</title>
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
   <script src="support/testharness-helper.sub.js"></script>
@@ -9,36 +9,36 @@
 <body>
   <script>
     var tests = [
-      { "name": "'unsafe-hashed-attributes' is properly subsumed.", 
-        "required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-eval' 'strict-dynamic' 'unsafe-hashed-attributes'", 
-        "returned_csp_1": "style-src http://example1.com/foo/bar.html 'unsafe-hashed-attributes'",
+      { "name": "'unsafe-hashes' is properly subsumed.",
+        "required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-eval' 'strict-dynamic' 'unsafe-hashes'",
+        "returned_csp_1": "style-src http://example1.com/foo/bar.html 'unsafe-hashes'",
         "expected": IframeLoad.EXPECT_LOAD },
-      { "name": "No other keyword has the same effect as 'unsafe-hashed-attributes'.", 
-        "required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-hashed-attributes'", 
+      { "name": "No other keyword has the same effect as 'unsafe-hashes'.",
+        "required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-hashes'",
         "returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-inline'",
         "expected": IframeLoad.EXPECT_BLOCK },
-      { "name": "Other expressions have to be subsumed.", 
-        "required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-hashed-attributes'", 
-        "returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-inline' 'unsafe-hashed-attributes'",
+      { "name": "Other expressions have to be subsumed.",
+        "required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-hashes'",
+        "returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-inline' 'unsafe-hashes'",
         "expected": IframeLoad.EXPECT_BLOCK },
-      { "name": "Effective policy is properly found.", 
-        "required_csp": "style-src http://example1.com/foo/ 'self'  'unsafe-hashed-attributes'", 
-        "returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-eval' 'unsafe-hashed-attributes'",
-        "returned_csp_2": "style-src http://example1.com/foo/ 'self' 'unsafe-hashed-attributes'",
+      { "name": "Effective policy is properly found.",
+        "required_csp": "style-src http://example1.com/foo/ 'self'  'unsafe-hashes'",
+        "returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-eval' 'unsafe-hashes'",
+        "returned_csp_2": "style-src http://example1.com/foo/ 'self' 'unsafe-hashes'",
         "expected": IframeLoad.EXPECT_LOAD },
-      { "name": "Required csp must allow 'unsafe-hashed-attributes'.", 
-        "required_csp": "style-src http://example1.com/foo/ 'self'", 
-        "returned_csp_1": "style-src http://example1.com/foo/ 'self'  'unsafe-hashed-attributes'",
+      { "name": "Required csp must allow 'unsafe-hashes'.",
+        "required_csp": "style-src http://example1.com/foo/ 'self'",
+        "returned_csp_1": "style-src http://example1.com/foo/ 'self'  'unsafe-hashes'",
         "expected": IframeLoad.EXPECT_BLOCK },
-      { "name": "Effective policy is properly found where 'unsafe-hashed-attributes' is not subsumed.", 
-        "required_csp": "style-src http://example1.com/foo/ 'self'", 
-        "returned_csp_1": "style-src 'unsafe-eval' 'unsafe-hashed-attributes'",
-        "returned_csp_2": "style-src 'unsafe-hashed-attributes' 'unsafe-inline'",
+      { "name": "Effective policy is properly found where 'unsafe-hashes' is not subsumed.",
+        "required_csp": "style-src http://example1.com/foo/ 'self'",
+        "returned_csp_1": "style-src 'unsafe-eval' 'unsafe-hashes'",
+        "returned_csp_2": "style-src 'unsafe-hashes' 'unsafe-inline'",
         "expected": IframeLoad.EXPECT_BLOCK },
-      { "name": "Effective policy is properly found where 'unsafe-hashed-attributes' is not part of it.", 
-        "required_csp": "style-src http://example1.com/foo/ 'self'", 
+      { "name": "Effective policy is properly found where 'unsafe-hashes' is not part of it.",
+        "required_csp": "style-src http://example1.com/foo/ 'self'",
         "returned_csp_1": "style-src 'unsafe-eval' 'self'",
-        "returned_csp_2": "style-src 'unsafe-hashed-attributes' 'self'",
+        "returned_csp_2": "style-src 'unsafe-hashes' 'self'",
         "expected": IframeLoad.EXPECT_LOAD },
     ];
     tests.forEach(test => {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_allowed-href.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_allowed-href.html
new file mode 100644
index 0000000..76e9576
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_allowed-href.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-hashes' 'nonce-abc'
+    'sha256-r5W8SQIDMTbMxAjJ7KzCzFT38dwBy7Y5KF5B+20009g=';">
+    <!--
+    'sha256-r5W8SQIDMTbMxAjJ7KzCzFT38dwBy7Y5KF5B+20009g=' ==> 'javascript:t1.done();'
+    -->
+    <script src='/resources/testharness.js' nonce='abc'></script>
+    <script src='/resources/testharnessreport.js' nonce='abc'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <a href='javascript:t1.done();' id='test'>
+    <script nonce='abc'>
+        var t1 = async_test("Test that the javascript: src is allowed to run");
+
+        window.addEventListener('securitypolicyviolation', t1.unreached_func("Should have not raised any event"));
+
+        document.getElementById('test').click();
+    </script>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_allowed-href_blank.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_allowed-href_blank.html
new file mode 100644
index 0000000..30d05ee
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_allowed-href_blank.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-hashes' 'nonce-abc'
+    'sha256-r5W8SQIDMTbMxAjJ7KzCzFT38dwBy7Y5KF5B+20009g=';">
+    <!--
+    'sha256-r5W8SQIDMTbMxAjJ7KzCzFT38dwBy7Y5KF5B+20009g=' ==> 'javascript:t1.done();'
+    -->
+    <script src='/resources/testharness.js' nonce='abc'></script>
+    <script src='/resources/testharnessreport.js' nonce='abc'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <a target="_blank" href='javascript:t1.done();' id='test'>
+    <script nonce='abc'>
+        var t1 = async_test("Test that the javascript: src is allowed to run");
+
+        window.addEventListener('securitypolicyviolation', t1.unreached_func("Should have not raised any event"));
+
+        document.getElementById('test').click();
+    </script>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_allowed-window_location.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_allowed-window_location.html
new file mode 100644
index 0000000..7dfb7b57
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_allowed-window_location.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <!--
+    'sha256-IIiAJ8UuliU8o1qAv6CV4P3R8DeTf/v3MrsCwXW171Y=' ==> 'javascript:opener.postMessage('pass', '*')'
+    -->
+    <script src='/resources/testharness.js' nonce='abc'></script>
+    <script src='/resources/testharnessreport.js' nonce='abc'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <script nonce='abc'>
+        var t1 = async_test("Test that the javascript: src is allowed to run");
+
+        window.onmessage = t1.step_func_done(function(e) {
+          assert_equals(e.data, "pass");
+        });
+
+        window.open('support/child_window_location_navigate.sub.html' + 
+              '?csp=' + encodeURI("script-src 'unsafe-hashes' 'nonce-abc' 'sha256-IIiAJ8UuliU8o1qAv6CV4P3R8DeTf/v3MrsCwXW171Y='") +
+              '&url=' + encodeURI("javascript:opener.postMessage('pass', '*')"));
+    </script>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_allowed-window_open.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_allowed-window_open.html
new file mode 100644
index 0000000..970290e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_allowed-window_open.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-hashes' 'nonce-abc'
+    'sha256-IIiAJ8UuliU8o1qAv6CV4P3R8DeTf/v3MrsCwXW171Y=';">
+    <!--
+    'sha256-IIiAJ8UuliU8o1qAv6CV4P3R8DeTf/v3MrsCwXW171Y=' ==> 'javascript:opener.postMessage('pass', '*')'
+    -->
+    <script src='/resources/testharness.js' nonce='abc'></script>
+    <script src='/resources/testharnessreport.js' nonce='abc'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <script nonce='abc'>
+        var t1 = async_test("Test that the javascript: src is allowed to run");
+
+        window.onmessage = t1.step_func_done(function(e) {
+          assert_equals(e.data, "pass");
+        });
+
+        window.addEventListener('securitypolicyviolation', t1.unreached_func("Should have not raised any event"));
+
+        window.open("javascript:opener.postMessage('pass', '*')");
+    </script>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-href.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-href.html
new file mode 100644
index 0000000..f53a2e92
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-href.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <meta http-equiv="Content-Security-Policy" content="script-src 'nonce-abc'
+    'sha256-3MhWOWQJwDMJCRltopqBmDhP4qq569eTDcH+BpbHp0o=';">
+    <!--
+    'sha256-3MhWOWQJwDMJCRltopqBmDhP4qq569eTDcH+BpbHp0o=' ==> javascript:t1.unreached_func("Should not have run javascript: URL");
+    -->
+    <script src='/resources/testharness.js' nonce='abc'></script>
+    <script src='/resources/testharnessreport.js' nonce='abc'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <a href='javascript:t1.unreached_func("Should not have run javascript: URL");' id='test'>
+    <script nonce='abc'>
+        var t1 = async_test("Test that the javascript: src is not allowed to run");
+
+        window.addEventListener('securitypolicyviolation', t1.step_func_done(function(e) {
+            assert_equals(e.violatedDirective, 'script-src');
+            assert_equals(e.blockedURI, 'inline');
+        }));
+
+        document.getElementById('test').click();
+    </script>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-href_blank.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-href_blank.html
new file mode 100644
index 0000000..6b9f60c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-href_blank.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-hashes' 'nonce-abc'
+    'sha256-r5W8SQIDMTbMxAjJ7KzCzFT38dwBy7Y5KF5B+20009g=';">
+    <!--
+    'sha256-3MhWOWQJwDMJCRltopqBmDhP4qq569eTDcH+BpbHp0o=' ==> javascript:t1.unreached_func("Should not have run javascript: URL");
+    -->
+    <script src='/resources/testharness.js' nonce='abc'></script>
+    <script src='/resources/testharnessreport.js' nonce='abc'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <a href='javascript:t1.unreached_func("Should not have run javascript: URL");' id='test'>
+    <script nonce='abc'>
+        var t1 = async_test("Test that the javascript: src is not allowed to run");
+
+        window.addEventListener('securitypolicyviolation', t1.step_func_done(function(e) {
+             assert_equals(e.violatedDirective, 'script-src');
+             assert_equals(e.blockedURI, 'inline');
+        }));
+
+        document.getElementById('test').click();
+    </script>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-window_location.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-window_location.html
new file mode 100644
index 0000000..c014bd1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-window_location.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <!--
+    'sha256-IIiAJ8UuliU8o1qAv6CV4P3R8DeTf/v3MrsCwXW171Y=' ==> 'javascript:opener.postMessage('pass', '*')'
+    -->
+    <script src='/resources/testharness.js' nonce='abc'></script>
+    <script src='/resources/testharnessreport.js' nonce='abc'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <script nonce='abc'>
+        var t1 = async_test("Test that the javascript: src is not allowed to run");
+
+        window.onmessage = t1.step_func_done(function(e) {
+          assert_equals(e.data, "fail");
+        });
+
+        window.open('support/child_window_location_navigate.sub.html' + 
+              '?csp=' + encodeURI("script-src 'nonce-abc' 'sha256-IIiAJ8UuliU8o1qAv6CV4P3R8DeTf/v3MrsCwXW171Y='") +
+              '&url=' + encodeURI("javascript:opener.postMessage('pass', '*')"));
+    </script>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-window_open.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-window_open.html
new file mode 100644
index 0000000..3667f80
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-window_open.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <meta http-equiv="Content-Security-Policy" content="script-src 'nonce-abc'
+    'sha256-IIiAJ8UuliU8o1qAv6CV4P3R8DeTf/v3MrsCwXW171Y=';">
+    <!--
+    'sha256-IIiAJ8UuliU8o1qAv6CV4P3R8DeTf/v3MrsCwXW171Y=' ==> 'javascript:opener.postMessage('pass', '*')'
+    -->
+    <script src='/resources/testharness.js' nonce='abc'></script>
+    <script src='/resources/testharnessreport.js' nonce='abc'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <script nonce='abc'>
+        var t1 = async_test("Test that the javascript: src is not allowed to run");
+
+        window.onmessage = t1.unreached_func("Should have not received any message");
+
+        window.addEventListener('securitypolicyviolation', t1.step_func_done(function(e) {
+            assert_equals(e.violatedDirective, 'script-src');
+            assert_equals(e.blockedURI, 'inline');
+        }));
+
+        window.open("javascript:opener.postMessage('pass', '*')");
+    </script>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-href.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-href.html
new file mode 100644
index 0000000..adae81b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-href.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-hashes' 'nonce-abc'
+    'sha256-r5W8SQIDMTbMxAjJ7KzCzFT38dwBy7Y5KF5B+20009g=';">
+    <!--
+    'sha256-3MhWOWQJwDMJCRltopqBmDhP4qq569eTDcH+BpbHp0o=' ==> javascript:t1.unreached_func("Should not have run javascript: URL");
+    -->
+    <script src='/resources/testharness.js' nonce='abc'></script>
+    <script src='/resources/testharnessreport.js' nonce='abc'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <a href='javascript:t1.unreached_func("Should not have run javascript: URL");' id='test'>
+    <script nonce='abc'>
+        var t1 = async_test("Test that the javascript: src is not allowed to run");
+
+        window.addEventListener('securitypolicyviolation', t1.step_func_done(function(e) {
+            assert_equals(e.violatedDirective, 'script-src');
+            assert_equals(e.blockedURI, 'inline');
+        }));
+
+        document.getElementById('test').click();
+    </script>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-href_blank.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-href_blank.html
new file mode 100644
index 0000000..470283e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-href_blank.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <meta http-equiv="Content-Security-Policy" content="script-src 'nonce-abc'
+    'sha256-3MhWOWQJwDMJCRltopqBmDhP4qq569eTDcH+BpbHp0o=';">
+    <!--
+    'sha256-3MhWOWQJwDMJCRltopqBmDhP4qq569eTDcH+BpbHp0o=' ==> javascript:t1.unreached_func("Should not have run javascript: URL");
+    -->
+    <script src='/resources/testharness.js' nonce='abc'></script>
+    <script src='/resources/testharnessreport.js' nonce='abc'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <a target="_blank" href='javascript:t1.unreached_func("Should not have run javascript: URL");' id='test'>
+    <script nonce='abc'>
+        var t1 = async_test("Test that the javascript: src is not allowed to run");
+
+        window.addEventListener('securitypolicyviolation', t1.step_func_done(function(e) {
+             assert_equals(e.violatedDirective, 'script-src');
+             assert_equals(e.blockedURI, 'inline');
+        }));
+
+        document.getElementById('test').click();
+    </script>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-window_location.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-window_location.html
new file mode 100644
index 0000000..cfb8d6b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-window_location.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <!--
+    'sha256-IIiAJ8UuliU8o1qAv6CV4P3R8DeTf/v3MrsCwXW171Y=' ==> 'javascript:opener.postMessage('pass', '*')'
+    -->
+    <script src='/resources/testharness.js' nonce='abc'></script>
+    <script src='/resources/testharnessreport.js' nonce='abc'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <script nonce='abc'>
+        var t1 = async_test("Test that the javascript: src is not allowed to run");
+
+        window.onmessage = t1.step_func_done(function(e) {
+          assert_equals(e.data, "fail");
+        });
+
+        window.open('support/child_window_location_navigate.sub.html' + 
+              '?csp=' + encodeURI("script-src 'unsafe-hashes' 'nonce-abc' 'sha256-VjH6k67F4kobUnNDOBE85QiJ9cuZMiYT6desKXvezVg='") +
+              '&url=' + encodeURI("javascript:opener.postMessage('pass', '*')"));
+    </script>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-window_open.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-window_open.html
new file mode 100644
index 0000000..8314e6a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-window_open.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-hashes' 'nonce-abc'
+    'sha256-VjH6k67F4kobUnNDOBE85QiJ9cuZMiYT6desKXvezVg=';">
+    <!--
+    'sha256-IIiAJ8UuliU8o1qAv6CV4P3R8DeTf/v3MrsCwXW171Y=' ==> 'javascript:opener.postMessage('pass', '*')'
+    -->
+    <script src='/resources/testharness.js' nonce='abc'></script>
+    <script src='/resources/testharnessreport.js' nonce='abc'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <script nonce='abc'>
+        var t1 = async_test("Test that the javascript: src is not allowed to run");
+
+        window.onmessage = t1.unreached_func("Should have not received any message");
+
+        window.addEventListener('securitypolicyviolation', t1.step_func_done(function(e) {
+            assert_equals(e.violatedDirective, 'script-src');
+            assert_equals(e.blockedURI, 'inline');
+        }));
+
+        window.open("javascript:opener.postMessage('pass', '*')");
+    </script>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashed-attributes/script_event_handlers_allowed.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/script_event_handlers_allowed.html
similarity index 80%
rename from third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashed-attributes/script_event_handlers_allowed.html
rename to third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/script_event_handlers_allowed.html
index 17f1938..cd78559 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashed-attributes/script_event_handlers_allowed.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/script_event_handlers_allowed.html
@@ -2,8 +2,8 @@
 <html>
 
 <head>
-    <meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-hashed-attributes' 'nonce-abc' 'sha256-wmuLCpoj8EMqfQlPnt5NIMgKkCK62CxAkAiewI0zZps='; img-src *;">
-    <title>Event handlers should be allowed if a matching hash and 'unsafe-hashed-attributes' are present</title>
+    <meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-hashes' 'nonce-abc' 'sha256-wmuLCpoj8EMqfQlPnt5NIMgKkCK62CxAkAiewI0zZps='; img-src *;">
+    <title>Event handlers should be allowed if a matching hash and 'unsafe-hashes' are present</title>
     <script src='/resources/testharness.js' nonce='abc'></script>
     <script src='/resources/testharnessreport.js' nonce='abc'></script>
 </head>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashed-attributes/script_event_handlers_denied_matching_hash_no_unsafe_inline_attribute.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/script_event_handlers_denied_missing_unsafe_hashes.html
similarity index 93%
rename from third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashed-attributes/script_event_handlers_denied_matching_hash_no_unsafe_inline_attribute.html
rename to third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/script_event_handlers_denied_missing_unsafe_hashes.html
index 1dae30cb..0323dda5 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashed-attributes/script_event_handlers_denied_matching_hash_no_unsafe_inline_attribute.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/script_event_handlers_denied_missing_unsafe_hashes.html
@@ -3,7 +3,7 @@
 
 <head>
     <meta http-equiv="Content-Security-Policy" content="script-src 'nonce-abc' 'sha256-Cb9N8BP42Neca22vQ9VaXlPU8oPF8HPxZHxRVcnLZJ4='; img-src *;">
-    <title>Event handlers should not be allowed if a matching hash is present without 'unsafe-hashed-attributes'</title>
+    <title>Event handlers should not be allowed if a matching hash is present without 'unsafe-hashes'</title>
     <script src='/resources/testharness.js' nonce='abc'></script>
     <script src='/resources/testharnessreport.js' nonce='abc'></script>
     
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashed-attributes/script_event_handlers_denied_not_matching_hash.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/script_event_handlers_denied_wrong_hash.html
similarity index 90%
rename from third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashed-attributes/script_event_handlers_denied_not_matching_hash.html
rename to third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/script_event_handlers_denied_wrong_hash.html
index 993ed55..b9b1357 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashed-attributes/script_event_handlers_denied_not_matching_hash.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/script_event_handlers_denied_wrong_hash.html
@@ -2,7 +2,7 @@
 <html>
 
 <head>
-    <meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-hashed-attributes' 'nonce-abc' 'sha256-thisdoesnotmatch'; img-src *;">
+    <meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-hashes' 'nonce-abc' 'sha256-thisdoesnotmatch'; img-src *;">
     <title>Event handlers should be not allowed if a matching hash is not present</title>
     <script src='/resources/testharness.js' nonce='abc'></script>
     <script src='/resources/testharnessreport.js' nonce='abc'></script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/style_attribute_allowed.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/style_attribute_allowed.html
new file mode 100644
index 0000000..69657ef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/style_attribute_allowed.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <meta http-equiv="Content-Security-Policy" content="img-src *;
+                      style-src 'unsafe-hashes' 'sha256-S0VSqEOmzmyOifPfat2sJ7ELOgkldAEbaXlvi5iMqjc=';">
+    <!--
+      'sha256-S0VSqEOmzmyOifPfat2sJ7ELOgkldAEbaXlvi5iMqjc=' ==> 'background: green'
+      -->
+    <title>Event handlers should be allowed if a matching hash and 'unsafe-hashes' are present</title>
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <script>
+        var t1 = async_test("Test that the inline style attribute is loaded");
+
+        function check_for_style() {
+          assert_equals("green", document.getElementById('test').style.background);
+          t1.done();
+        }
+
+        window.addEventListener('securitypolicyviolation', t1.unreached_func("Should have not raised any event"));
+    </script>
+    <img src='../support/pass.png' id='test' style='background: green'
+         onload='check_for_style()'>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/style_attribute_denied_missing_unsafe_hashes.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/style_attribute_denied_missing_unsafe_hashes.html
new file mode 100644
index 0000000..66be2c3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/style_attribute_denied_missing_unsafe_hashes.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <meta http-equiv="Content-Security-Policy" content="img-src *;
+                      style-src 'sha256-S0VSqEOmzmyOifPfat2sJ7ELOgkldAEbaXlvi5iMqjc=';">
+    <!--
+      'sha256-S0VSqEOmzmyOifPfat2sJ7ELOgkldAEbaXlvi5iMqjc=' ==> 'background: green'
+      -->
+    <title>Event handlers should be allowed if a matching hash and 'unsafe-hashes' are present</title>
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <script>
+        var t1 = async_test("Test that the inline style attribute is blocked");
+        
+        window.addEventListener('securitypolicyviolation', t1.step_func_done(function(e) {
+            assert_equals(e.violatedDirective, 'style-src');
+            assert_equals(e.blockedURI, 'inline');
+        }));
+
+    </script>
+    <img src='../support/pass.png' id='test' style='background: green'>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/style_attribute_denied_wrong_hash.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/style_attribute_denied_wrong_hash.html
new file mode 100644
index 0000000..32ca66a8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/style_attribute_denied_wrong_hash.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <meta http-equiv="Content-Security-Policy" content="img-src *;
+                      style-src 'unsafe-hashes' 'sha256-UI8QfroYhb0WX073XBuM+RTPntpjZfkyFLsMw5vQfd0=';">
+    <!--
+      'sha256-S0VSqEOmzmyOifPfat2sJ7ELOgkldAEbaXlvi5iMqjc=' ==> 'background: green'
+      -->
+    <title>Event handlers should be allowed if a matching hash and 'unsafe-hashes' are present</title>
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+</head>
+
+<body>
+    <div id='log'></div>
+    <script>
+        var t1 = async_test("Test that the inline style attribute is blocked");
+
+        window.addEventListener('securitypolicyviolation', t1.step_func_done(function(e) {
+            assert_equals(e.violatedDirective, 'style-src');
+            assert_equals(e.blockedURI, 'inline');
+        }));
+
+    </script>
+    <img src='../support/pass.png' id='test' style='background: green'>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/support/child_window_location_navigate.sub.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/support/child_window_location_navigate.sub.html
new file mode 100644
index 0000000..b6e60467
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/unsafe-hashes/support/child_window_location_navigate.sub.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+    <meta http-equiv="Content-Security-Policy" content="{{GET[csp]}}">
+</head>
+
+<body>
+  <script nonce='abc'>
+    window.addEventListener('securitypolicyviolation', function(e) {
+      opener.postMessage('fail', '*');
+    });
+
+    window.location.href = "{{GET[url]}}";
+  </script>
+</body>
+
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-013.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-013.html
new file mode 100644
index 0000000..f1bbc08
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-013.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Containment Test: Size containment replaced elements intrinsic size</title>
+<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-size">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name=assert content="This test checks that intrinsic size of replaced elements with 'contain: size' is zero.">
+<style>
+img {
+  background: green;
+  padding: 50px;
+  contain: size;
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<img src="/css/support/60x60-red.png" />
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html
new file mode 100644
index 0000000..8ca69ccd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>CSS Test: &lt;link rel="stylesheet"&gt; in Shadow DOM doesn't affect the normal DOM</title>
+<link rel="help" href="https://html.spec.whatwg.org/#link-type-stylesheet">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<style>
+  #light-dom {
+    width: 100px;
+    height: 100px;
+    background: green;
+    color: green;
+  }
+</style>
+<div id="host">FAIL</div>
+<div id="light-dom"></div>
+<script>
+  host.attachShadow({ mode: "open" }).innerHTML = `
+    <link rel="stylesheet" href="data:text/css,div { background: red !important }">
+  `;
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/shadow-link-rel-stylesheet.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/shadow-link-rel-stylesheet.html
new file mode 100644
index 0000000..d67929a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/shadow-link-rel-stylesheet.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>CSS Test: &lt;link rel="stylesheet"&gt; in Shadow DOM</title>
+<link rel="help" href="https://html.spec.whatwg.org/#link-type-stylesheet">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host">FAIL</div>
+<script>
+  host.attachShadow({ mode: "open" }).innerHTML = `
+    <link rel="stylesheet" href="resources/host-green-box.css">
+  `;
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/box-sizing-invalid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/box-sizing-invalid.html
index 90bb5a1..4ced382 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/box-sizing-invalid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/box-sizing-invalid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="box-sizing supports only the grammar 'content-box | border-box'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/box-sizing-valid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/box-sizing-valid.html
index 3d23d47..fb60ac23 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/box-sizing-valid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/box-sizing-valid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="box-sizing supports the full grammar 'content-box | border-box'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/caret-color-invalid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/caret-color-invalid.html
index 9751b9b..b4c9cb7 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/caret-color-invalid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/caret-color-invalid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="caret-color supports only the grammar 'auto | <color>'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/caret-color-valid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/caret-color-valid.html
index 81cfe25..41cc706 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/caret-color-valid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/caret-color-valid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="caret-color supports the full grammar 'auto | <color>'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/cursor-invalid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/cursor-invalid.html
index bd05530..dda8031 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/cursor-invalid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/cursor-invalid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="cursor supports only the grammar.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/cursor-valid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/cursor-valid.html
index 20ea2675..e33b82e 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/cursor-valid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/cursor-valid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="cursor supports the full grammar.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-color-invalid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-color-invalid.html
index 029c1e9..195f55d 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-color-invalid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-color-invalid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="outline-color supports only the grammar '<color> | invert'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-color-valid-mandatory.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-color-valid-mandatory.html
index 891bbc00..fbe730b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-color-valid-mandatory.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-color-valid-mandatory.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="outline-color supports '<color>'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-color-valid-optional.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-color-valid-optional.html
index bd3b9e6..bf12b87f 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-color-valid-optional.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-color-valid-optional.html
@@ -9,7 +9,7 @@
 <meta name="flags" content="may">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-invalid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-invalid.html
index ea8d88b..c56a579 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-invalid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-invalid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="outline supports only the grammar '<outline-color> || <outline> || <outline>'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-offset-invalid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-offset-invalid.html
index f547160..1ee9477 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-offset-invalid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-offset-invalid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="outline-offset supports only the grammar '<length>'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-offset-valid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-offset-valid.html
index a7064e55..c5e023b8 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-offset-valid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-offset-valid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="outline-offset supports the full grammar '<length>'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-style-invalid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-style-invalid.html
index 1ea6230..2340c62 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-style-invalid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-style-invalid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="outline-style supports only the grammar 'auto | <outline-line-style>'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-style-valid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-style-valid.html
index cebf614..5adcfda 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-style-valid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-style-valid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="outline-style supports the full grammar 'auto | <outline-line-style>'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-valid-mandatory.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-valid-mandatory.html
index f4cfe2cf..a296c98 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-valid-mandatory.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-valid-mandatory.html
@@ -9,7 +9,7 @@
 <meta name="assert" content="outline supports the full grammar '<outline-color> || <outline> || <outline>'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-valid-optional.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-valid-optional.html
index 66ec8973e..e179406c 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-valid-optional.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-valid-optional.html
@@ -11,7 +11,7 @@
 <meta name="flags" content="may">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-width-invalid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-width-invalid.html
index 71cb5337..07012fef 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-width-invalid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-width-invalid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="outline-width supports only the grammar '<border-width>'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-width-valid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-width-valid.html
index f683991..050371246 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-width-valid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/outline-width-valid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="outline-width supports the full grammar '<border-width>'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resize-invalid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resize-invalid.html
index 5fdb8ee..a56a1dbc 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resize-invalid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resize-invalid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="resize supports only the grammar 'none | both | horizontal | vertical'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resize-valid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resize-valid.html
index e9f03d9..025b0e4 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resize-valid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resize-valid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="resize supports the full grammar 'none | both | horizontal | vertical'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resources/parsing-testcommon.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/support/parsing-testcommon.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resources/parsing-testcommon.js
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/support/parsing-testcommon.js
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/text-overflow-invalid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/text-overflow-invalid.html
index f397481..f3945a1 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/text-overflow-invalid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/text-overflow-invalid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="text-overflow supports only the grammar 'clip | ellipsis'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/text-overflow-valid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/text-overflow-valid.html
index 80f267ea..3f0aaa60 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/text-overflow-valid.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/text-overflow-valid.html
@@ -8,7 +8,7 @@
 <meta name="assert" content="text-overflow supports the full grammar 'clip | ellipsis'.">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/parsing-testcommon.js"></script>
+<script src="support/parsing-testcommon.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/Document-createElement.html b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/Document-createElement.html
index cc946a4..fc43fc4 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/Document-createElement.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/Document-createElement.html
@@ -363,6 +363,31 @@
 
 }, 'document.createElement must report an exception thrown by a custom element constructor');
 
+test(function () {
+    var exceptionToThrow = {name: 'exception thrown by a custom constructor'};
+    class ThrowCustomBuiltinElement extends HTMLDivElement {
+        constructor()
+        {
+            super();
+            if (exceptionToThrow)
+                throw exceptionToThrow;
+        }
+    };
+    customElements.define('throw-custom-builtin-element', ThrowCustomBuiltinElement, { extends: 'div' });
+
+    assert_throws(exceptionToThrow, function () { new ThrowCustomBuiltinElement; });
+    var instance;
+    assert_reports(exceptionToThrow, function () { instance = document.createElement('div', { is: 'throw-custom-builtin-element' }); });
+    assert_equals(instance.localName, 'div');
+    assert_true(instance instanceof HTMLDivElement);
+
+    exceptionToThrow = false;
+    var instance = document.createElement('div', { is: 'throw-custom-builtin-element' });
+    assert_true(instance instanceof ThrowCustomBuiltinElement);
+    assert_equals(instance.localName, 'div');
+
+}, 'document.createElement must report an exception thrown by a custom built-in element constructor');
+
 test(() => {
   class MyElement extends HTMLDivElement {}
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/sec-metadata/fetch.tentative.https.sub.html b/third_party/WebKit/LayoutTests/external/wpt/fetch/sec-metadata/fetch.tentative.https.sub.html
index 2fd6a4b..7a2c223 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/sec-metadata/fetch.tentative.https.sub.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/sec-metadata/fetch.tentative.https.sub.html
@@ -9,7 +9,7 @@
         .then(j => {
           assert_header_equals(j.header, {
             "cause": undefined,
-            "destination": "\"\"",
+            "destination": "",
             "target": "subresource",
             "site": "same-origin"
           });
@@ -22,7 +22,7 @@
         .then(j => {
           assert_header_equals(j.header, {
             "cause": undefined,
-            "destination": "\"\"",
+            "destination": "",
             "target": "subresource",
             "site": "same-site"
           });
@@ -35,7 +35,7 @@
         .then(j => {
           assert_header_equals(j.header, {
             "cause": undefined,
-            "destination": "\"\"",
+            "destination": "",
             "target": "subresource",
             "site": "cross-site"
           });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/sec-metadata/resources/helper.js b/third_party/WebKit/LayoutTests/external/wpt/fetch/sec-metadata/resources/helper.js
index 5754b50..03d2d2d 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/sec-metadata/resources/helper.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/sec-metadata/resources/helper.js
@@ -2,6 +2,7 @@
   let result = {};
   value.split(',').forEach(item => {
     let parsed = item.trim().split('=');
+    parsed[1] = parsed[1].trim().replace(/^"|"$/g, '');
     result[parsed[0]] = parsed[1];
   });
   return result;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-classic.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-classic.html
index 6191827..33714c7 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-classic.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-classic.html
@@ -3,7 +3,7 @@
 <title>import() inside compiled strings uses the appropriate nonce inside a classic script</title>
 <link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
 
-<meta http-equiv="content-security-policy" content="script-src 'nonce-correct' 'unsafe-eval' 'unsafe-hashed-attributes' 'sha256-cAMzxBL19bKt4KwKGbxy/ZOFIIjH5AmRjlVbsD5pvNw=' 'sha256-3VjoJYNK/9HJMS8rrZHlqSZgUssDY+GPyc7AU8lNM3k='">
+<meta http-equiv="content-security-policy" content="script-src 'nonce-correct' 'unsafe-eval' 'unsafe-hashes' 'sha256-cAMzxBL19bKt4KwKGbxy/ZOFIIjH5AmRjlVbsD5pvNw=' 'sha256-3VjoJYNK/9HJMS8rrZHlqSZgUssDY+GPyc7AU8lNM3k='">
 
 <script nonce="correct" src="/resources/testharness.js"></script>
 <script nonce="correct" src="/resources/testharnessreport.js"></script>
@@ -74,7 +74,7 @@
 
   const promise = createTestPromise(t);
 
-  // This only works because of the 'unsafe-hashed-attributes' and the hash in the CSP policy
+  // This only works because of the 'unsafe-hashes' and the hash in the CSP policy
   dummyDiv.setAttribute(
     "onclick",
     `import('../imports-a.js?label=reflected inline event handlers').then(window.continueTest, window.errorTest)`
@@ -91,7 +91,7 @@
 
   const promise = createTestPromise(t);
 
-  // This only works because of the 'unsafe-hashed-attributes' and the hash in the CSP policy
+  // This only works because of the 'unsafe-hashes' and the hash in the CSP policy
   dummyDiv.setAttribute(
     "onclick",
     `import('../imports-a.js?label=inline event handlers triggered via UA code').then(window.continueTest, window.errorTest)`
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-module.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-module.html
index 3e09dd6d..9411acd2 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-module.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-module.html
@@ -3,7 +3,7 @@
 <title>import() inside compiled strings uses the appropriate nonce inside a module script</title>
 <link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
 
-<meta http-equiv="content-security-policy" content="script-src 'nonce-correct' 'unsafe-eval' 'unsafe-hashed-attributes' 'sha256-cAMzxBL19bKt4KwKGbxy/ZOFIIjH5AmRjlVbsD5pvNw=' 'sha256-3VjoJYNK/9HJMS8rrZHlqSZgUssDY+GPyc7AU8lNM3k='">
+<meta http-equiv="content-security-policy" content="script-src 'nonce-correct' 'unsafe-eval' 'unsafe-hashes' 'sha256-cAMzxBL19bKt4KwKGbxy/ZOFIIjH5AmRjlVbsD5pvNw=' 'sha256-3VjoJYNK/9HJMS8rrZHlqSZgUssDY+GPyc7AU8lNM3k='">
 
 <script nonce="correct" src="/resources/testharness.js"></script>
 <script nonce="correct" src="/resources/testharnessreport.js"></script>
@@ -73,7 +73,7 @@
 
   const promise = createTestPromise(t);
 
-  // This only works because of the 'unsafe-hashed-attributes' and the hash in the CSP policy
+  // This only works because of the 'unsafe-hashes' and the hash in the CSP policy
   dummyDiv.setAttribute(
     "onclick",
     `import('../imports-a.js?label=reflected inline event handlers').then(window.continueTest, window.errorTest)`
@@ -90,7 +90,7 @@
 
   const promise = createTestPromise(t);
 
-  // This only works because of the 'unsafe-hashed-attributes' and the hash in the CSP policy
+  // This only works because of the 'unsafe-hashes' and the hash in the CSP policy
   dummyDiv.setAttribute(
     "onclick",
     `import('../imports-a.js?label=inline event handlers triggered via UA code').then(window.continueTest, window.errorTest)`
diff --git a/third_party/WebKit/LayoutTests/external/wpt/infrastructure/server/title.any.js b/third_party/WebKit/LayoutTests/external/wpt/infrastructure/server/title.any.js
new file mode 100644
index 0000000..df2f8b04
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/infrastructure/server/title.any.js
@@ -0,0 +1,13 @@
+// META: global=window,dedicatedworker,sharedworker
+// META: title=foobar
+test(t => {
+  if (GLOBAL.isWindow()) {
+    assert_equals(document.title, 'foobar');
+    assert_false('META_TITLE' in self);
+  } else {
+    assert_equals(META_TITLE, 'foobar');
+  }
+  assert_equals(t.name, 'foobar');
+});
+
+done();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/infrastructure/server/title.any.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/infrastructure/server/title.any.sharedworker-expected.txt
new file mode 100644
index 0000000..41c78f59
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/infrastructure/server/title.any.sharedworker-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL title META_TITLE is not defined
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/infrastructure/server/title.any.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/infrastructure/server/title.any.worker-expected.txt
new file mode 100644
index 0000000..41c78f59
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/infrastructure/server/title.any.worker-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL title META_TITLE is not defined
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/beacon.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/beacon.idl
new file mode 100644
index 0000000..66344856
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/beacon.idl
@@ -0,0 +1,8 @@
+// GENERATED CONTENT - DO NOT EDIT
+// Content of this file was automatically extracted from the
+// "Beacon" spec.
+// See: https://w3c.github.io/beacon/
+
+partial interface Navigator {
+    boolean sendBeacon(USVString url, optional BodyInit? data = null);
+};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/testharness.js b/third_party/WebKit/LayoutTests/external/wpt/resources/testharness.js
index 9889795..d4bf292 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/resources/testharness.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/resources/testharness.js
@@ -213,12 +213,9 @@
     }
 
     WindowTestEnvironment.prototype.next_default_test_name = function() {
-        //Don't use document.title to work around an Opera bug in XHTML documents
-        var title = document.getElementsByTagName("title")[0];
-        var prefix = (title && title.firstChild && title.firstChild.data) || "Untitled";
         var suffix = this.name_counter > 0 ? " " + this.name_counter : "";
         this.name_counter++;
-        return prefix + suffix;
+        return get_title() + suffix;
     };
 
     WindowTestEnvironment.prototype.on_new_harness_properties = function(properties) {
@@ -288,7 +285,7 @@
     WorkerTestEnvironment.prototype.next_default_test_name = function() {
         var suffix = this.name_counter > 0 ? " " + this.name_counter : "";
         this.name_counter++;
-        return "Untitled" + suffix;
+        return get_title() + suffix;
     };
 
     WorkerTestEnvironment.prototype.on_new_harness_properties = function() {};
@@ -2917,6 +2914,25 @@
         return undefined;
     }
 
+    /** Returns the <title> or filename or "Untitled" */
+    function get_title()
+    {
+        if ('document' in global_scope) {
+            //Don't use document.title to work around an Opera bug in XHTML documents
+            var title = document.getElementsByTagName("title")[0];
+            if (title && title.firstChild && title.firstChild.data) {
+                return title.firstChild.data;
+            }
+        }
+        if ('META_TITLE' in global_scope && META_TITLE) {
+            return META_TITLE;
+        }
+        if ('location' in global_scope) {
+            return location.pathname.substring(location.pathname.lastIndexOf('/') + 1, location.pathname.indexOf('.'));
+        }
+        return "Untitled";
+    }
+
     function supports_post_message(w)
     {
         var supports;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/META.yml b/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/META.yml
index 73ae3b20..1ab5f04 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/META.yml
+++ b/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/META.yml
@@ -1,4 +1,3 @@
 suggested_reviewers:
   - birtles
   - theres-waldo
-  - manta12
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/navigation-redirect.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/navigation-redirect.https.html
index 3f12c2f..ed300fa 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/navigation-redirect.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/navigation-redirect.https.html
@@ -1,5 +1,6 @@
 <!DOCTYPE html>
 <title>Service Worker: Navigation redirection</title>
+<meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/common/get-host-info.sub.js"></script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/construct-byob-request.dedicatedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/construct-byob-request.dedicatedworker-expected.txt
index b4cca16..c640a4fbd 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/construct-byob-request.dedicatedworker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/construct-byob-request.dedicatedworker-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Untitled Uncaught RangeError: bytes type is not yet implemented
+FAIL construct-byob-request Uncaught RangeError: bytes type is not yet implemented
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/construct-byob-request.sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/construct-byob-request.sharedworker-expected.txt
index b4cca16..c640a4fbd 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/construct-byob-request.sharedworker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-byte-streams/construct-byob-request.sharedworker-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Untitled Uncaught RangeError: bytes type is not yet implemented
+FAIL construct-byob-request Uncaught RangeError: bytes type is not yet implemented
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/interfaces/WorkerUtils/importScripts/002.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/workers/interfaces/WorkerUtils/importScripts/002.worker-expected.txt
index 3686fa8c..cce58ba 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/workers/interfaces/WorkerUtils/importScripts/002.worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/workers/interfaces/WorkerUtils/importScripts/002.worker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-FAIL Untitled assert_throws: function "function() {
+FAIL 002 assert_throws: function "function() {
     importScripts('data:text/javascript,ran=true','http://foo bar');
   }" threw object "NetworkError: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://foo%20bar/' failed to load." that is not a DOMException SyntaxError: property "code" is equal to 19, expected 12
 Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/semantics/structured-clone/dedicated-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/workers/semantics/structured-clone/dedicated-expected.txt
new file mode 100644
index 0000000..3c8beb85
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/workers/semantics/structured-clone/dedicated-expected.txt
@@ -0,0 +1,119 @@
+This is a testharness.js-based test.
+Found 115 tests; 112 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS primitive undefined
+PASS primitive null
+PASS primitive true
+PASS primitive false
+PASS primitive string, empty string
+PASS primitive string, lone high surrogate
+PASS primitive string, lone low surrogate
+PASS primitive string, NUL
+PASS primitive string, astral character
+PASS primitive number, 0.2
+PASS primitive number, 0
+PASS primitive number, -0
+PASS primitive number, NaN
+PASS primitive number, Infinity
+PASS primitive number, -Infinity
+PASS primitive number, 9007199254740992
+PASS primitive number, -9007199254740992
+PASS primitive number, 9007199254740994
+PASS primitive number, -9007199254740994
+PASS Array primitives
+PASS Object primitives
+PASS Boolean true
+PASS Boolean false
+PASS Array Boolean objects
+PASS Object Boolean objects
+PASS String empty string
+PASS String lone high surrogate
+PASS String lone low surrogate
+PASS String NUL
+PASS String astral character
+PASS Array String objects
+PASS Object String objects
+PASS Number 0.2
+PASS Number 0
+PASS Number -0
+PASS Number NaN
+PASS Number Infinity
+PASS Number -Infinity
+PASS Number 9007199254740992
+PASS Number -9007199254740992
+PASS Number 9007199254740994
+PASS Number -9007199254740994
+PASS Array Number objects
+PASS Object Number objects
+PASS Date 0
+PASS Date -0
+PASS Date -8.64e15
+PASS Date 8.64e15
+PASS Array Date objects
+PASS Object Date objects
+PASS RegExp flags and lastIndex
+PASS RegExp sticky flag
+PASS RegExp unicode flag
+PASS RegExp empty
+PASS RegExp slash
+FAIL RegExp new line assert_equals: source expected "\\n" but got "\n"
+PASS Array RegExp object, RegExp flags and lastIndex
+PASS Array RegExp object, RegExp sticky flag
+PASS Array RegExp object, RegExp unicode flag
+PASS Array RegExp object, RegExp empty
+PASS Array RegExp object, RegExp slash
+FAIL Array RegExp object, RegExp new line assert_equals: source expected "\\n" but got "\n"
+PASS Object RegExp object, RegExp flags and lastIndex
+PASS Object RegExp object, RegExp sticky flag
+PASS Object RegExp object, RegExp unicode flag
+PASS Object RegExp object, RegExp empty
+PASS Object RegExp object, RegExp slash
+FAIL Object RegExp object, RegExp new line assert_equals: source expected "\\n" but got "\n"
+PASS Blob basic
+PASS Blob unpaired high surrogate (invalid utf-8)
+PASS Blob unpaired low surrogate (invalid utf-8)
+PASS Blob paired surrogates (invalid utf-8)
+PASS Blob empty
+PASS Blob NUL
+PASS Array Blob object, Blob basic
+PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8)
+PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8)
+PASS Array Blob object, Blob paired surrogates (invalid utf-8)
+PASS Array Blob object, Blob empty
+PASS Array Blob object, Blob NUL
+PASS Object Blob object, Blob basic
+PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8)
+PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8)
+PASS Object Blob object, Blob paired surrogates (invalid utf-8)
+PASS Object Blob object, Blob empty
+PASS Object Blob object, Blob NUL
+PASS File basic
+PASS FileList empty
+PASS Array FileList object, FileList empty
+PASS Object FileList object, FileList empty
+PASS ImageData 1x1 transparent black
+PASS ImageData 1x1 non-transparent non-black
+PASS Array ImageData object, ImageData 1x1 transparent black
+PASS Array ImageData object, ImageData 1x1 non-transparent non-black
+PASS Object ImageData object, ImageData 1x1 transparent black
+PASS Object ImageData object, ImageData 1x1 non-transparent non-black
+PASS Array sparse
+PASS Array with non-index property
+PASS Object with index property and length
+PASS Array with circular reference
+PASS Object with circular reference
+PASS Array with identical property values
+PASS Object with identical property values
+PASS Object with property on prototype
+PASS Object with non-enumerable property
+PASS Object with non-writable property
+PASS Object with non-configurable property
+PASS ImageBitmap 1x1 transparent black
+PASS ImageBitmap 1x1 non-transparent non-black
+PASS Array ImageBitmap object, ImageBitmap 1x1 transparent black
+PASS Array ImageBitmap object, ImageBitmap 1x1 transparent non-black
+PASS Object ImageBitmap object, ImageBitmap 1x1 transparent black
+PASS Object ImageBitmap object, ImageBitmap 1x1 transparent non-black
+PASS ArrayBuffer
+PASS MessagePort
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/semantics/structured-clone/shared-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/workers/semantics/structured-clone/shared-expected.txt
new file mode 100644
index 0000000..3c8beb85
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/workers/semantics/structured-clone/shared-expected.txt
@@ -0,0 +1,119 @@
+This is a testharness.js-based test.
+Found 115 tests; 112 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS primitive undefined
+PASS primitive null
+PASS primitive true
+PASS primitive false
+PASS primitive string, empty string
+PASS primitive string, lone high surrogate
+PASS primitive string, lone low surrogate
+PASS primitive string, NUL
+PASS primitive string, astral character
+PASS primitive number, 0.2
+PASS primitive number, 0
+PASS primitive number, -0
+PASS primitive number, NaN
+PASS primitive number, Infinity
+PASS primitive number, -Infinity
+PASS primitive number, 9007199254740992
+PASS primitive number, -9007199254740992
+PASS primitive number, 9007199254740994
+PASS primitive number, -9007199254740994
+PASS Array primitives
+PASS Object primitives
+PASS Boolean true
+PASS Boolean false
+PASS Array Boolean objects
+PASS Object Boolean objects
+PASS String empty string
+PASS String lone high surrogate
+PASS String lone low surrogate
+PASS String NUL
+PASS String astral character
+PASS Array String objects
+PASS Object String objects
+PASS Number 0.2
+PASS Number 0
+PASS Number -0
+PASS Number NaN
+PASS Number Infinity
+PASS Number -Infinity
+PASS Number 9007199254740992
+PASS Number -9007199254740992
+PASS Number 9007199254740994
+PASS Number -9007199254740994
+PASS Array Number objects
+PASS Object Number objects
+PASS Date 0
+PASS Date -0
+PASS Date -8.64e15
+PASS Date 8.64e15
+PASS Array Date objects
+PASS Object Date objects
+PASS RegExp flags and lastIndex
+PASS RegExp sticky flag
+PASS RegExp unicode flag
+PASS RegExp empty
+PASS RegExp slash
+FAIL RegExp new line assert_equals: source expected "\\n" but got "\n"
+PASS Array RegExp object, RegExp flags and lastIndex
+PASS Array RegExp object, RegExp sticky flag
+PASS Array RegExp object, RegExp unicode flag
+PASS Array RegExp object, RegExp empty
+PASS Array RegExp object, RegExp slash
+FAIL Array RegExp object, RegExp new line assert_equals: source expected "\\n" but got "\n"
+PASS Object RegExp object, RegExp flags and lastIndex
+PASS Object RegExp object, RegExp sticky flag
+PASS Object RegExp object, RegExp unicode flag
+PASS Object RegExp object, RegExp empty
+PASS Object RegExp object, RegExp slash
+FAIL Object RegExp object, RegExp new line assert_equals: source expected "\\n" but got "\n"
+PASS Blob basic
+PASS Blob unpaired high surrogate (invalid utf-8)
+PASS Blob unpaired low surrogate (invalid utf-8)
+PASS Blob paired surrogates (invalid utf-8)
+PASS Blob empty
+PASS Blob NUL
+PASS Array Blob object, Blob basic
+PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8)
+PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8)
+PASS Array Blob object, Blob paired surrogates (invalid utf-8)
+PASS Array Blob object, Blob empty
+PASS Array Blob object, Blob NUL
+PASS Object Blob object, Blob basic
+PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8)
+PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8)
+PASS Object Blob object, Blob paired surrogates (invalid utf-8)
+PASS Object Blob object, Blob empty
+PASS Object Blob object, Blob NUL
+PASS File basic
+PASS FileList empty
+PASS Array FileList object, FileList empty
+PASS Object FileList object, FileList empty
+PASS ImageData 1x1 transparent black
+PASS ImageData 1x1 non-transparent non-black
+PASS Array ImageData object, ImageData 1x1 transparent black
+PASS Array ImageData object, ImageData 1x1 non-transparent non-black
+PASS Object ImageData object, ImageData 1x1 transparent black
+PASS Object ImageData object, ImageData 1x1 non-transparent non-black
+PASS Array sparse
+PASS Array with non-index property
+PASS Object with index property and length
+PASS Array with circular reference
+PASS Object with circular reference
+PASS Array with identical property values
+PASS Object with identical property values
+PASS Object with property on prototype
+PASS Object with non-enumerable property
+PASS Object with non-writable property
+PASS Object with non-configurable property
+PASS ImageBitmap 1x1 transparent black
+PASS ImageBitmap 1x1 non-transparent non-black
+PASS Array ImageBitmap object, ImageBitmap 1x1 transparent black
+PASS Array ImageBitmap object, ImageBitmap 1x1 transparent non-black
+PASS Object ImageBitmap object, ImageBitmap 1x1 transparent black
+PASS Object ImageBitmap object, ImageBitmap 1x1 transparent non-black
+PASS ArrayBuffer
+PASS MessagePort
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/fast/forms/form-element-geometry.html b/third_party/WebKit/LayoutTests/fast/forms/form-element-geometry.html
index b51d8d7..12e5862c 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/form-element-geometry.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/form-element-geometry.html
@@ -1,3 +1,4 @@
+<!doctype html>
 <html>
 
 <head>
diff --git a/third_party/WebKit/LayoutTests/fast/speech/scripted/mock-speechrecognizer.js b/third_party/WebKit/LayoutTests/fast/speech/scripted/mock-speechrecognizer.js
new file mode 100644
index 0000000..25036f1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/speech/scripted/mock-speechrecognizer.js
@@ -0,0 +1,122 @@
+'use strict';
+
+// MockSpeechRecognizer is a mock implementation of mojom::SpeechRecognizer and
+// the browser speech recognition service. It currently only supports running
+// one recognition session at a time. Mock results can be set using
+// addMockSpeechRecognitionResult, and setMockSpeechRecognitionError can be used
+// to simulate an error state. If no mock results are set, a NoMatch error is
+// sent to the client.
+class MockSpeechRecognizer {
+  constructor() {
+    this.results_ = [];
+    this.session_ = null;
+    this.session_client_ = null;
+    this.error_ = null;
+    this.lastSetTimeout_ = null;
+
+    this.task_queue_ = [];
+
+    this.binding_ = new mojo.Binding(blink.mojom.SpeechRecognizer, this);
+    this.interceptor_ = new MojoInterfaceInterceptor(blink.mojom.SpeechRecognizer.name);
+    this.interceptor_.oninterfacerequest = e => {
+      this.binding_.bind(e.handle);
+      this.binding_.setConnectionErrorHandler(() => {
+        this.reset();
+      });
+    };
+    this.interceptor_.start();
+  }
+
+  reset() {
+    this.binding_.close();
+    this.results_ = [];
+    this.session_ = null;
+    this.session_client_ = null;
+    this.error_ = null;
+  }
+
+  addMockSpeechRecognitionResult(transcript, confidence) {
+    let toString16 = function(string) {
+      let array = new Array(string.length);
+      for (var i = 0; i < string.length; ++i) {
+        array[i] = string.charCodeAt(i);
+      }
+      return { data: array };
+    }
+    var hypothesis = new blink.mojom.SpeechRecognitionHypothesis({
+      utterance: toString16(transcript),
+      confidence: confidence
+    });
+    var result = new blink.mojom.SpeechRecognitionResult({
+      hypotheses: [hypothesis],
+      is_provisional: false
+    });
+    this.results_.push(result);
+  }
+
+  setMockSpeechRecognitionError(errorCode) {
+    this.error_ = new blink.mojom.SpeechRecognitionError({
+      code: errorCode,
+      details: blink.mojom.SpeechAudioErrorDetails.kNone
+    });
+  }
+
+  dispatchError() {
+    this.session_client_.errorOccurred(this.error_);
+    this.error_ = null;
+    this.session_client_.ended();
+  }
+
+  dispatchResult() {
+    this.session_client_.started();
+    this.session_client_.audioStarted();
+    this.session_client_.soundStarted();
+
+    if (this.results_.length) {
+      this.results_.forEach(result => {
+        this.session_client_.resultRetrieved([result]);
+      });
+      this.results_ = [];
+    } else {
+      var error = new blink.mojom.SpeechRecognitionError({
+        code: blink.mojom.SpeechRecognitionErrorCode.kNoMatch,
+        details: blink.mojom.SpeechAudioErrorDetails.kNone
+      });
+      this.session_client_.errorOccurred(error);
+    }
+    this.session_client_.soundEnded();
+    this.session_client_.audioEnded();
+    this.session_client_.ended();
+  }
+
+  start(params) {
+    this.session_ = new MockSpeechRecognitionSession(params.sessionRequest, this);
+    this.session_client_ = params.client;
+
+    // if setMockSpeechRecognitionError was called
+    if (this.error_) {
+      this.dispatchError();
+      return;
+    }
+
+    this.dispatchResult();
+  }
+}
+
+let mockSpeechRecognizer = new MockSpeechRecognizer();
+
+class MockSpeechRecognitionSession {
+  constructor(request, recognizer) {
+    this.binding_ = new mojo.Binding(blink.mojom.SpeechRecognitionSession, this, request);
+    this.binding_.setConnectionErrorHandler(() => {
+      this.binding_.close();
+    });
+    this.recognizer_ = recognizer;
+  }
+
+  stop() {}
+
+  abort() {
+    this.recognizer_.session_client_.ended();
+  }
+}
diff --git a/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-basics.html b/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-basics.html
index 57d0d3e..e738b08 100644
--- a/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-basics.html
+++ b/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-basics.html
@@ -2,6 +2,9 @@
 <html>
 <head>
 <script src="../../../resources/js-test.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/third_party/blink/public/mojom/speech/speech_recognizer.mojom.js"></script>
+<script src="mock-speechrecognizer.js"></script>
 </head>
 <body>
 <script type="text/javascript">
@@ -50,10 +53,7 @@
         ++count;
         noMatchTest();
     }
-
-    if (window.testRunner) {
-        testRunner.addMockSpeechRecognitionResult('hello, world', 0.42);
-    }
+    mockSpeechRecognizer.addMockSpeechRecognitionResult('hello, world', 0.42);
     r.start();
 }
 
diff --git a/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-detached-no-crash.html b/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-detached-no-crash.html
index 709fb66..171dafc 100644
--- a/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-detached-no-crash.html
+++ b/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-detached-no-crash.html
@@ -2,6 +2,9 @@
 <html>
 <head>
 <script src="../../../resources/js-test.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/third_party/blink/public/mojom/speech/speech_recognizer.mojom.js"></script>
+<script src="mock-speechrecognizer.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-errors-expected.txt b/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-errors-expected.txt
index 630c637e..a5a19af 100644
--- a/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-errors-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-errors-expected.txt
@@ -10,7 +10,7 @@
 onerror
 PASS count is 0
 PASS event.error is "not-allowed"
-PASS event.message is "not allowed"
+PASS event.message is ""
 PASS event.type is "error"
 onend
 PASS count is 1
diff --git a/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-errors.html b/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-errors.html
index 95d731fa..0965be02d 100644
--- a/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-errors.html
+++ b/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-errors.html
@@ -2,6 +2,9 @@
 <html>
 <head>
 <script src="../../../resources/js-test.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/third_party/blink/public/mojom/speech/speech_recognizer.mojom.js"></script>
+<script src="mock-speechrecognizer.js"></script>
 </head>
 <body>
 <script type="text/javascript">
@@ -33,7 +36,7 @@
     window.count = 0;
 
     r.start();
-    testRunner.setMockSpeechRecognitionError("NotAllowedError", "not allowed");
+    mockSpeechRecognizer.setMockSpeechRecognitionError(blink.mojom.SpeechRecognitionErrorCode.kNotAllowed);
 
     // Check that we get an error event.
     r.onerror = function() {
@@ -41,7 +44,7 @@
         shouldBe('count', '0');
         count++;
         shouldBeEqualToString('event.error', 'not-allowed');
-        shouldBeEqualToString('event.message', 'not allowed');
+        shouldBeEqualToString('event.message', '');
         shouldBeEqualToString('event.type', 'error');
     }
 
@@ -58,4 +61,3 @@
 </script>
 </body>
 </html>
-
diff --git a/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-re-restart.html b/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-re-restart.html
index c38f5cd8..dea53ca 100644
--- a/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-re-restart.html
+++ b/third_party/WebKit/LayoutTests/fast/speech/scripted/speechrecognition-re-restart.html
@@ -2,6 +2,9 @@
 <html>
 <head>
 <script src="../../../resources/js-test.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/third_party/blink/public/mojom/speech/speech_recognizer.mojom.js"></script>
+<script src="mock-speechrecognizer.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/fast/speech/scripted/start-exception-expected.txt b/third_party/WebKit/LayoutTests/fast/speech/scripted/start-exception-expected.txt
deleted file mode 100644
index 1934262..0000000
--- a/third_party/WebKit/LayoutTests/fast/speech/scripted/start-exception-expected.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-Test getting an exception when calling start() in the Speech JavaScript API
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS 'webkitSpeechRecognition' in self is true
-PASS webkitSpeechRecognition == null is false
-
-doubleStart():
-window.r = new webkitSpeechRecognition()
-PASS r.start() did not throw exception.
-PASS r.start() threw exception InvalidStateError: Failed to execute 'start' on 'SpeechRecognition': recognition has already started..
-onstart
-PASS r.start() threw exception InvalidStateError: Failed to execute 'start' on 'SpeechRecognition': recognition has already started..
-onaudiostart
-PASS r.start() threw exception InvalidStateError: Failed to execute 'start' on 'SpeechRecognition': recognition has already started..
-onsoundstart
-PASS r.start() threw exception InvalidStateError: Failed to execute 'start' on 'SpeechRecognition': recognition has already started..
-onspeechstart
-PASS r.start() threw exception InvalidStateError: Failed to execute 'start' on 'SpeechRecognition': recognition has already started..
-onnomatch
-PASS r.start() threw exception InvalidStateError: Failed to execute 'start' on 'SpeechRecognition': recognition has already started..
-onspeechend
-PASS r.start() threw exception InvalidStateError: Failed to execute 'start' on 'SpeechRecognition': recognition has already started..
-onsoundend
-PASS r.start() threw exception InvalidStateError: Failed to execute 'start' on 'SpeechRecognition': recognition has already started..
-onaudioend
-PASS r.start() threw exception InvalidStateError: Failed to execute 'start' on 'SpeechRecognition': recognition has already started..
-onend
-PASS r.start() did not throw exception.
-r.abort()
-onend
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/speech/scripted/start-exception.html b/third_party/WebKit/LayoutTests/fast/speech/scripted/start-exception.html
index c21ff43..e40a475 100644
--- a/third_party/WebKit/LayoutTests/fast/speech/scripted/start-exception.html
+++ b/third_party/WebKit/LayoutTests/fast/speech/scripted/start-exception.html
@@ -1,52 +1,35 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../../resources/js-test.js"></script>
-</head>
-<body>
-<script type="text/javascript">
-description('Test getting an exception when calling start() in the Speech JavaScript API');
+<!doctype html>
+<title>Test getting an exception when calling start() in the Speech JavaScript API</title>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/third_party/blink/public/mojom/speech/speech_recognizer.mojom.js"></script>
+<script src="mock-speechrecognizer.js"></script>
+<script>
 
-function run() {
-    // Check availability of constructors.
-    shouldBeTrue("'webkitSpeechRecognition' in self");
-    shouldBeFalse("webkitSpeechRecognition == null");
+test(() => {
+  assert_true('webkitSpeechRecognition' in self);
+  assert_false(webkitSpeechRecognition == null);
+}, "Check availability of constructors");
 
-    doubleStart();
-}
-
-function doubleStart() {
-    debug('\ndoubleStart():');
-    evalAndLog("window.r = new webkitSpeechRecognition()");
-
-    // Set default handlers.
-    for (var prop in r) {
-        if (prop.match('^on')) {
-            r[prop] = function() {
-                debug('on' + event.type);
-
-                if (event.type === 'end') {
-                    shouldNotThrow("r.start()");
-                    evalAndLog("r.abort()");
-
-                    r.onend = function() {
-                        debug('onend');
-                        finishJSTest();
-                    }
-                } else {
-                    shouldThrow("r.start()", '"InvalidStateError: Failed to execute \'start\' on \'SpeechRecognition\': recognition has already started."');
-                }
-            }
+async_test(t => {
+  var r = new webkitSpeechRecognition();
+  // Set default handlers.
+  for (var prop in r) {
+    if (prop.match('^on')) {
+      r[prop] = () => {
+        if (event.type === 'end') {
+          r.start();
+          r.abort();
+          r.onend = () => t.done();
+        } else {
+          assert_throws('InvalidStateError', () => r.start());
         }
+      }
     }
+  }
+  r.start();
+  assert_throws('InvalidStateError', () => r.start());
+}, "Double start");
 
-    shouldNotThrow("r.start()");
-    shouldThrow("r.start()", '"InvalidStateError: Failed to execute \'start\' on \'SpeechRecognition\': recognition has already started."');
-}
-
-window.onload = run;
-window.jsTestIsAsync = true;
 </script>
-</body>
-</html>
-
diff --git a/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-console-log.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-console-log.html
index 73e8203..b22e308 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-console-log.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-console-log.html
@@ -41,7 +41,6 @@
         console.timeEnd("time");
         console.assert(true);
         console.assert(false);
-        console.markTimeline("markTimeline");
         */
         self.addEventListener("connect", function (e) {
             var port = e.ports[0];
diff --git a/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-console-log-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-console-log-expected.txt
index b908b3e..a793c4ad 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-console-log-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-console-log-expected.txt
@@ -7,7 +7,6 @@
 CONSOLE DEBUG: line 8: debug
 CONSOLE DEBUG: line 9: count: 1
 CONSOLE ERROR: line 16: console.assert
-CONSOLE WARNING: line 17: 'console.markTimeline' is deprecated. Please use 'console.timeStamp' instead.
 This tests that 'console.log' and friends function correctly from workers.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-console-log.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-console-log.html
index 146b6c7e9..b2d0fc8 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-console-log.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-console-log.html
@@ -38,7 +38,6 @@
         */
         console.assert(true);
         console.assert(false);
-        console.markTimeline("markTimeline");
         this.postMessage({ done: true });
     </script>
     <script>
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.png
index c28f5e93..473e177 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.txt
index 8bc8834d..97d105a 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.txt
@@ -1,8 +1,8 @@
-layer at (0,0) size 800x600 scrollHeight 653
+layer at (0,0) size 800x600 scrollHeight 675
   LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x653 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
-  LayoutNGBlockFlow {HTML} at (0,0) size 800x652.88
-    LayoutNGBlockFlow {BODY} at (8,8) size 784x636.88
+layer at (0,0) size 800x675 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x675.31
+    LayoutNGBlockFlow {BODY} at (8,21.44) size 784x645.88
       LayoutNGBlockFlow {H1} at (0,0) size 784x37
         LayoutText {#text} at (0,0) size 418x36
           text run at (0,0) width 418: "Form Element Geometry Tests"
@@ -12,32 +12,32 @@
       LayoutNGBlockFlow {H2} at (0,98.34) size 784x27
         LayoutText {#text} at (0,0) size 165x26
           text run at (0,0) width 165: "Bounding Boxes"
-      LayoutTable {TABLE} at (0,145.25) size 166x32
-        LayoutTableSection {TBODY} at (0,0) size 166x32
-          LayoutTableRow {TR} at (0,2) size 166x28
-            LayoutNGTableCell {TD} at (2,2) size 58x28 [r=0 c=0 rs=1 cs=1]
-              LayoutNGBlockFlow {DIV} at (1,1) size 56x26 [border: (2px solid #0000FF)]
+      LayoutTable {TABLE} at (0,145.25) size 166x38
+        LayoutTableSection {TBODY} at (0,0) size 166x38
+          LayoutTableRow {TR} at (0,2) size 166x34
+            LayoutNGTableCell {TD} at (2,2) size 58x34 [r=0 c=0 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 56x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 52x22
-                  LayoutButton {INPUT} at (2,2) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+                  LayoutButton {INPUT} at (2,7) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
                     LayoutBlockFlow (anonymous) at (8,3) size 36x16
                       LayoutText {#text} at (0,0) size 36x16
                         text run at (0,0) width 36: "button"
-            LayoutNGTableCell {TD} at (62,3) size 60x26 [r=0 c=1 rs=1 cs=1]
-              LayoutNGBlockFlow {DIV} at (1,1) size 58x24 [border: (2px solid #0000FF)]
+            LayoutNGTableCell {TD} at (62,2) size 60x34 [r=0 c=1 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 58x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 54x20
-                  LayoutMenuList {SELECT} at (2,2) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+                  LayoutMenuList {SELECT} at (2,8) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
                     LayoutBlockFlow (anonymous) at (1,1) size 52x18
                       LayoutText (anonymous) at (4,1) size 32x16
                         text run at (4,1) width 32: "menu"
-            LayoutNGTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1]
-              LayoutNGBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+            LayoutNGTableCell {TD} at (124,2) size 19x34 [r=0 c=2 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 17x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 13x13
-                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
-            LayoutNGTableCell {TD} at (145,6) size 19x19 [r=0 c=3 rs=1 cs=1]
-              LayoutNGBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+                  LayoutBlockFlow {INPUT} at (2,10) size 13x13
+            LayoutNGTableCell {TD} at (145,2) size 19x34 [r=0 c=3 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 17x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 13x13
-                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
-      LayoutTable {TABLE} at (0,177.25) size 166x32
+                  LayoutBlockFlow {INPUT} at (2,10) size 13x13
+      LayoutTable {TABLE} at (0,183.25) size 166x32
         LayoutTableSection {TBODY} at (0,0) size 166x32
           LayoutTableRow {TR} at (0,2) size 166x28
             LayoutNGTableCell {TD} at (2,2) size 58x28 [r=0 c=0 rs=1 cs=1]
@@ -52,13 +52,13 @@
                   LayoutBlockFlow (anonymous) at (1,1) size 52x18
                     LayoutText (anonymous) at (4,1) size 32x16
                       text run at (4,1) width 32: "menu"
-            LayoutNGTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1]
-              LayoutNGBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
-                LayoutBlockFlow {INPUT} at (2,2) size 13x13
-            LayoutNGTableCell {TD} at (145,6) size 19x19 [r=0 c=3 rs=1 cs=1]
-              LayoutNGBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
-                LayoutBlockFlow {INPUT} at (2,2) size 13x13
-      LayoutTable {TABLE} at (0,209.25) size 166x32
+            LayoutNGTableCell {TD} at (124,3) size 19x26 [r=0 c=2 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 17x24 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,4) size 13x13
+            LayoutNGTableCell {TD} at (145,3) size 19x26 [r=0 c=3 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 17x24 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,4) size 13x13
+      LayoutTable {TABLE} at (0,215.25) size 166x32
         LayoutTableSection {TBODY} at (0,0) size 166x32
           LayoutTableRow {TR} at (0,2) size 166x28
             LayoutNGTableCell {TD} at (2,2) size 58x28 [r=0 c=0 rs=1 cs=1]
@@ -75,22 +75,22 @@
                     LayoutBlockFlow (anonymous) at (1,1) size 52x18
                       LayoutText (anonymous) at (4,1) size 32x16
                         text run at (4,1) width 32: "menu"
-            LayoutNGTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1]
-              LayoutNGBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+            LayoutNGTableCell {TD} at (124,3) size 19x26 [r=0 c=2 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 17x24 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 13x13
-                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
-            LayoutNGTableCell {TD} at (145,6) size 19x19 [r=0 c=3 rs=1 cs=1]
-              LayoutNGBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+                  LayoutBlockFlow {INPUT} at (2,4) size 13x13
+            LayoutNGTableCell {TD} at (145,3) size 19x26 [r=0 c=3 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 17x24 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 13x13
-                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
-      LayoutTable {TABLE} at (0,241.25) size 590x80
-        LayoutTableSection {TBODY} at (0,0) size 590x80
-          LayoutTableRow {TR} at (0,2) size 590x76
+                  LayoutBlockFlow {INPUT} at (2,4) size 13x13
+      LayoutTable {TABLE} at (0,247.25) size 592x81
+        LayoutTableSection {TBODY} at (0,0) size 592x81
+          LayoutTableRow {TR} at (0,2) size 592x77
             LayoutNGTableCell {TD} at (2,2) size 107x28 [r=0 c=0 rs=1 cs=1]
               LayoutNGBlockFlow {DIV} at (1,1) size 105x26 [border: (2px solid #0000FF)]
                 LayoutTextControl {INPUT} at (2,2) size 101x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-            LayoutNGTableCell {TD} at (111,2) size 44x76 [r=0 c=1 rs=1 cs=1]
-              LayoutNGBlockFlow {DIV} at (1,1) size 42x74 [border: (2px solid #0000FF)]
+            LayoutNGTableCell {TD} at (111,2) size 44x77 [r=0 c=1 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 42x75 [border: (2px solid #0000FF)]
             LayoutNGTableCell {TD} at (157,2) size 244x28 [r=0 c=2 rs=1 cs=1]
               LayoutNGBlockFlow {DIV} at (1,1) size 242x26 [border: (2px solid #0000FF)]
                 LayoutFileUploadControl {INPUT} at (2,2) size 238x22 "No file chosen"
@@ -98,12 +98,12 @@
                     LayoutBlockFlow (anonymous) at (8,3) size 69x16
                       LayoutText {#text} at (0,0) size 69x16
                         text run at (0,0) width 69: "Choose File"
-            LayoutNGTableCell {TD} at (403,2) size 185x42 [r=0 c=3 rs=1 cs=1]
-              LayoutNGBlockFlow {DIV} at (1,1) size 183x40 [border: (2px solid #0000FF)]
-      LayoutNGBlockFlow {H2} at (0,341.16) size 784x27
+            LayoutNGTableCell {TD} at (403,2) size 187x49 [r=0 c=3 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 185x47 [border: (2px solid #0000FF)]
+      LayoutNGBlockFlow {H2} at (0,348.16) size 784x27
         LayoutText {#text} at (0,0) size 199x26
           text run at (0,0) width 199: "Baseline Alignment"
-      LayoutNGBlockFlow {DIV} at (0,388.06) size 784x28
+      LayoutNGBlockFlow {DIV} at (0,395.06) size 784x28
         LayoutInline {FONT} at (0,0) size 212x27
           LayoutText {#text} at (0,0) size 43x27
             text run at (0,0) width 43: "text "
@@ -124,7 +124,7 @@
             text run at (182,0) width 6: " "
           LayoutBlockFlow {INPUT} at (192,8) size 13x13
           LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow {DIV} at (0,416.06) size 784x22
+      LayoutNGBlockFlow {DIV} at (0,423.06) size 784x22
         LayoutText {#text} at (0,1) size 27x19
           text run at (0,1) width 27: "text "
         LayoutButton {INPUT} at (27,0) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
@@ -144,7 +144,7 @@
           text run at (162,1) width 4: " "
         LayoutBlockFlow {INPUT} at (170,3) size 13x13
         LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow {DIV} at (0,438.06) size 784x22
+      LayoutNGBlockFlow {DIV} at (0,445.06) size 784x22
         LayoutInline {FONT} at (0,0) size 178x12
           LayoutText {#text} at (0,6) size 18x12
             text run at (0,6) width 18: "text "
@@ -165,24 +165,24 @@
             text run at (151,6) width 3: " "
           LayoutBlockFlow {INPUT} at (158,3) size 13x13
           LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow {DIV} at (0,460.06) size 784x42
-        LayoutText {#text} at (0,21) size 27x19
-          text run at (0,21) width 27: "text "
-        LayoutTextControl {INPUT} at (27,20) size 101x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-        LayoutText {#text} at (128,21) size 4x19
-          text run at (128,21) width 4: " "
-        LayoutFileUploadControl {INPUT} at (132,20) size 238x22 "No file chosen"
+      LayoutNGBlockFlow {DIV} at (0,467.06) size 784x44
+        LayoutText {#text} at (0,23) size 27x19
+          text run at (0,23) width 27: "text "
+        LayoutTextControl {INPUT} at (27,22) size 101x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutText {#text} at (128,23) size 4x19
+          text run at (128,23) width 4: " "
+        LayoutFileUploadControl {INPUT} at (132,22) size 238x22 "No file chosen"
           LayoutButton {INPUT} at (0,0) size 85x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
             LayoutBlockFlow (anonymous) at (8,3) size 69x16
               LayoutText {#text} at (0,0) size 69x16
                 text run at (0,0) width 69: "Choose File"
-        LayoutText {#text} at (370,21) size 4x19
-          text run at (370,21) width 4: " "
+        LayoutText {#text} at (370,23) size 4x19
+          text run at (370,23) width 4: " "
         LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow {H2} at (0,521.97) size 784x27
+      LayoutNGBlockFlow {H2} at (0,530.97) size 784x27
         LayoutText {#text} at (0,0) size 197x26
           text run at (0,0) width 197: "Pop-up Menu Sizes"
-      LayoutNGBlockFlow {DIV} at (0,568.88) size 784x28
+      LayoutNGBlockFlow {DIV} at (0,577.88) size 784x28
         LayoutInline {FONT} at (0,0) size 137x27
           LayoutText {#text} at (0,0) size 0x0
           LayoutMenuList {SELECT} at (0,6) size 22x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
@@ -202,7 +202,7 @@
               LayoutText (anonymous) at (4,1) size 56x16
                 text run at (4,1) width 56: "xxxxxxxx"
           LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow {DIV} at (0,596.88) size 784x20
+      LayoutNGBlockFlow {DIV} at (0,605.88) size 784x20
         LayoutMenuList {SELECT} at (0,0) size 22x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
           LayoutBlockFlow (anonymous) at (1,1) size 20x18
             LayoutText (anonymous) at (4,1) size 4x16
@@ -220,7 +220,7 @@
             LayoutText (anonymous) at (4,1) size 56x16
               text run at (4,1) width 56: "xxxxxxxx"
         LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow {DIV} at (0,616.88) size 784x20
+      LayoutNGBlockFlow {DIV} at (0,625.88) size 784x20
         LayoutInline {FONT} at (0,0) size 131x20
           LayoutText {#text} at (0,0) size 0x0
           LayoutMenuList {SELECT} at (0,0) size 22x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
@@ -240,11 +240,11 @@
               LayoutText (anonymous) at (4,1) size 56x16
                 text run at (4,1) width 56: "xxxxxxxx"
           LayoutText {#text} at (0,0) size 0x0
-layer at (15,257) size 97x16
+layer at (15,277) size 97x16
   LayoutBlockFlow {DIV} at (2,3) size 97x16
     LayoutText {#text} at (0,0) size 50x16
       text run at (0,0) width 50: "text field"
-layer at (122,254) size 38x70 clip at (123,255) size 21x68 scrollHeight 85
+layer at (122,274) size 38x70 clip at (123,275) size 21x68 scrollHeight 85
   LayoutListBox {SELECT} at (2,2) size 38x70 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
     LayoutBlockFlow {OPTION} at (1,1) size 21x17
       LayoutText {#text} at (2,0) size 17x16
@@ -261,17 +261,17 @@
     LayoutBlockFlow {OPTION} at (1,69) size 21x17
       LayoutText {#text} at (2,0) size 7x16
         text run at (2,0) width 7: "5"
-layer at (414,254) size 179x36 clip at (415,255) size 177x34
-  LayoutTextControl {TEXTAREA} at (2,2) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+layer at (414,274) size 181x38 clip at (415,275) size 179x36
+  LayoutTextControl {TEXTAREA} at (2,2) size 181x38 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
     LayoutBlockFlow {DIV} at (3,3) size 175x16
       LayoutText {#text} at (0,0) size 64x16
         text run at (0,0) width 64: "textarea"
-layer at (37,491) size 97x16
+layer at (37,514) size 97x16
   LayoutBlockFlow {DIV} at (2,3) size 97x16
     LayoutText {#text} at (0,0) size 50x16
       text run at (0,0) width 50: "text field"
-layer at (382,468) size 179x36 clip at (383,469) size 177x34
-  LayoutTextControl {TEXTAREA} at (374,0) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+layer at (382,489) size 181x38 clip at (383,490) size 179x36
+  LayoutTextControl {TEXTAREA} at (374,0) size 181x38 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
     LayoutBlockFlow {DIV} at (3,3) size 175x16
       LayoutText {#text} at (0,0) size 64x16
         text run at (0,0) width 64: "textarea"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4427-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4427-expected.png
index 8c1df49..369677b 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4427-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug4427-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug5538-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug5538-expected.png
index f1e26dd..83c4c39 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug5538-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug5538-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug78162-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug78162-expected.png
index 189ace9..62907be 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug78162-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug78162-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/core/bloomberg-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/core/bloomberg-expected.png
index 579f1a1..0abc05e 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/core/bloomberg-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/core/bloomberg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug72393-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug72393-expected.png
index bc95339..a9f79188 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug72393-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla_expected_failures/bugs/bug72393-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-get-expected.txt b/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-get-expected.txt
index c5beddde..afc7089 100644
--- a/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-get-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-get-expected.txt
@@ -14,5 +14,5 @@
 HTTP_CONNECTION = keep-alive
 HTTP_HOST = localhost:8080
 HTTP_REFERER = http://127.0.0.1:8000/navigation/form-targets-cross-site-frame-get.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=nested, site=cross-site
+HTTP_SEC_METADATA = cause="forced", destination="document", target="nested", site="cross-site"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
diff --git a/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-no-referrer-expected.txt b/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-no-referrer-expected.txt
index a821bb17..dcfe1cc4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-no-referrer-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-no-referrer-expected.txt
@@ -15,5 +15,5 @@
 HTTP_CONNECTION = keep-alive
 HTTP_HOST = localhost:8080
 HTTP_ORIGIN = null
-HTTP_SEC_METADATA = cause=forced, destination=document, target=nested, site=cross-site
+HTTP_SEC_METADATA = cause="forced", destination="document", target="nested", site="cross-site"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
diff --git a/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-post-expected.txt b/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-post-expected.txt
index df4aa48..e8c68ff4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-post-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-post-expected.txt
@@ -16,5 +16,5 @@
 HTTP_HOST = localhost:8080
 HTTP_ORIGIN = http://127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/navigation/form-targets-cross-site-frame-post.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=nested, site=cross-site
+HTTP_SEC_METADATA = cause="forced", destination="document", target="nested", site="cross-site"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
diff --git a/third_party/WebKit/LayoutTests/http/tests/navigation/form-with-enctype-targets-cross-site-frame-expected.txt b/third_party/WebKit/LayoutTests/http/tests/navigation/form-with-enctype-targets-cross-site-frame-expected.txt
index 3fb71a7..cc9c484 100644
--- a/third_party/WebKit/LayoutTests/http/tests/navigation/form-with-enctype-targets-cross-site-frame-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/navigation/form-with-enctype-targets-cross-site-frame-expected.txt
@@ -16,5 +16,5 @@
 HTTP_HOST = localhost:8080
 HTTP_ORIGIN = http://127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/navigation/form-with-enctype-targets-cross-site-frame.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=nested, site=cross-site
+HTTP_SEC_METADATA = cause="forced", destination="document", target="nested", site="cross-site"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
diff --git a/third_party/WebKit/LayoutTests/http/tests/navigation/post-basic-expected.txt b/third_party/WebKit/LayoutTests/http/tests/navigation/post-basic-expected.txt
index 9511d8a..0af6987 100644
--- a/third_party/WebKit/LayoutTests/http/tests/navigation/post-basic-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/navigation/post-basic-expected.txt
@@ -11,7 +11,7 @@
 HTTP_HOST = 127.0.0.1:8000
 HTTP_ORIGIN = http://127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/navigation/resources/page-that-posts.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=top-level, site=same-origin
+HTTP_SEC_METADATA = cause="forced", destination="document", target="top-level", site="same-origin"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
 
 ============== Back Forward List ==============
diff --git a/third_party/WebKit/LayoutTests/http/tests/navigation/post-frames-expected.txt b/third_party/WebKit/LayoutTests/http/tests/navigation/post-frames-expected.txt
index 023de1bf..85141c7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/navigation/post-frames-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/navigation/post-frames-expected.txt
@@ -18,7 +18,7 @@
 HTTP_HOST = 127.0.0.1:8000
 HTTP_ORIGIN = http://127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/navigation/resources/page-that-posts.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=nested, site=same-origin
+HTTP_SEC_METADATA = cause="forced", destination="document", target="nested", site="same-origin"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
 
 ============== Back Forward List ==============
diff --git a/third_party/WebKit/LayoutTests/http/tests/navigation/post-frames-goback1-expected.txt b/third_party/WebKit/LayoutTests/http/tests/navigation/post-frames-goback1-expected.txt
index 70f8bfb0..2d6eac7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/navigation/post-frames-goback1-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/navigation/post-frames-goback1-expected.txt
@@ -18,7 +18,7 @@
 HTTP_HOST = 127.0.0.1:8000
 HTTP_ORIGIN = http://127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/navigation/post-frames-goback1.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=nested, site=same-origin
+HTTP_SEC_METADATA = cause="forced", destination="document", target="nested", site="same-origin"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
 
 ============== Back Forward List ==============
diff --git a/third_party/WebKit/LayoutTests/http/tests/navigation/post-goback1-expected.txt b/third_party/WebKit/LayoutTests/http/tests/navigation/post-goback1-expected.txt
index 63f09f6..b347ee0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/navigation/post-goback1-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/navigation/post-goback1-expected.txt
@@ -11,7 +11,7 @@
 HTTP_HOST = 127.0.0.1:8000
 HTTP_ORIGIN = http://127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/navigation/resources/page-that-posts.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=top-level, site=same-origin
+HTTP_SEC_METADATA = cause="forced", destination="document", target="top-level", site="same-origin"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
 
 ============== Back Forward List ==============
diff --git a/third_party/WebKit/LayoutTests/http/tests/navigation/rename-subframe-goback-expected.txt b/third_party/WebKit/LayoutTests/http/tests/navigation/rename-subframe-goback-expected.txt
index ec0492e..daf9c93 100644
--- a/third_party/WebKit/LayoutTests/http/tests/navigation/rename-subframe-goback-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/navigation/rename-subframe-goback-expected.txt
@@ -19,5 +19,5 @@
 HTTP_HOST = 127.0.0.1:8000
 HTTP_ORIGIN = http://127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/navigation/resources/page-that-posts.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=nested, site=same-origin
+HTTP_SEC_METADATA = cause="forced", destination="document", target="nested", site="same-origin"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-leak-path-on-redirect-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-leak-path-on-redirect-expected.txt
index 7cb69b6..cd2a06b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-leak-path-on-redirect-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-leak-path-on-redirect-expected.txt
@@ -8,7 +8,7 @@
 HTTP_CONNECTION = keep-alive
 HTTP_HOST = 127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/security/contentSecurityPolicy/1.1/form-action-leak-path-on-redirect.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=top-level, site=same-origin
+HTTP_SEC_METADATA = cause="forced", destination="document", target="top-level", site="same-origin"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
 
 ============== Back Forward List ==============
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-allowed-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-allowed-expected.txt
index a51c667..d12c6fc 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-allowed-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-allowed-expected.txt
@@ -10,7 +10,7 @@
 HTTP_HOST = 127.0.0.1:8000
 HTTP_ORIGIN = http://127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/security/contentSecurityPolicy/1.1/form-action-src-allowed.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=top-level, site=same-origin
+HTTP_SEC_METADATA = cause="forced", destination="document", target="top-level", site="same-origin"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
 
 ============== Back Forward List ==============
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-allowed-with-redirect-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-allowed-with-redirect-expected.txt
index 3198df4f..371e67d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-allowed-with-redirect-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-allowed-with-redirect-expected.txt
@@ -8,7 +8,7 @@
 HTTP_CONNECTION = keep-alive
 HTTP_HOST = 127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/security/contentSecurityPolicy/1.1/form-action-src-allowed-with-redirect.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=top-level, site=same-origin
+HTTP_SEC_METADATA = cause="forced", destination="document", target="top-level", site="same-origin"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
 
 ============== Back Forward List ==============
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-default-ignored-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-default-ignored-expected.txt
index b81713e..29839e6 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-default-ignored-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-default-ignored-expected.txt
@@ -10,7 +10,7 @@
 HTTP_HOST = 127.0.0.1:8000
 HTTP_ORIGIN = http://127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/security/contentSecurityPolicy/1.1/form-action-src-default-ignored.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=top-level, site=same-origin
+HTTP_SEC_METADATA = cause="forced", destination="document", target="top-level", site="same-origin"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
 
 ============== Back Forward List ==============
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-default-ignored-with-redirect-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-default-ignored-with-redirect-expected.txt
index 7c30054..fdaf488 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-default-ignored-with-redirect-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-default-ignored-with-redirect-expected.txt
@@ -8,7 +8,7 @@
 HTTP_CONNECTION = keep-alive
 HTTP_HOST = 127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/security/contentSecurityPolicy/1.1/form-action-src-default-ignored-with-redirect.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=top-level, site=same-origin
+HTTP_SEC_METADATA = cause="forced", destination="document", target="top-level", site="same-origin"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
 
 ============== Back Forward List ==============
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-get-allowed-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-get-allowed-expected.txt
index 8a68e97..67c894a4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-get-allowed-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-get-allowed-expected.txt
@@ -8,7 +8,7 @@
 HTTP_CONNECTION = keep-alive
 HTTP_HOST = 127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/security/contentSecurityPolicy/1.1/form-action-src-get-allowed.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=top-level, site=same-origin
+HTTP_SEC_METADATA = cause="forced", destination="document", target="top-level", site="same-origin"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
 
 ============== Back Forward List ==============
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-get-allowed-with-redirect-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-get-allowed-with-redirect-expected.txt
index bae03c9..3e5bc89a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-get-allowed-with-redirect-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/form-action-src-get-allowed-with-redirect-expected.txt
@@ -8,7 +8,7 @@
 HTTP_CONNECTION = keep-alive
 HTTP_HOST = 127.0.0.1:8000
 HTTP_REFERER = http://127.0.0.1:8000/security/contentSecurityPolicy/1.1/form-action-src-get-allowed-with-redirect.html
-HTTP_SEC_METADATA = cause=forced, destination=document, target=top-level, site=same-origin
+HTTP_SEC_METADATA = cause="forced", destination="document", target="top-level", site="same-origin"
 HTTP_UPGRADE_INSECURE_REQUESTS = 1
 
 ============== Back Forward List ==============
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-handler-allowed.html b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-handler-allowed.html
index c740defd..800907a4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-handler-allowed.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scripthash-handler-allowed.html
@@ -24,7 +24,7 @@
             }, 'Inline event handlers not whitelisted by the policy should generate error events.');
         </script>
 
-        <meta http-equiv="Content-Security-Policy" content="script-src 'sha256-nhtYaXCssBJTThiDLYewspQYue9tisulEwJ3nTJKcMI=' 'unsafe-hashed-attributes'">
+        <meta http-equiv="Content-Security-Policy" content="script-src 'sha256-nhtYaXCssBJTThiDLYewspQYue9tisulEwJ3nTJKcMI=' 'unsafe-hashes'">
     </head>
     <body>
         <button id="pass" onclick="expectSuccess(this)"></button>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/csp3-experimental/csp3_script_event_handlers_allowed.html b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/csp3-experimental/csp3_script_event_handlers_allowed.html
deleted file mode 100644
index e01e77d..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/csp3-experimental/csp3_script_event_handlers_allowed.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-
-<head>
-    <meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-hashed-attributes' 'nonce-abc' 'csp3-sha256-wmuLCpoj8EMqfQlPnt5NIMgKkCK62CxAkAiewI0zZps='; img-src *;">
-    <title>Event handlers should be allowed if a matching hash and 'unsafe-hashed-attributes' are present</title>
-    <script src='/resources/testharness.js' nonce='abc'></script>
-    <script src='/resources/testharnessreport.js' nonce='abc'></script>
-</head>
-
-<body>
-    <div id='log'></div>
-    <script nonce='abc'>
-        var t1 = async_test("Test that the inline event handler is allowed to run");
-        
-        window.addEventListener('securitypolicyviolation', t1.unreached_func("Should have not raised any event"));
-    </script>
-    <img src='../resources/pass.png'
-         onload='t1.done();'>
-</body>
-
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/usecounter.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/usecounter.html
index 92be7d4..9d45611 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/usecounter.html
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/usecounter.html
@@ -6,7 +6,7 @@
 <script>
 
 const kFeature = 675;  // From UseCounter.h
-const kDeprecatedFeature = 538;  // From Deprecation.h
+const kDeprecatedFeature = 166;  // From Deprecation.h
 
 function isUseCounted(win, feature) {
   return win.internals.isUseCounted(win.document, feature);
diff --git a/third_party/WebKit/LayoutTests/http/tests/workers/shared-worker-usecounter.html b/third_party/WebKit/LayoutTests/http/tests/workers/shared-worker-usecounter.html
index 51cf03c2..9586872 100644
--- a/third_party/WebKit/LayoutTests/http/tests/workers/shared-worker-usecounter.html
+++ b/third_party/WebKit/LayoutTests/http/tests/workers/shared-worker-usecounter.html
@@ -7,7 +7,7 @@
 <script>
 
 const kFeature = 675;  // From UseCounter.h
-const kDeprecatedFeature = 538;  // From Deprecation.h
+const kDeprecatedFeature = 166;  // From Deprecation.h
 
 function isUseCounted(win, feature) {
   return win.internals.isUseCounted(win.document, feature);
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/form-element-geometry-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/form-element-geometry-expected.png
index d0bdc5e8..bad4571 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/form-element-geometry-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/form-element-geometry-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/form-element-geometry-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/form-element-geometry-expected.txt
index 0aba684..83075c5 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/form-element-geometry-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/form-element-geometry-expected.txt
@@ -1,8 +1,8 @@
-layer at (0,0) size 800x600 scrollHeight 653
+layer at (0,0) size 800x600 scrollHeight 675
   LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x653 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x652.88
-    LayoutBlockFlow {BODY} at (8,8) size 784x636.88
+layer at (0,0) size 800x675 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x675.31
+    LayoutBlockFlow {BODY} at (8,21.44) size 784x645.88
       LayoutBlockFlow {H1} at (0,0) size 784x37
         LayoutText {#text} at (0,0) size 419x36
           text run at (0,0) width 419: "Form Element Geometry Tests"
@@ -12,32 +12,32 @@
       LayoutBlockFlow {H2} at (0,98.34) size 784x27
         LayoutText {#text} at (0,0) size 165x26
           text run at (0,0) width 165: "Bounding Boxes"
-      LayoutTable {TABLE} at (0,145.25) size 166x32
-        LayoutTableSection {TBODY} at (0,0) size 166x32
-          LayoutTableRow {TR} at (0,2) size 166x28
-            LayoutTableCell {TD} at (2,2) size 58x28 [r=0 c=0 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 56x26 [border: (2px solid #0000FF)]
+      LayoutTable {TABLE} at (0,145.25) size 166x38
+        LayoutTableSection {TBODY} at (0,0) size 166x38
+          LayoutTableRow {TR} at (0,2) size 166x34
+            LayoutTableCell {TD} at (2,2) size 58x34 [r=0 c=0 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 56x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 52x27
-                  LayoutButton {INPUT} at (2,2) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+                  LayoutButton {INPUT} at (2,7) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
                     LayoutBlockFlow (anonymous) at (8,3) size 36x16
                       LayoutText {#text} at (0,0) size 36x16
                         text run at (0,0) width 36: "button"
-            LayoutTableCell {TD} at (62,3) size 60x26 [r=0 c=1 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 58x24 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (62,2) size 60x34 [r=0 c=1 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 58x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 54x27
-                  LayoutMenuList {SELECT} at (2,2) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+                  LayoutMenuList {SELECT} at (2,8) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
                     LayoutBlockFlow (anonymous) at (1,1) size 52x18
                       LayoutText (anonymous) at (4,1) size 32x16
                         text run at (4,1) width 32: "menu"
-            LayoutTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (124,2) size 19x34 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 17x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 13x27
-                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
-            LayoutTableCell {TD} at (145,6) size 19x19 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+                  LayoutBlockFlow {INPUT} at (2,10) size 13x13
+            LayoutTableCell {TD} at (145,2) size 19x34 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 17x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 13x27
-                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
-      LayoutTable {TABLE} at (0,177.25) size 166x32
+                  LayoutBlockFlow {INPUT} at (2,10) size 13x13
+      LayoutTable {TABLE} at (0,183.25) size 166x32
         LayoutTableSection {TBODY} at (0,0) size 166x32
           LayoutTableRow {TR} at (0,2) size 166x28
             LayoutTableCell {TD} at (2,2) size 58x28 [r=0 c=0 rs=1 cs=1]
@@ -52,13 +52,13 @@
                   LayoutBlockFlow (anonymous) at (1,1) size 52x18
                     LayoutText (anonymous) at (4,1) size 32x16
                       text run at (4,1) width 32: "menu"
-            LayoutTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
-                LayoutBlockFlow {INPUT} at (2,2) size 13x13
-            LayoutTableCell {TD} at (145,6) size 19x19 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
-                LayoutBlockFlow {INPUT} at (2,2) size 13x13
-      LayoutTable {TABLE} at (0,209.25) size 166x32
+            LayoutTableCell {TD} at (124,3) size 19x26 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 17x24 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,4) size 13x13
+            LayoutTableCell {TD} at (145,3) size 19x26 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 17x24 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,4) size 13x13
+      LayoutTable {TABLE} at (0,215.25) size 166x32
         LayoutTableSection {TBODY} at (0,0) size 166x32
           LayoutTableRow {TR} at (0,2) size 166x28
             LayoutTableCell {TD} at (2,2) size 58x28 [r=0 c=0 rs=1 cs=1]
@@ -75,22 +75,22 @@
                     LayoutBlockFlow (anonymous) at (1,1) size 52x18
                       LayoutText (anonymous) at (4,1) size 32x16
                         text run at (4,1) width 32: "menu"
-            LayoutTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (124,3) size 19x26 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 17x24 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 13x12
-                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
-            LayoutTableCell {TD} at (145,6) size 19x19 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+                  LayoutBlockFlow {INPUT} at (2,4) size 13x13
+            LayoutTableCell {TD} at (145,3) size 19x26 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 17x24 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 13x12
-                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
-      LayoutTable {TABLE} at (0,241.25) size 590x80
-        LayoutTableSection {TBODY} at (0,0) size 590x80
-          LayoutTableRow {TR} at (0,2) size 590x76
+                  LayoutBlockFlow {INPUT} at (2,4) size 13x13
+      LayoutTable {TABLE} at (0,247.25) size 592x81
+        LayoutTableSection {TBODY} at (0,0) size 592x81
+          LayoutTableRow {TR} at (0,2) size 592x77
             LayoutTableCell {TD} at (2,2) size 107x28 [r=0 c=0 rs=1 cs=1]
               LayoutBlockFlow {DIV} at (1,1) size 105x26 [border: (2px solid #0000FF)]
                 LayoutTextControl {INPUT} at (2,2) size 101x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-            LayoutTableCell {TD} at (111,2) size 44x76 [r=0 c=1 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 42x74 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (111,2) size 44x77 [r=0 c=1 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 42x75 [border: (2px solid #0000FF)]
             LayoutTableCell {TD} at (157,2) size 244x28 [r=0 c=2 rs=1 cs=1]
               LayoutBlockFlow {DIV} at (1,1) size 242x26 [border: (2px solid #0000FF)]
                 LayoutFileUploadControl {INPUT} at (2,2) size 238x22 "No file chosen"
@@ -98,12 +98,12 @@
                     LayoutBlockFlow (anonymous) at (8,3) size 69x16
                       LayoutText {#text} at (0,0) size 69x16
                         text run at (0,0) width 69: "Choose File"
-            LayoutTableCell {TD} at (403,2) size 185x42 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 183x40 [border: (2px solid #0000FF)]
-      LayoutBlockFlow {H2} at (0,341.16) size 784x27
+            LayoutTableCell {TD} at (403,2) size 187x49 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 185x47 [border: (2px solid #0000FF)]
+      LayoutBlockFlow {H2} at (0,348.16) size 784x27
         LayoutText {#text} at (0,0) size 200x26
           text run at (0,0) width 200: "Baseline Alignment"
-      LayoutBlockFlow {DIV} at (0,388.06) size 784x28
+      LayoutBlockFlow {DIV} at (0,395.06) size 784x28
         LayoutInline {FONT} at (0,0) size 208x27
           LayoutText {#text} at (0,0) size 43x27
             text run at (0,0) width 43: "text "
@@ -124,7 +124,7 @@
             text run at (182,0) width 6: " "
           LayoutBlockFlow {INPUT} at (192,8) size 13x13
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,416.06) size 784x22
+      LayoutBlockFlow {DIV} at (0,423.06) size 784x22
         LayoutText {#text} at (0,1) size 27x19
           text run at (0,1) width 27: "text "
         LayoutButton {INPUT} at (27,0) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
@@ -144,7 +144,7 @@
           text run at (162,1) width 4: " "
         LayoutBlockFlow {INPUT} at (170,3) size 13x13
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,438.06) size 784x22
+      LayoutBlockFlow {DIV} at (0,445.06) size 784x22
         LayoutInline {FONT} at (0,0) size 174x12
           LayoutText {#text} at (0,6) size 18x12
             text run at (0,6) width 18: "text "
@@ -165,24 +165,24 @@
             text run at (151,6) width 3: " "
           LayoutBlockFlow {INPUT} at (158,3) size 13x13
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,460.06) size 784x42
-        LayoutText {#text} at (0,21) size 27x19
-          text run at (0,21) width 27: "text "
-        LayoutTextControl {INPUT} at (27,20) size 101x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-        LayoutText {#text} at (128,21) size 4x19
-          text run at (128,21) width 4: " "
-        LayoutFileUploadControl {INPUT} at (132,20) size 238x22 "No file chosen"
+      LayoutBlockFlow {DIV} at (0,467.06) size 784x44
+        LayoutText {#text} at (0,23) size 27x19
+          text run at (0,23) width 27: "text "
+        LayoutTextControl {INPUT} at (27,22) size 101x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutText {#text} at (128,23) size 4x19
+          text run at (128,23) width 4: " "
+        LayoutFileUploadControl {INPUT} at (132,22) size 238x22 "No file chosen"
           LayoutButton {INPUT} at (0,0) size 85x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
             LayoutBlockFlow (anonymous) at (8,3) size 69x16
               LayoutText {#text} at (0,0) size 69x16
                 text run at (0,0) width 69: "Choose File"
-        LayoutText {#text} at (370,21) size 4x19
-          text run at (370,21) width 4: " "
+        LayoutText {#text} at (370,23) size 4x19
+          text run at (370,23) width 4: " "
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {H2} at (0,521.97) size 784x27
+      LayoutBlockFlow {H2} at (0,530.97) size 784x27
         LayoutText {#text} at (0,0) size 197x26
           text run at (0,0) width 197: "Pop-up Menu Sizes"
-      LayoutBlockFlow {DIV} at (0,568.88) size 784x28
+      LayoutBlockFlow {DIV} at (0,577.88) size 784x28
         LayoutInline {FONT} at (0,0) size 137x27
           LayoutText {#text} at (0,0) size 0x0
           LayoutMenuList {SELECT} at (0,6) size 22x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
@@ -202,7 +202,7 @@
               LayoutText (anonymous) at (4,1) size 56x16
                 text run at (4,1) width 56: "xxxxxxxx"
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,596.88) size 784x20
+      LayoutBlockFlow {DIV} at (0,605.88) size 784x20
         LayoutMenuList {SELECT} at (0,0) size 22x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
           LayoutBlockFlow (anonymous) at (1,1) size 20x18
             LayoutText (anonymous) at (4,1) size 4x16
@@ -220,7 +220,7 @@
             LayoutText (anonymous) at (4,1) size 56x16
               text run at (4,1) width 56: "xxxxxxxx"
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,616.88) size 784x20
+      LayoutBlockFlow {DIV} at (0,625.88) size 784x20
         LayoutInline {FONT} at (0,0) size 131x12
           LayoutText {#text} at (0,0) size 0x0
           LayoutMenuList {SELECT} at (0,0) size 22x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
@@ -240,11 +240,11 @@
               LayoutText (anonymous) at (4,1) size 56x16
                 text run at (4,1) width 56: "xxxxxxxx"
           LayoutText {#text} at (0,0) size 0x0
-layer at (15,257) size 97x16
+layer at (15,277) size 97x16
   LayoutBlockFlow {DIV} at (2,3) size 97x16
     LayoutText {#text} at (0,0) size 50x16
       text run at (0,0) width 50: "text field"
-layer at (122,254) size 38x70 clip at (123,255) size 21x68 scrollHeight 85
+layer at (122,274) size 38x70 clip at (123,275) size 21x68 scrollHeight 85
   LayoutListBox {SELECT} at (2,2) size 38x70 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
     LayoutBlockFlow {OPTION} at (1,1) size 21x17
       LayoutText {#text} at (2,0) size 17x16
@@ -261,17 +261,17 @@
     LayoutBlockFlow {OPTION} at (1,69) size 21x17
       LayoutText {#text} at (2,0) size 7x16
         text run at (2,0) width 7: "5"
-layer at (414,254) size 179x36 clip at (415,255) size 177x34
-  LayoutTextControl {TEXTAREA} at (2,2) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+layer at (414,274) size 181x38 clip at (415,275) size 179x36
+  LayoutTextControl {TEXTAREA} at (2,2) size 181x38 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
     LayoutBlockFlow {DIV} at (3,3) size 175x16
       LayoutText {#text} at (0,0) size 64x16
         text run at (0,0) width 64: "textarea"
-layer at (37,491) size 97x16
+layer at (37,514) size 97x16
   LayoutBlockFlow {DIV} at (2,3) size 97x16
     LayoutText {#text} at (0,0) size 50x16
       text run at (0,0) width 50: "text field"
-layer at (382,468) size 179x36 clip at (383,469) size 177x34
-  LayoutTextControl {TEXTAREA} at (374,0) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+layer at (382,489) size 181x38 clip at (383,490) size 179x36
+  LayoutTextControl {TEXTAREA} at (374,0) size 181x38 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
     LayoutBlockFlow {DIV} at (3,3) size 175x16
       LayoutText {#text} at (0,0) size 64x16
         text run at (0,0) width 64: "textarea"
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug10565-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug10565-expected.png
index 5a84d0e..66f8fbf 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug10565-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug10565-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug113424-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug113424-expected.png
index 7fa4fe7b..0e5c4509 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug113424-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug113424-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1188-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1188-expected.png
index cd49fe3..ca7ba5b1 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1188-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1188-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4427-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4427-expected.png
index a2e94c5d..3f8b6c1 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4427-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4427-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4527-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4527-expected.png
index b2de859..3b7fa8a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4527-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4527-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug5538-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug5538-expected.png
index dabda802b..0969689f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug5538-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug5538-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug78162-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug78162-expected.png
index a811a32..b0fca92 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug78162-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug78162-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug86708-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug86708-expected.png
index 320e908..eef016cd 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug86708-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug86708-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/core/bloomberg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/core/bloomberg-expected.png
index de857d0..6edf690 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/core/bloomberg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/core/bloomberg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/other/ms-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/other/ms-expected.png
index 3cacb5b..efc751f0 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/other/ms-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/other/ms-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/bugs/bug72393-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/bugs/bug72393-expected.png
index e5f0143..ec271bc22 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/bugs/bug72393-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/bugs/bug72393-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/form-element-geometry-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/form-element-geometry-expected.png
index 1b92ee4..75150d7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/form-element-geometry-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/form-element-geometry-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/form-element-geometry-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/form-element-geometry-expected.txt
index 63beff1..49abe8c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/form-element-geometry-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/form-element-geometry-expected.txt
@@ -1,8 +1,8 @@
-layer at (0,0) size 800x600 scrollHeight 617
+layer at (0,0) size 800x600 scrollHeight 643
   LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x617 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x616.88
-    LayoutBlockFlow {BODY} at (8,8) size 784x600.88
+layer at (0,0) size 800x643 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x643.31
+    LayoutBlockFlow {BODY} at (8,21.44) size 784x613.88
       LayoutBlockFlow {H1} at (0,0) size 784x37
         LayoutText {#text} at (0,0) size 420x37
           text run at (0,0) width 420: "Form Element Geometry Tests"
@@ -12,78 +12,78 @@
       LayoutBlockFlow {H2} at (0,96.34) size 784x28
         LayoutText {#text} at (0,0) size 167x28
           text run at (0,0) width 167: "Bounding Boxes"
-      LayoutTable {TABLE} at (0,144.25) size 166x28
-        LayoutTableSection {TBODY} at (0,0) size 166x28
-          LayoutTableRow {TR} at (0,2) size 166x24
-            LayoutTableCell {TD} at (2,2) size 55x24 [r=0 c=0 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 53x22 [border: (2px solid #0000FF)]
+      LayoutTable {TABLE} at (0,144.25) size 166x38
+        LayoutTableSection {TBODY} at (0,0) size 166x38
+          LayoutTableRow {TR} at (0,2) size 166x34
+            LayoutTableCell {TD} at (2,2) size 55x34 [r=0 c=0 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 53x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 49x28
-                  LayoutButton {INPUT} at (2,2) size 48.53x18 [bgcolor=#FFFFFF]
+                  LayoutButton {INPUT} at (2,11) size 48.53x18 [bgcolor=#FFFFFF]
                     LayoutBlockFlow (anonymous) at (8,2) size 32.53x13
                       LayoutText {#text} at (0,0) size 33x13
                         text run at (0,0) width 33: "button"
-            LayoutTableCell {TD} at (59,2) size 65x24 [r=0 c=1 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 63x22 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (59,2) size 65x34 [r=0 c=1 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 63x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 59x28
-                  LayoutMenuList {SELECT} at (2,2) size 59x18 [bgcolor=#F8F8F8]
+                  LayoutMenuList {SELECT} at (2,11) size 59x18 [bgcolor=#F8F8F8]
                     LayoutBlockFlow (anonymous) at (0,0) size 59x18
                       LayoutText (anonymous) at (8,2) size 28x13
                         text run at (8,2) width 28: "menu"
-            LayoutTableCell {TD} at (126,4) size 18x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x17 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (126,2) size 18x34 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 12x28
-                  LayoutBlockFlow {INPUT} at (2,2) size 12x13
-            LayoutTableCell {TD} at (146,5) size 18x18 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x16 [border: (2px solid #0000FF)]
+                  LayoutBlockFlow {INPUT} at (2,13) size 12x13
+            LayoutTableCell {TD} at (146,2) size 18x34 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 12x28
-                  LayoutBlockFlow {INPUT} at (2,2) size 12x12
-      LayoutTable {TABLE} at (0,172.25) size 166x28
-        LayoutTableSection {TBODY} at (0,0) size 166x28
-          LayoutTableRow {TR} at (0,2) size 166x24
-            LayoutTableCell {TD} at (2,2) size 55x24 [r=0 c=0 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 53x22 [border: (2px solid #0000FF)]
-                LayoutButton {INPUT} at (2,2) size 48.53x18 [bgcolor=#FFFFFF]
+                  LayoutBlockFlow {INPUT} at (2,14) size 12x12
+      LayoutTable {TABLE} at (0,182.25) size 166x29
+        LayoutTableSection {TBODY} at (0,0) size 166x29
+          LayoutTableRow {TR} at (0,2) size 166x25
+            LayoutTableCell {TD} at (2,2) size 55x25 [r=0 c=0 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 53x23 [border: (2px solid #0000FF)]
+                LayoutButton {INPUT} at (2,3) size 48.53x18 [bgcolor=#FFFFFF]
                   LayoutBlockFlow (anonymous) at (8,2) size 32.53x13
                     LayoutText {#text} at (0,0) size 33x13
                       text run at (0,0) width 33: "button"
-            LayoutTableCell {TD} at (59,2) size 65x24 [r=0 c=1 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 63x22 [border: (2px solid #0000FF)]
-                LayoutMenuList {SELECT} at (2,2) size 59x18 [bgcolor=#F8F8F8]
+            LayoutTableCell {TD} at (59,2) size 65x25 [r=0 c=1 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 63x23 [border: (2px solid #0000FF)]
+                LayoutMenuList {SELECT} at (2,3) size 59x18 [bgcolor=#F8F8F8]
                   LayoutBlockFlow (anonymous) at (0,0) size 59x18
                     LayoutText (anonymous) at (8,2) size 28x13
                       text run at (8,2) width 28: "menu"
-            LayoutTableCell {TD} at (126,4) size 18x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x17 [border: (2px solid #0000FF)]
-                LayoutBlockFlow {INPUT} at (2,2) size 12x13
-            LayoutTableCell {TD} at (146,5) size 18x18 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x16 [border: (2px solid #0000FF)]
-                LayoutBlockFlow {INPUT} at (2,2) size 12x12
-      LayoutTable {TABLE} at (0,200.25) size 166x28
-        LayoutTableSection {TBODY} at (0,0) size 166x28
-          LayoutTableRow {TR} at (0,2) size 166x24
-            LayoutTableCell {TD} at (2,2) size 55x24 [r=0 c=0 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 53x22 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (126,2) size 18x24 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x22 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,5) size 12x13
+            LayoutTableCell {TD} at (146,2) size 18x24 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x22 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,6) size 12x12
+      LayoutTable {TABLE} at (0,211.25) size 166x29
+        LayoutTableSection {TBODY} at (0,0) size 166x29
+          LayoutTableRow {TR} at (0,2) size 166x25
+            LayoutTableCell {TD} at (2,2) size 55x25 [r=0 c=0 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 53x23 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 49x13
-                  LayoutButton {INPUT} at (2,2) size 48.53x18 [bgcolor=#FFFFFF]
+                  LayoutButton {INPUT} at (2,3) size 48.53x18 [bgcolor=#FFFFFF]
                     LayoutBlockFlow (anonymous) at (8,2) size 32.53x13
                       LayoutText {#text} at (0,0) size 33x13
                         text run at (0,0) width 33: "button"
-            LayoutTableCell {TD} at (59,2) size 65x24 [r=0 c=1 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 63x22 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (59,2) size 65x25 [r=0 c=1 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 63x23 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 59x13
-                  LayoutMenuList {SELECT} at (2,2) size 59x18 [bgcolor=#F8F8F8]
+                  LayoutMenuList {SELECT} at (2,3) size 59x18 [bgcolor=#F8F8F8]
                     LayoutBlockFlow (anonymous) at (0,0) size 59x18
                       LayoutText (anonymous) at (8,2) size 28x13
                         text run at (8,2) width 28: "menu"
-            LayoutTableCell {TD} at (126,4) size 18x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x17 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (126,2) size 18x24 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x22 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 12x13
-                  LayoutBlockFlow {INPUT} at (2,2) size 12x13
-            LayoutTableCell {TD} at (146,5) size 18x18 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x16 [border: (2px solid #0000FF)]
+                  LayoutBlockFlow {INPUT} at (2,5) size 12x13
+            LayoutTableCell {TD} at (146,2) size 18x24 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x22 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 12x13
-                  LayoutBlockFlow {INPUT} at (2,2) size 12x12
-      LayoutTable {TABLE} at (0,228.25) size 490x69
+                  LayoutBlockFlow {INPUT} at (2,6) size 12x12
+      LayoutTable {TABLE} at (0,240.25) size 490x69
         LayoutTableSection {TBODY} at (0,0) size 490x69
           LayoutTableRow {TR} at (0,2) size 490x65
             LayoutTableCell {TD} at (2,2) size 77x25 [r=0 c=0 rs=1 cs=1]
@@ -91,19 +91,19 @@
                 LayoutTextControl {INPUT} at (2,2) size 71x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
             LayoutTableCell {TD} at (81,2) size 38x64.75 [r=0 c=1 rs=1 cs=1]
               LayoutBlockFlow {DIV} at (1,1) size 36x62.75 [border: (2px solid #0000FF)]
-            LayoutTableCell {TD} at (121,2) size 218x24 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 216x22 [border: (2px solid #0000FF)]
-                LayoutFileUploadControl {INPUT} at (2,2) size 212x18 "No file chosen"
+            LayoutTableCell {TD} at (121,2) size 218x25 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 216x23 [border: (2px solid #0000FF)]
+                LayoutFileUploadControl {INPUT} at (2,3) size 212x18 "No file chosen"
                   LayoutButton {INPUT} at (0,0) size 75.22x18 [bgcolor=#FFFFFF]
                     LayoutBlockFlow (anonymous) at (8,2) size 59.22x13
                       LayoutText {#text} at (0,0) size 60x13
                         text run at (0,0) width 60: "Choose File"
-            LayoutTableCell {TD} at (341,2) size 147x38 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 145x36 [border: (2px solid #0000FF)]
-      LayoutBlockFlow {H2} at (0,317.16) size 784x28
+            LayoutTableCell {TD} at (341,2) size 147x42 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 145x40 [border: (2px solid #0000FF)]
+      LayoutBlockFlow {H2} at (0,329.16) size 784x28
         LayoutText {#text} at (0,0) size 200x28
           text run at (0,0) width 200: "Baseline Alignment"
-      LayoutBlockFlow {DIV} at (0,365.06) size 784x28
+      LayoutBlockFlow {DIV} at (0,377.06) size 784x28
         LayoutInline {FONT} at (0,0) size 204x28
           LayoutText {#text} at (0,0) size 42x28
             text run at (0,0) width 42: "text "
@@ -124,7 +124,7 @@
             text run at (179,0) width 7: " "
           LayoutBlockFlow {INPUT} at (188.14,12) size 12x12
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,393.06) size 784x19
+      LayoutBlockFlow {DIV} at (0,405.06) size 784x19
         LayoutText {#text} at (0,0) size 28x18
           text run at (0,0) width 28: "text "
         LayoutButton {INPUT} at (27.98,1) size 48.53x18 [bgcolor=#FFFFFF]
@@ -144,7 +144,7 @@
           text run at (161,0) width 5: " "
         LayoutBlockFlow {INPUT} at (168.14,4) size 12x12
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,412.06) size 784x19
+      LayoutBlockFlow {DIV} at (0,424.06) size 784x19
         LayoutInline {FONT} at (0,0) size 169x13
           LayoutText {#text} at (0,4) size 18x13
             text run at (0,4) width 18: "text "
@@ -165,7 +165,7 @@
             text run at (147,4) width 4: " "
           LayoutBlockFlow {INPUT} at (153.14,4) size 12x12
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,431.06) size 784x37
+      LayoutBlockFlow {DIV} at (0,443.06) size 784x37
         LayoutText {#text} at (0,18) size 28x18
           text run at (0,18) width 28: "text "
         LayoutTextControl {INPUT} at (27.98,18) size 71x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
@@ -179,10 +179,10 @@
         LayoutText {#text} at (314,18) size 5x18
           text run at (314,18) width 5: " "
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {H2} at (0,487.97) size 784x28
+      LayoutBlockFlow {H2} at (0,499.97) size 784x28
         LayoutText {#text} at (0,0) size 198x28
           text run at (0,0) width 198: "Pop-up Menu Sizes"
-      LayoutBlockFlow {DIV} at (0,535.88) size 784x28
+      LayoutBlockFlow {DIV} at (0,547.88) size 784x28
         LayoutInline {FONT} at (0,0) size 162x28
           LayoutText {#text} at (0,0) size 0x0
           LayoutMenuList {SELECT} at (0,9) size 36x18 [bgcolor=#F8F8F8]
@@ -202,7 +202,7 @@
               LayoutText (anonymous) at (8,2) size 47x13
                 text run at (8,2) width 47: "xxxxxxxx"
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,563.88) size 784x19
+      LayoutBlockFlow {DIV} at (0,575.88) size 784x19
         LayoutMenuList {SELECT} at (0,1) size 36x18 [bgcolor=#F8F8F8]
           LayoutBlockFlow (anonymous) at (0,0) size 36x18
             LayoutText (anonymous) at (8,2) size 4x13
@@ -220,31 +220,31 @@
             LayoutText (anonymous) at (8,2) size 47x13
               text run at (8,2) width 47: "xxxxxxxx"
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,582.88) size 784x18
+      LayoutBlockFlow {DIV} at (0,594.88) size 784x19
         LayoutInline {FONT} at (0,0) size 155x13
           LayoutText {#text} at (0,0) size 0x0
-          LayoutMenuList {SELECT} at (0,0) size 36x18 [bgcolor=#F8F8F8]
+          LayoutMenuList {SELECT} at (0,1) size 36x18 [bgcolor=#F8F8F8]
             LayoutBlockFlow (anonymous) at (0,0) size 36x18
               LayoutText (anonymous) at (8,2) size 4x13
                 text run at (8,2) width 4: " "
-          LayoutText {#text} at (36,3) size 3x13
-            text run at (36,3) width 3: " "
-          LayoutMenuList {SELECT} at (38.50,0) size 36x18 [bgcolor=#F8F8F8]
+          LayoutText {#text} at (36,4) size 3x13
+            text run at (36,4) width 3: " "
+          LayoutMenuList {SELECT} at (38.50,1) size 36x18 [bgcolor=#F8F8F8]
             LayoutBlockFlow (anonymous) at (0,0) size 36x18
               LayoutText (anonymous) at (8,2) size 3x13
                 text run at (8,2) width 3: "|"
-          LayoutText {#text} at (74,3) size 3x13
-            text run at (74,3) width 3: " "
-          LayoutMenuList {SELECT} at (77,0) size 78x18 [bgcolor=#F8F8F8]
+          LayoutText {#text} at (74,4) size 3x13
+            text run at (74,4) width 3: " "
+          LayoutMenuList {SELECT} at (77,1) size 78x18 [bgcolor=#F8F8F8]
             LayoutBlockFlow (anonymous) at (0,0) size 78x18
               LayoutText (anonymous) at (8,2) size 47x13
                 text run at (8,2) width 47: "xxxxxxxx"
           LayoutText {#text} at (0,0) size 0x0
-layer at (16,244) size 65x13
+layer at (16,270) size 65x13
   LayoutBlockFlow {DIV} at (3,3) size 65x13
     LayoutText {#text} at (0,0) size 43x13
       text run at (0,0) width 43: "text field"
-layer at (92,241) size 31x59 clip at (93,242) size 18x57 scrollHeight 71
+layer at (92,267) size 31x59 clip at (93,268) size 18x56 scrollHeight 71
   LayoutListBox {SELECT} at (2,2) size 31.08x58.75 [bgcolor=#FFFFFF] [border: (1px solid #999999)]
     LayoutBlockFlow {OPTION} at (1,1) size 18.08x14.19
       LayoutText {#text} at (2,0) size 15x13
@@ -261,16 +261,16 @@
     LayoutBlockFlow {OPTION} at (1,57.75) size 18.08x14.19
       LayoutText {#text} at (2,0) size 7x13
         text run at (2,0) width 7: "5"
-layer at (352,241) size 141x32 clip at (353,242) size 139x30
+layer at (352,267) size 141x32 clip at (353,268) size 139x30
   LayoutTextControl {TEXTAREA} at (2,2) size 141x32 [bgcolor=#FFFFFF] [border: (1px solid #000000)]
     LayoutBlockFlow {DIV} at (3,3) size 135x13
       LayoutText {#text} at (0,0) size 41x13
         text run at (0,0) width 41: "textarea"
-layer at (39,460) size 65x13
+layer at (39,486) size 65x13
   LayoutBlockFlow {DIV} at (3,3) size 65x13
     LayoutText {#text} at (0,0) size 43x13
       text run at (0,0) width 43: "text field"
-layer at (327,439) size 141x32 clip at (328,440) size 139x30
+layer at (327,465) size 141x32 clip at (328,466) size 139x30
   LayoutTextControl {TEXTAREA} at (318.98,0) size 141x32 [bgcolor=#FFFFFF] [border: (1px solid #000000)]
     LayoutBlockFlow {DIV} at (3,3) size 135x13
       LayoutText {#text} at (0,0) size 41x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla/bugs/bug1188-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla/bugs/bug1188-expected.png
index 95e17a7..67c2162 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla/bugs/bug1188-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla/bugs/bug1188-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/form-element-geometry-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/form-element-geometry-expected.png
index 6f7d068..36536125 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/form-element-geometry-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/form-element-geometry-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/form-element-geometry-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/form-element-geometry-expected.txt
index 94cefde..bd8df83 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/form-element-geometry-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/form-element-geometry-expected.txt
@@ -1,8 +1,8 @@
-layer at (0,0) size 800x600 scrollHeight 617
+layer at (0,0) size 800x600 scrollHeight 643
   LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x617 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x616.88
-    LayoutBlockFlow {BODY} at (8,8) size 784x600.88
+layer at (0,0) size 800x643 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x643.31
+    LayoutBlockFlow {BODY} at (8,21.44) size 784x613.88
       LayoutBlockFlow {H1} at (0,0) size 784x37
         LayoutText {#text} at (0,0) size 420x37
           text run at (0,0) width 420: "Form Element Geometry Tests"
@@ -12,78 +12,78 @@
       LayoutBlockFlow {H2} at (0,96.34) size 784x28
         LayoutText {#text} at (0,0) size 167x28
           text run at (0,0) width 167: "Bounding Boxes"
-      LayoutTable {TABLE} at (0,144.25) size 169x28
-        LayoutTableSection {TBODY} at (0,0) size 169x28
-          LayoutTableRow {TR} at (0,2) size 169x24
-            LayoutTableCell {TD} at (2,2) size 57x24 [r=0 c=0 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 55x22 [border: (2px solid #0000FF)]
+      LayoutTable {TABLE} at (0,144.25) size 169x38
+        LayoutTableSection {TBODY} at (0,0) size 169x38
+          LayoutTableRow {TR} at (0,2) size 169x34
+            LayoutTableCell {TD} at (2,2) size 57x34 [r=0 c=0 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 55x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 51x28
-                  LayoutButton {INPUT} at (2,2) size 50.02x18 [bgcolor=#FFFFFF]
+                  LayoutButton {INPUT} at (2,11) size 50.02x18 [bgcolor=#FFFFFF]
                     LayoutBlockFlow (anonymous) at (8,2) size 34.02x13
                       LayoutText {#text} at (0,0) size 34x13
                         text run at (0,0) width 34: "button"
-            LayoutTableCell {TD} at (61,2) size 66x24 [r=0 c=1 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 64x22 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (61,2) size 66x34 [r=0 c=1 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 64x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 60x28
-                  LayoutMenuList {SELECT} at (2,2) size 60x18 [bgcolor=#F8F8F8]
+                  LayoutMenuList {SELECT} at (2,11) size 60x18 [bgcolor=#F8F8F8]
                     LayoutBlockFlow (anonymous) at (0,0) size 60x18
                       LayoutText (anonymous) at (8,2) size 29x13
                         text run at (8,2) width 29: "menu"
-            LayoutTableCell {TD} at (129,4) size 18x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x17 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (129,2) size 18x34 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 12x28
-                  LayoutBlockFlow {INPUT} at (2,2) size 12x13
-            LayoutTableCell {TD} at (149,5) size 18x18 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x16 [border: (2px solid #0000FF)]
+                  LayoutBlockFlow {INPUT} at (2,13) size 12x13
+            LayoutTableCell {TD} at (149,2) size 18x34 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 12x28
-                  LayoutBlockFlow {INPUT} at (2,2) size 12x12
-      LayoutTable {TABLE} at (0,172.25) size 169x28
-        LayoutTableSection {TBODY} at (0,0) size 169x28
-          LayoutTableRow {TR} at (0,2) size 169x24
-            LayoutTableCell {TD} at (2,2) size 57x24 [r=0 c=0 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 55x22 [border: (2px solid #0000FF)]
-                LayoutButton {INPUT} at (2,2) size 50.02x18 [bgcolor=#FFFFFF]
+                  LayoutBlockFlow {INPUT} at (2,14) size 12x12
+      LayoutTable {TABLE} at (0,182.25) size 169x29
+        LayoutTableSection {TBODY} at (0,0) size 169x29
+          LayoutTableRow {TR} at (0,2) size 169x25
+            LayoutTableCell {TD} at (2,2) size 57x25 [r=0 c=0 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 55x23 [border: (2px solid #0000FF)]
+                LayoutButton {INPUT} at (2,3) size 50.02x18 [bgcolor=#FFFFFF]
                   LayoutBlockFlow (anonymous) at (8,2) size 34.02x13
                     LayoutText {#text} at (0,0) size 34x13
                       text run at (0,0) width 34: "button"
-            LayoutTableCell {TD} at (61,2) size 66x24 [r=0 c=1 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 64x22 [border: (2px solid #0000FF)]
-                LayoutMenuList {SELECT} at (2,2) size 60x18 [bgcolor=#F8F8F8]
+            LayoutTableCell {TD} at (61,2) size 66x25 [r=0 c=1 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 64x23 [border: (2px solid #0000FF)]
+                LayoutMenuList {SELECT} at (2,3) size 60x18 [bgcolor=#F8F8F8]
                   LayoutBlockFlow (anonymous) at (0,0) size 60x18
                     LayoutText (anonymous) at (8,2) size 29x13
                       text run at (8,2) width 29: "menu"
-            LayoutTableCell {TD} at (129,4) size 18x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x17 [border: (2px solid #0000FF)]
-                LayoutBlockFlow {INPUT} at (2,2) size 12x13
-            LayoutTableCell {TD} at (149,5) size 18x18 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x16 [border: (2px solid #0000FF)]
-                LayoutBlockFlow {INPUT} at (2,2) size 12x12
-      LayoutTable {TABLE} at (0,200.25) size 169x28
-        LayoutTableSection {TBODY} at (0,0) size 169x28
-          LayoutTableRow {TR} at (0,2) size 169x24
-            LayoutTableCell {TD} at (2,2) size 57x24 [r=0 c=0 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 55x22 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (129,2) size 18x24 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x22 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,5) size 12x13
+            LayoutTableCell {TD} at (149,2) size 18x24 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x22 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,6) size 12x12
+      LayoutTable {TABLE} at (0,211.25) size 169x29
+        LayoutTableSection {TBODY} at (0,0) size 169x29
+          LayoutTableRow {TR} at (0,2) size 169x25
+            LayoutTableCell {TD} at (2,2) size 57x25 [r=0 c=0 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 55x23 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 51x13
-                  LayoutButton {INPUT} at (2,2) size 50.02x18 [bgcolor=#FFFFFF]
+                  LayoutButton {INPUT} at (2,3) size 50.02x18 [bgcolor=#FFFFFF]
                     LayoutBlockFlow (anonymous) at (8,2) size 34.02x13
                       LayoutText {#text} at (0,0) size 34x13
                         text run at (0,0) width 34: "button"
-            LayoutTableCell {TD} at (61,2) size 66x24 [r=0 c=1 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 64x22 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (61,2) size 66x25 [r=0 c=1 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 64x23 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 60x13
-                  LayoutMenuList {SELECT} at (2,2) size 60x18 [bgcolor=#F8F8F8]
+                  LayoutMenuList {SELECT} at (2,3) size 60x18 [bgcolor=#F8F8F8]
                     LayoutBlockFlow (anonymous) at (0,0) size 60x18
                       LayoutText (anonymous) at (8,2) size 29x13
                         text run at (8,2) width 29: "menu"
-            LayoutTableCell {TD} at (129,4) size 18x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x17 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (129,2) size 18x24 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x22 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 12x13
-                  LayoutBlockFlow {INPUT} at (2,2) size 12x13
-            LayoutTableCell {TD} at (149,5) size 18x18 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x16 [border: (2px solid #0000FF)]
+                  LayoutBlockFlow {INPUT} at (2,5) size 12x13
+            LayoutTableCell {TD} at (149,2) size 18x24 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x22 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 12x13
-                  LayoutBlockFlow {INPUT} at (2,2) size 12x12
-      LayoutTable {TABLE} at (0,228.25) size 515x69
+                  LayoutBlockFlow {INPUT} at (2,6) size 12x12
+      LayoutTable {TABLE} at (0,240.25) size 515x69
         LayoutTableSection {TBODY} at (0,0) size 515x69
           LayoutTableRow {TR} at (0,2) size 515x65
             LayoutTableCell {TD} at (2,2) size 77x25 [r=0 c=0 rs=1 cs=1]
@@ -91,19 +91,19 @@
                 LayoutTextControl {INPUT} at (2,2) size 71x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
             LayoutTableCell {TD} at (81,2) size 39x64.75 [r=0 c=1 rs=1 cs=1]
               LayoutBlockFlow {DIV} at (1,1) size 37x62.75 [border: (2px solid #0000FF)]
-            LayoutTableCell {TD} at (122,2) size 242x24 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 240x22 [border: (2px solid #0000FF)]
-                LayoutFileUploadControl {INPUT} at (2,2) size 236x18 "No file chosen"
+            LayoutTableCell {TD} at (122,2) size 242x25 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 240x23 [border: (2px solid #0000FF)]
+                LayoutFileUploadControl {INPUT} at (2,3) size 236x18 "No file chosen"
                   LayoutButton {INPUT} at (0,0) size 76.61x18 [bgcolor=#FFFFFF]
                     LayoutBlockFlow (anonymous) at (8,2) size 60.61x13
                       LayoutText {#text} at (0,0) size 61x13
                         text run at (0,0) width 61: "Choose File"
-            LayoutTableCell {TD} at (366,2) size 147x38 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 145x36 [border: (2px solid #0000FF)]
-      LayoutBlockFlow {H2} at (0,317.16) size 784x28
+            LayoutTableCell {TD} at (366,2) size 147x42 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 145x40 [border: (2px solid #0000FF)]
+      LayoutBlockFlow {H2} at (0,329.16) size 784x28
         LayoutText {#text} at (0,0) size 200x28
           text run at (0,0) width 200: "Baseline Alignment"
-      LayoutBlockFlow {DIV} at (0,365.06) size 784x28
+      LayoutBlockFlow {DIV} at (0,377.06) size 784x28
         LayoutInline {FONT} at (0,0) size 206x28
           LayoutText {#text} at (0,0) size 42x28
             text run at (0,0) width 42: "text "
@@ -124,7 +124,7 @@
             text run at (181,0) width 7: " "
           LayoutBlockFlow {INPUT} at (190.67,12) size 12x12
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,393.06) size 784x19
+      LayoutBlockFlow {DIV} at (0,405.06) size 784x19
         LayoutText {#text} at (0,0) size 28x18
           text run at (0,0) width 28: "text "
         LayoutButton {INPUT} at (27.98,1) size 50.02x18 [bgcolor=#FFFFFF]
@@ -144,7 +144,7 @@
           text run at (163,0) width 5: " "
         LayoutBlockFlow {INPUT} at (170.67,4) size 12x12
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,412.06) size 784x19
+      LayoutBlockFlow {DIV} at (0,424.06) size 784x19
         LayoutInline {FONT} at (0,0) size 171x13
           LayoutText {#text} at (0,4) size 18x13
             text run at (0,4) width 18: "text "
@@ -165,7 +165,7 @@
             text run at (150,4) width 3: " "
           LayoutBlockFlow {INPUT} at (155.67,4) size 12x12
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,431.06) size 784x37
+      LayoutBlockFlow {DIV} at (0,443.06) size 784x37
         LayoutText {#text} at (0,18) size 28x18
           text run at (0,18) width 28: "text "
         LayoutTextControl {INPUT} at (27.98,18) size 71x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
@@ -179,10 +179,10 @@
         LayoutText {#text} at (338,18) size 5x18
           text run at (338,18) width 5: " "
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {H2} at (0,487.97) size 784x28
+      LayoutBlockFlow {H2} at (0,499.97) size 784x28
         LayoutText {#text} at (0,0) size 198x28
           text run at (0,0) width 198: "Pop-up Menu Sizes"
-      LayoutBlockFlow {DIV} at (0,535.88) size 784x28
+      LayoutBlockFlow {DIV} at (0,547.88) size 784x28
         LayoutInline {FONT} at (0,0) size 162x28
           LayoutText {#text} at (0,0) size 0x0
           LayoutMenuList {SELECT} at (0,9) size 36x18 [bgcolor=#F8F8F8]
@@ -202,7 +202,7 @@
               LayoutText (anonymous) at (8,2) size 47x13
                 text run at (8,2) width 47: "xxxxxxxx"
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,563.88) size 784x19
+      LayoutBlockFlow {DIV} at (0,575.88) size 784x19
         LayoutMenuList {SELECT} at (0,1) size 36x18 [bgcolor=#F8F8F8]
           LayoutBlockFlow (anonymous) at (0,0) size 36x18
             LayoutText (anonymous) at (8,2) size 4x13
@@ -220,31 +220,31 @@
             LayoutText (anonymous) at (8,2) size 47x13
               text run at (8,2) width 47: "xxxxxxxx"
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,582.88) size 784x18
+      LayoutBlockFlow {DIV} at (0,594.88) size 784x19
         LayoutInline {FONT} at (0,0) size 155x13
           LayoutText {#text} at (0,0) size 0x0
-          LayoutMenuList {SELECT} at (0,0) size 36x18 [bgcolor=#F8F8F8]
+          LayoutMenuList {SELECT} at (0,1) size 36x18 [bgcolor=#F8F8F8]
             LayoutBlockFlow (anonymous) at (0,0) size 36x18
               LayoutText (anonymous) at (8,2) size 4x13
                 text run at (8,2) width 4: " "
-          LayoutText {#text} at (36,3) size 3x13
-            text run at (36,3) width 3: " "
-          LayoutMenuList {SELECT} at (38.50,0) size 36x18 [bgcolor=#F8F8F8]
+          LayoutText {#text} at (36,4) size 3x13
+            text run at (36,4) width 3: " "
+          LayoutMenuList {SELECT} at (38.50,1) size 36x18 [bgcolor=#F8F8F8]
             LayoutBlockFlow (anonymous) at (0,0) size 36x18
               LayoutText (anonymous) at (8,2) size 4x13
                 text run at (8,2) width 4: "|"
-          LayoutText {#text} at (74,3) size 3x13
-            text run at (74,3) width 3: " "
-          LayoutMenuList {SELECT} at (77,0) size 78x18 [bgcolor=#F8F8F8]
+          LayoutText {#text} at (74,4) size 3x13
+            text run at (74,4) width 3: " "
+          LayoutMenuList {SELECT} at (77,1) size 78x18 [bgcolor=#F8F8F8]
             LayoutBlockFlow (anonymous) at (0,0) size 78x18
               LayoutText (anonymous) at (8,2) size 47x13
                 text run at (8,2) width 47: "xxxxxxxx"
           LayoutText {#text} at (0,0) size 0x0
-layer at (16,244) size 65x13
+layer at (16,270) size 65x13
   LayoutBlockFlow {DIV} at (3,3) size 65x13
     LayoutText {#text} at (0,0) size 46x13
       text run at (0,0) width 46: "text field"
-layer at (92,241) size 32x59 clip at (93,242) size 19x57 scrollHeight 71
+layer at (92,267) size 32x59 clip at (93,268) size 19x56 scrollHeight 71
   LayoutListBox {SELECT} at (2,2) size 32.19x58.75 [bgcolor=#FFFFFF] [border: (1px solid #999999)]
     LayoutBlockFlow {OPTION} at (1,1) size 19.19x14.19
       LayoutText {#text} at (2,0) size 16x13
@@ -261,16 +261,16 @@
     LayoutBlockFlow {OPTION} at (1,57.75) size 19.19x14.19
       LayoutText {#text} at (2,0) size 7x13
         text run at (2,0) width 7: "5"
-layer at (377,241) size 141x32 clip at (378,242) size 139x30
+layer at (377,267) size 141x32 clip at (378,268) size 139x30
   LayoutTextControl {TEXTAREA} at (2,2) size 141x32 [bgcolor=#FFFFFF] [border: (1px solid #000000)]
     LayoutBlockFlow {DIV} at (3,3) size 135x13
       LayoutText {#text} at (0,0) size 43x13
         text run at (0,0) width 43: "textarea"
-layer at (39,460) size 65x13
+layer at (39,486) size 65x13
   LayoutBlockFlow {DIV} at (3,3) size 65x13
     LayoutText {#text} at (0,0) size 46x13
       text run at (0,0) width 46: "text field"
-layer at (351,439) size 141x32 clip at (352,440) size 139x30
+layer at (351,465) size 141x32 clip at (352,466) size 139x30
   LayoutTextControl {TEXTAREA} at (342.98,0) size 141x32 [bgcolor=#FFFFFF] [border: (1px solid #000000)]
     LayoutBlockFlow {DIV} at (3,3) size 135x13
       LayoutText {#text} at (0,0) size 43x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla/bugs/bug1188-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla/bugs/bug1188-expected.png
index 149ff27..70cf66db 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla/bugs/bug1188-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla/bugs/bug1188-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla/core/bloomberg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla/core/bloomberg-expected.png
index ef7e15e..9626ece3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla/core/bloomberg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla/core/bloomberg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/fast/forms/form-element-geometry-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/fast/forms/form-element-geometry-expected.png
index d3dbed1..47162de 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/fast/forms/form-element-geometry-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/fast/forms/form-element-geometry-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/tables/mozilla/bugs/bug1188-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/tables/mozilla/bugs/bug1188-expected.png
index e0b110a5..7b9d6ad 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/tables/mozilla/bugs/bug1188-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/tables/mozilla/bugs/bug1188-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/form-element-geometry-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/form-element-geometry-expected.png
index 5cd5d0b..7a972e0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/form-element-geometry-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/form-element-geometry-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/tables/mozilla/bugs/bug4527-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/tables/mozilla/bugs/bug4527-expected.png
index cf8102e..638ccee 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/tables/mozilla/bugs/bug4527-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/tables/mozilla/bugs/bug4527-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/form-element-geometry-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/form-element-geometry-expected.png
index 294ab7a..9994909 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/form-element-geometry-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/form-element-geometry-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/form-element-geometry-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/form-element-geometry-expected.txt
index f3f4c5d7..044b2f5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/form-element-geometry-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/form-element-geometry-expected.txt
@@ -1,8 +1,8 @@
-layer at (0,0) size 800x600 scrollHeight 617
+layer at (0,0) size 800x600 scrollHeight 643
   LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x617 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x616.88
-    LayoutBlockFlow {BODY} at (8,8) size 784x600.88
+layer at (0,0) size 800x643 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x643.31
+    LayoutBlockFlow {BODY} at (8,21.44) size 784x613.88
       LayoutBlockFlow {H1} at (0,0) size 784x37
         LayoutText {#text} at (0,0) size 420x37
           text run at (0,0) width 420: "Form Element Geometry Tests"
@@ -12,78 +12,78 @@
       LayoutBlockFlow {H2} at (0,96.34) size 784x28
         LayoutText {#text} at (0,0) size 167x28
           text run at (0,0) width 167: "Bounding Boxes"
-      LayoutTable {TABLE} at (0,144.25) size 169x28
-        LayoutTableSection {TBODY} at (0,0) size 169x28
-          LayoutTableRow {TR} at (0,2) size 169x24
-            LayoutTableCell {TD} at (2,2) size 57x24 [r=0 c=0 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 55x22 [border: (2px solid #0000FF)]
+      LayoutTable {TABLE} at (0,144.25) size 169x38
+        LayoutTableSection {TBODY} at (0,0) size 169x38
+          LayoutTableRow {TR} at (0,2) size 169x34
+            LayoutTableCell {TD} at (2,2) size 57x34 [r=0 c=0 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 55x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 51x28
-                  LayoutButton {INPUT} at (2,2) size 50.41x18 [bgcolor=#FFFFFF]
+                  LayoutButton {INPUT} at (2,11) size 50.41x18 [bgcolor=#FFFFFF]
                     LayoutBlockFlow (anonymous) at (8,2) size 34.41x13
                       LayoutText {#text} at (0,0) size 35x13
                         text run at (0,0) width 35: "button"
-            LayoutTableCell {TD} at (61,2) size 66x24 [r=0 c=1 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 64x22 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (61,2) size 66x34 [r=0 c=1 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 64x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 60x28
-                  LayoutMenuList {SELECT} at (2,2) size 60x18 [bgcolor=#F8F8F8]
+                  LayoutMenuList {SELECT} at (2,11) size 60x18 [bgcolor=#F8F8F8]
                     LayoutBlockFlow (anonymous) at (0,0) size 60x18
                       LayoutText (anonymous) at (8,2) size 29x13
                         text run at (8,2) width 29: "menu"
-            LayoutTableCell {TD} at (129,4) size 18x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x17 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (129,2) size 18x34 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 12x28
-                  LayoutBlockFlow {INPUT} at (2,2) size 12x13
-            LayoutTableCell {TD} at (149,5) size 18x18 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x16 [border: (2px solid #0000FF)]
+                  LayoutBlockFlow {INPUT} at (2,13) size 12x13
+            LayoutTableCell {TD} at (149,2) size 18x34 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 12x28
-                  LayoutBlockFlow {INPUT} at (2,2) size 12x12
-      LayoutTable {TABLE} at (0,172.25) size 169x28
-        LayoutTableSection {TBODY} at (0,0) size 169x28
-          LayoutTableRow {TR} at (0,2) size 169x24
-            LayoutTableCell {TD} at (2,2) size 57x24 [r=0 c=0 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 55x22 [border: (2px solid #0000FF)]
-                LayoutButton {INPUT} at (2,2) size 50.41x18 [bgcolor=#FFFFFF]
+                  LayoutBlockFlow {INPUT} at (2,14) size 12x12
+      LayoutTable {TABLE} at (0,182.25) size 169x29
+        LayoutTableSection {TBODY} at (0,0) size 169x29
+          LayoutTableRow {TR} at (0,2) size 169x25
+            LayoutTableCell {TD} at (2,2) size 57x25 [r=0 c=0 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 55x23 [border: (2px solid #0000FF)]
+                LayoutButton {INPUT} at (2,3) size 50.41x18 [bgcolor=#FFFFFF]
                   LayoutBlockFlow (anonymous) at (8,2) size 34.41x13
                     LayoutText {#text} at (0,0) size 35x13
                       text run at (0,0) width 35: "button"
-            LayoutTableCell {TD} at (61,2) size 66x24 [r=0 c=1 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 64x22 [border: (2px solid #0000FF)]
-                LayoutMenuList {SELECT} at (2,2) size 60x18 [bgcolor=#F8F8F8]
+            LayoutTableCell {TD} at (61,2) size 66x25 [r=0 c=1 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 64x23 [border: (2px solid #0000FF)]
+                LayoutMenuList {SELECT} at (2,3) size 60x18 [bgcolor=#F8F8F8]
                   LayoutBlockFlow (anonymous) at (0,0) size 60x18
                     LayoutText (anonymous) at (8,2) size 29x13
                       text run at (8,2) width 29: "menu"
-            LayoutTableCell {TD} at (129,4) size 18x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x17 [border: (2px solid #0000FF)]
-                LayoutBlockFlow {INPUT} at (2,2) size 12x13
-            LayoutTableCell {TD} at (149,5) size 18x18 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x16 [border: (2px solid #0000FF)]
-                LayoutBlockFlow {INPUT} at (2,2) size 12x12
-      LayoutTable {TABLE} at (0,200.25) size 169x28
-        LayoutTableSection {TBODY} at (0,0) size 169x28
-          LayoutTableRow {TR} at (0,2) size 169x24
-            LayoutTableCell {TD} at (2,2) size 57x24 [r=0 c=0 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 55x22 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (129,2) size 18x24 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x22 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,5) size 12x13
+            LayoutTableCell {TD} at (149,2) size 18x24 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x22 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,6) size 12x12
+      LayoutTable {TABLE} at (0,211.25) size 169x29
+        LayoutTableSection {TBODY} at (0,0) size 169x29
+          LayoutTableRow {TR} at (0,2) size 169x25
+            LayoutTableCell {TD} at (2,2) size 57x25 [r=0 c=0 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 55x23 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 51x13
-                  LayoutButton {INPUT} at (2,2) size 50.41x18 [bgcolor=#FFFFFF]
+                  LayoutButton {INPUT} at (2,3) size 50.41x18 [bgcolor=#FFFFFF]
                     LayoutBlockFlow (anonymous) at (8,2) size 34.41x13
                       LayoutText {#text} at (0,0) size 35x13
                         text run at (0,0) width 35: "button"
-            LayoutTableCell {TD} at (61,2) size 66x24 [r=0 c=1 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 64x22 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (61,2) size 66x25 [r=0 c=1 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 64x23 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 60x13
-                  LayoutMenuList {SELECT} at (2,2) size 60x18 [bgcolor=#F8F8F8]
+                  LayoutMenuList {SELECT} at (2,3) size 60x18 [bgcolor=#F8F8F8]
                     LayoutBlockFlow (anonymous) at (0,0) size 60x18
                       LayoutText (anonymous) at (8,2) size 29x13
                         text run at (8,2) width 29: "menu"
-            LayoutTableCell {TD} at (129,4) size 18x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x17 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (129,2) size 18x24 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x22 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 12x13
-                  LayoutBlockFlow {INPUT} at (2,2) size 12x13
-            LayoutTableCell {TD} at (149,5) size 18x18 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 16x16 [border: (2px solid #0000FF)]
+                  LayoutBlockFlow {INPUT} at (2,5) size 12x13
+            LayoutTableCell {TD} at (149,2) size 18x24 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 16x22 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 12x13
-                  LayoutBlockFlow {INPUT} at (2,2) size 12x12
-      LayoutTable {TABLE} at (0,228.25) size 517x69
+                  LayoutBlockFlow {INPUT} at (2,6) size 12x12
+      LayoutTable {TABLE} at (0,240.25) size 517x69
         LayoutTableSection {TBODY} at (0,0) size 517x69
           LayoutTableRow {TR} at (0,2) size 517x65
             LayoutTableCell {TD} at (2,2) size 77x25 [r=0 c=0 rs=1 cs=1]
@@ -91,19 +91,19 @@
                 LayoutTextControl {INPUT} at (2,2) size 71x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
             LayoutTableCell {TD} at (81,2) size 39x64.75 [r=0 c=1 rs=1 cs=1]
               LayoutBlockFlow {DIV} at (1,1) size 37x62.75 [border: (2px solid #0000FF)]
-            LayoutTableCell {TD} at (122,2) size 244x24 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 242x22 [border: (2px solid #0000FF)]
-                LayoutFileUploadControl {INPUT} at (2,2) size 238x18 "No file chosen"
+            LayoutTableCell {TD} at (122,2) size 244x25 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 242x23 [border: (2px solid #0000FF)]
+                LayoutFileUploadControl {INPUT} at (2,3) size 238x18 "No file chosen"
                   LayoutButton {INPUT} at (0,0) size 77.33x18 [bgcolor=#FFFFFF]
                     LayoutBlockFlow (anonymous) at (8,2) size 61.33x13
                       LayoutText {#text} at (0,0) size 62x13
                         text run at (0,0) width 62: "Choose File"
-            LayoutTableCell {TD} at (368,2) size 147x38 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 145x36 [border: (2px solid #0000FF)]
-      LayoutBlockFlow {H2} at (0,317.16) size 784x28
+            LayoutTableCell {TD} at (368,2) size 147x42 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 145x40 [border: (2px solid #0000FF)]
+      LayoutBlockFlow {H2} at (0,329.16) size 784x28
         LayoutText {#text} at (0,0) size 200x28
           text run at (0,0) width 200: "Baseline Alignment"
-      LayoutBlockFlow {DIV} at (0,365.06) size 784x28
+      LayoutBlockFlow {DIV} at (0,377.06) size 784x28
         LayoutInline {FONT} at (0,0) size 206x28
           LayoutText {#text} at (0,0) size 42x28
             text run at (0,0) width 42: "text "
@@ -124,7 +124,7 @@
             text run at (182,0) width 7: " "
           LayoutBlockFlow {INPUT} at (191.06,12) size 12x12
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,393.06) size 784x19
+      LayoutBlockFlow {DIV} at (0,405.06) size 784x19
         LayoutText {#text} at (0,0) size 28x18
           text run at (0,0) width 28: "text "
         LayoutButton {INPUT} at (27.98,1) size 50.41x18 [bgcolor=#FFFFFF]
@@ -144,7 +144,7 @@
           text run at (164,0) width 5: " "
         LayoutBlockFlow {INPUT} at (171.06,4) size 12x12
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,412.06) size 784x19
+      LayoutBlockFlow {DIV} at (0,424.06) size 784x19
         LayoutInline {FONT} at (0,0) size 171x13
           LayoutText {#text} at (0,4) size 18x13
             text run at (0,4) width 18: "text "
@@ -165,7 +165,7 @@
             text run at (150,4) width 4: " "
           LayoutBlockFlow {INPUT} at (156.06,4) size 12x12
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,431.06) size 784x37
+      LayoutBlockFlow {DIV} at (0,443.06) size 784x37
         LayoutText {#text} at (0,18) size 28x18
           text run at (0,18) width 28: "text "
         LayoutTextControl {INPUT} at (27.98,18) size 71x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
@@ -179,10 +179,10 @@
         LayoutText {#text} at (340,18) size 5x18
           text run at (340,18) width 5: " "
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {H2} at (0,487.97) size 784x28
+      LayoutBlockFlow {H2} at (0,499.97) size 784x28
         LayoutText {#text} at (0,0) size 198x28
           text run at (0,0) width 198: "Pop-up Menu Sizes"
-      LayoutBlockFlow {DIV} at (0,535.88) size 784x28
+      LayoutBlockFlow {DIV} at (0,547.88) size 784x28
         LayoutInline {FONT} at (0,0) size 162x28
           LayoutText {#text} at (0,0) size 0x0
           LayoutMenuList {SELECT} at (0,9) size 36x18 [bgcolor=#F8F8F8]
@@ -202,7 +202,7 @@
               LayoutText (anonymous) at (8,2) size 47x13
                 text run at (8,2) width 47: "xxxxxxxx"
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,563.88) size 784x19
+      LayoutBlockFlow {DIV} at (0,575.88) size 784x19
         LayoutMenuList {SELECT} at (0,1) size 36x18 [bgcolor=#F8F8F8]
           LayoutBlockFlow (anonymous) at (0,0) size 36x18
             LayoutText (anonymous) at (8,2) size 4x13
@@ -220,31 +220,31 @@
             LayoutText (anonymous) at (8,2) size 47x13
               text run at (8,2) width 47: "xxxxxxxx"
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,582.88) size 784x18
+      LayoutBlockFlow {DIV} at (0,594.88) size 784x19
         LayoutInline {FONT} at (0,0) size 155x13
           LayoutText {#text} at (0,0) size 0x0
-          LayoutMenuList {SELECT} at (0,0) size 36x18 [bgcolor=#F8F8F8]
+          LayoutMenuList {SELECT} at (0,1) size 36x18 [bgcolor=#F8F8F8]
             LayoutBlockFlow (anonymous) at (0,0) size 36x18
               LayoutText (anonymous) at (8,2) size 4x13
                 text run at (8,2) width 4: " "
-          LayoutText {#text} at (36,3) size 3x13
-            text run at (36,3) width 3: " "
-          LayoutMenuList {SELECT} at (38.50,0) size 36x18 [bgcolor=#F8F8F8]
+          LayoutText {#text} at (36,4) size 3x13
+            text run at (36,4) width 3: " "
+          LayoutMenuList {SELECT} at (38.50,1) size 36x18 [bgcolor=#F8F8F8]
             LayoutBlockFlow (anonymous) at (0,0) size 36x18
               LayoutText (anonymous) at (8,2) size 4x13
                 text run at (8,2) width 4: "|"
-          LayoutText {#text} at (74,3) size 3x13
-            text run at (74,3) width 3: " "
-          LayoutMenuList {SELECT} at (77,0) size 78x18 [bgcolor=#F8F8F8]
+          LayoutText {#text} at (74,4) size 3x13
+            text run at (74,4) width 3: " "
+          LayoutMenuList {SELECT} at (77,1) size 78x18 [bgcolor=#F8F8F8]
             LayoutBlockFlow (anonymous) at (0,0) size 78x18
               LayoutText (anonymous) at (8,2) size 47x13
                 text run at (8,2) width 47: "xxxxxxxx"
           LayoutText {#text} at (0,0) size 0x0
-layer at (16,244) size 65x13
+layer at (16,270) size 65x13
   LayoutBlockFlow {DIV} at (3,3) size 65x13
     LayoutText {#text} at (0,0) size 46x13
       text run at (0,0) width 46: "text field"
-layer at (92,241) size 32x59 clip at (93,242) size 19x57 scrollHeight 71
+layer at (92,267) size 32x59 clip at (93,268) size 19x56 scrollHeight 71
   LayoutListBox {SELECT} at (2,2) size 32.44x58.75 [bgcolor=#FFFFFF] [border: (1px solid #999999)]
     LayoutBlockFlow {OPTION} at (1,1) size 19.44x14.19
       LayoutText {#text} at (2,0) size 16x13
@@ -261,16 +261,16 @@
     LayoutBlockFlow {OPTION} at (1,57.75) size 19.44x14.19
       LayoutText {#text} at (2,0) size 7x13
         text run at (2,0) width 7: "5"
-layer at (379,241) size 141x32 clip at (380,242) size 139x30
+layer at (379,267) size 141x32 clip at (380,268) size 139x30
   LayoutTextControl {TEXTAREA} at (2,2) size 141x32 [bgcolor=#FFFFFF] [border: (1px solid #000000)]
     LayoutBlockFlow {DIV} at (3,3) size 135x13
       LayoutText {#text} at (0,0) size 43x13
         text run at (0,0) width 43: "textarea"
-layer at (39,460) size 65x13
+layer at (39,486) size 65x13
   LayoutBlockFlow {DIV} at (3,3) size 65x13
     LayoutText {#text} at (0,0) size 46x13
       text run at (0,0) width 46: "text field"
-layer at (353,439) size 141x32 clip at (354,440) size 139x30
+layer at (353,465) size 141x32 clip at (354,466) size 139x30
   LayoutTextControl {TEXTAREA} at (344.98,0) size 141x32 [bgcolor=#FFFFFF] [border: (1px solid #000000)]
     LayoutBlockFlow {DIV} at (3,3) size 135x13
       LayoutText {#text} at (0,0) size 43x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug10565-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug10565-expected.png
index 2ce65169..a6961c1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug10565-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug10565-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug113424-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug113424-expected.png
index c62716c..f337fc00 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug113424-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug113424-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1188-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1188-expected.png
index 48eb7e0..94c930c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1188-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1188-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug26553-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug26553-expected.png
new file mode 100644
index 0000000..563fc8bc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug26553-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4427-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4427-expected.png
index 1801958..37e0233 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4427-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4427-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4527-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4527-expected.png
index 06cef1d9..d431e69 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4527-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4527-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug5538-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug5538-expected.png
index 1b61e35..e5ff8dd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug5538-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug5538-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug78162-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug78162-expected.png
index 4aea94e..cde14a6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug78162-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug78162-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug86708-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug86708-expected.png
index d98167a4..275f0247 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug86708-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug86708-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/core/bloomberg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/core/bloomberg-expected.png
index 1d01d90..10a657e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/core/bloomberg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/core/bloomberg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/other/ms-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/other/ms-expected.png
index b15d61dce..7dd621a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/other/ms-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/other/ms-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/bugs/bug23847-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/bugs/bug23847-expected.png
index 027fe7d..d114b3bb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/bugs/bug23847-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/bugs/bug23847-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/bugs/bug72393-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/bugs/bug72393-expected.png
index e60d341..145e9ba 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/bugs/bug72393-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/bugs/bug72393-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/form-element-geometry-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/form-element-geometry-expected.png
index acc28eb4..001778b3 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/form-element-geometry-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/form-element-geometry-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/form-element-geometry-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/forms/form-element-geometry-expected.txt
index f61058de..c9ecb4e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/form-element-geometry-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/form-element-geometry-expected.txt
@@ -1,8 +1,8 @@
-layer at (0,0) size 800x600 scrollHeight 653
+layer at (0,0) size 800x600 scrollHeight 675
   LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x653 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x652.88
-    LayoutBlockFlow {BODY} at (8,8) size 784x636.88
+layer at (0,0) size 800x675 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x675.31
+    LayoutBlockFlow {BODY} at (8,21.44) size 784x645.88
       LayoutBlockFlow {H1} at (0,0) size 784x37
         LayoutText {#text} at (0,0) size 417x36
           text run at (0,0) width 417: "Form Element Geometry Tests"
@@ -12,32 +12,32 @@
       LayoutBlockFlow {H2} at (0,98.34) size 784x27
         LayoutText {#text} at (0,0) size 165x26
           text run at (0,0) width 165: "Bounding Boxes"
-      LayoutTable {TABLE} at (0,145.25) size 166x32
-        LayoutTableSection {TBODY} at (0,0) size 166x32
-          LayoutTableRow {TR} at (0,2) size 166x28
-            LayoutTableCell {TD} at (2,2) size 58x28 [r=0 c=0 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 56x26 [border: (2px solid #0000FF)]
+      LayoutTable {TABLE} at (0,145.25) size 166x38
+        LayoutTableSection {TBODY} at (0,0) size 166x38
+          LayoutTableRow {TR} at (0,2) size 166x34
+            LayoutTableCell {TD} at (2,2) size 58x34 [r=0 c=0 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 56x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 52x27
-                  LayoutButton {INPUT} at (2,2) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+                  LayoutButton {INPUT} at (2,7) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
                     LayoutBlockFlow (anonymous) at (8,3) size 36x16
                       LayoutText {#text} at (0,0) size 36x16
                         text run at (0,0) width 36: "button"
-            LayoutTableCell {TD} at (62,3) size 60x26 [r=0 c=1 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 58x24 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (62,2) size 60x34 [r=0 c=1 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 58x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 54x27
-                  LayoutMenuList {SELECT} at (2,2) size 54x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+                  LayoutMenuList {SELECT} at (2,8) size 54x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
                     LayoutBlockFlow (anonymous) at (1,1) size 52x18
                       LayoutText (anonymous) at (4,1) size 32x16
                         text run at (4,1) width 32: "menu"
-            LayoutTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (124,2) size 19x34 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 17x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 13x27
-                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
-            LayoutTableCell {TD} at (145,6) size 19x19 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+                  LayoutBlockFlow {INPUT} at (2,10) size 13x13
+            LayoutTableCell {TD} at (145,2) size 19x34 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 17x32 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 13x27
-                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
-      LayoutTable {TABLE} at (0,177.25) size 166x32
+                  LayoutBlockFlow {INPUT} at (2,10) size 13x13
+      LayoutTable {TABLE} at (0,183.25) size 166x32
         LayoutTableSection {TBODY} at (0,0) size 166x32
           LayoutTableRow {TR} at (0,2) size 166x28
             LayoutTableCell {TD} at (2,2) size 58x28 [r=0 c=0 rs=1 cs=1]
@@ -52,13 +52,13 @@
                   LayoutBlockFlow (anonymous) at (1,1) size 52x18
                     LayoutText (anonymous) at (4,1) size 32x16
                       text run at (4,1) width 32: "menu"
-            LayoutTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
-                LayoutBlockFlow {INPUT} at (2,2) size 13x13
-            LayoutTableCell {TD} at (145,6) size 19x19 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
-                LayoutBlockFlow {INPUT} at (2,2) size 13x13
-      LayoutTable {TABLE} at (0,209.25) size 166x32
+            LayoutTableCell {TD} at (124,3) size 19x26 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 17x24 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,4) size 13x13
+            LayoutTableCell {TD} at (145,3) size 19x26 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 17x24 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,4) size 13x13
+      LayoutTable {TABLE} at (0,215.25) size 166x32
         LayoutTableSection {TBODY} at (0,0) size 166x32
           LayoutTableRow {TR} at (0,2) size 166x28
             LayoutTableCell {TD} at (2,2) size 58x28 [r=0 c=0 rs=1 cs=1]
@@ -75,22 +75,22 @@
                     LayoutBlockFlow (anonymous) at (1,1) size 52x18
                       LayoutText (anonymous) at (4,1) size 32x16
                         text run at (4,1) width 32: "menu"
-            LayoutTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (124,3) size 19x26 [r=0 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 17x24 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 13x12
-                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
-            LayoutTableCell {TD} at (145,6) size 19x19 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+                  LayoutBlockFlow {INPUT} at (2,4) size 13x13
+            LayoutTableCell {TD} at (145,3) size 19x26 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 17x24 [border: (2px solid #0000FF)]
                 LayoutInline {FONT} at (0,0) size 13x12
-                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
-      LayoutTable {TABLE} at (0,241.25) size 592x80
-        LayoutTableSection {TBODY} at (0,0) size 592x80
-          LayoutTableRow {TR} at (0,2) size 592x76
+                  LayoutBlockFlow {INPUT} at (2,4) size 13x13
+      LayoutTable {TABLE} at (0,247.25) size 594x81
+        LayoutTableSection {TBODY} at (0,0) size 594x81
+          LayoutTableRow {TR} at (0,2) size 594x77
             LayoutTableCell {TD} at (2,2) size 109x28 [r=0 c=0 rs=1 cs=1]
               LayoutBlockFlow {DIV} at (1,1) size 107x26 [border: (2px solid #0000FF)]
                 LayoutTextControl {INPUT} at (2,2) size 103x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-            LayoutTableCell {TD} at (113,2) size 44x76 [r=0 c=1 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 42x74 [border: (2px solid #0000FF)]
+            LayoutTableCell {TD} at (113,2) size 44x77 [r=0 c=1 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 42x75 [border: (2px solid #0000FF)]
             LayoutTableCell {TD} at (159,2) size 244x28 [r=0 c=2 rs=1 cs=1]
               LayoutBlockFlow {DIV} at (1,1) size 242x26 [border: (2px solid #0000FF)]
                 LayoutFileUploadControl {INPUT} at (2,2) size 238x22 "No file chosen"
@@ -98,12 +98,12 @@
                     LayoutBlockFlow (anonymous) at (8,3) size 69x16
                       LayoutText {#text} at (0,0) size 69x16
                         text run at (0,0) width 69: "Choose File"
-            LayoutTableCell {TD} at (405,2) size 185x42 [r=0 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (1,1) size 183x40 [border: (2px solid #0000FF)]
-      LayoutBlockFlow {H2} at (0,341.16) size 784x27
+            LayoutTableCell {TD} at (405,2) size 187x49 [r=0 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (1,1) size 185x47 [border: (2px solid #0000FF)]
+      LayoutBlockFlow {H2} at (0,348.16) size 784x27
         LayoutText {#text} at (0,0) size 199x26
           text run at (0,0) width 199: "Baseline Alignment"
-      LayoutBlockFlow {DIV} at (0,388.06) size 784x28
+      LayoutBlockFlow {DIV} at (0,395.06) size 784x28
         LayoutInline {FONT} at (0,0) size 208x27
           LayoutText {#text} at (0,0) size 43x27
             text run at (0,0) width 43: "text "
@@ -124,7 +124,7 @@
             text run at (182,0) width 6: " "
           LayoutBlockFlow {INPUT} at (192,8) size 13x13
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,416.06) size 784x22
+      LayoutBlockFlow {DIV} at (0,423.06) size 784x22
         LayoutText {#text} at (0,1) size 26x19
           text run at (0,1) width 26: "text "
         LayoutButton {INPUT} at (26,0) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
@@ -144,7 +144,7 @@
           text run at (161,1) width 4: " "
         LayoutBlockFlow {INPUT} at (169,3) size 13x13
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,438.06) size 784x22
+      LayoutBlockFlow {DIV} at (0,445.06) size 784x22
         LayoutInline {FONT} at (0,0) size 174x12
           LayoutText {#text} at (0,6) size 18x12
             text run at (0,6) width 18: "text "
@@ -165,24 +165,24 @@
             text run at (151,6) width 3: " "
           LayoutBlockFlow {INPUT} at (158,3) size 13x13
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,460.06) size 784x42
-        LayoutText {#text} at (0,21) size 26x19
-          text run at (0,21) width 26: "text "
-        LayoutTextControl {INPUT} at (26,20) size 103x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-        LayoutText {#text} at (129,21) size 4x19
-          text run at (129,21) width 4: " "
-        LayoutFileUploadControl {INPUT} at (133,20) size 238x22 "No file chosen"
+      LayoutBlockFlow {DIV} at (0,467.06) size 784x44
+        LayoutText {#text} at (0,23) size 26x19
+          text run at (0,23) width 26: "text "
+        LayoutTextControl {INPUT} at (26,22) size 103x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutText {#text} at (129,23) size 4x19
+          text run at (129,23) width 4: " "
+        LayoutFileUploadControl {INPUT} at (133,22) size 238x22 "No file chosen"
           LayoutButton {INPUT} at (0,0) size 85x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
             LayoutBlockFlow (anonymous) at (8,3) size 69x16
               LayoutText {#text} at (0,0) size 69x16
                 text run at (0,0) width 69: "Choose File"
-        LayoutText {#text} at (371,21) size 4x19
-          text run at (371,21) width 4: " "
+        LayoutText {#text} at (371,23) size 4x19
+          text run at (371,23) width 4: " "
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {H2} at (0,521.97) size 784x27
+      LayoutBlockFlow {H2} at (0,530.97) size 784x27
         LayoutText {#text} at (0,0) size 195x26
           text run at (0,0) width 195: "Pop-up Menu Sizes"
-      LayoutBlockFlow {DIV} at (0,568.88) size 784x28
+      LayoutBlockFlow {DIV} at (0,577.88) size 784x28
         LayoutInline {FONT} at (0,0) size 137x27
           LayoutText {#text} at (0,0) size 0x0
           LayoutMenuList {SELECT} at (0,6) size 22x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
@@ -202,7 +202,7 @@
               LayoutText (anonymous) at (4,1) size 56x16
                 text run at (4,1) width 56: "xxxxxxxx"
           LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,596.88) size 784x20
+      LayoutBlockFlow {DIV} at (0,605.88) size 784x20
         LayoutMenuList {SELECT} at (0,0) size 22x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
           LayoutBlockFlow (anonymous) at (1,1) size 20x18
             LayoutText (anonymous) at (4,1) size 4x16
@@ -220,7 +220,7 @@
             LayoutText (anonymous) at (4,1) size 56x16
               text run at (4,1) width 56: "xxxxxxxx"
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {DIV} at (0,616.88) size 784x20
+      LayoutBlockFlow {DIV} at (0,625.88) size 784x20
         LayoutInline {FONT} at (0,0) size 131x12
           LayoutText {#text} at (0,0) size 0x0
           LayoutMenuList {SELECT} at (0,0) size 22x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
@@ -240,11 +240,11 @@
               LayoutText (anonymous) at (4,1) size 56x16
                 text run at (4,1) width 56: "xxxxxxxx"
           LayoutText {#text} at (0,0) size 0x0
-layer at (15,257) size 99x16
+layer at (15,277) size 99x16
   LayoutBlockFlow {DIV} at (2,3) size 99x16
     LayoutText {#text} at (0,0) size 49x16
       text run at (0,0) width 49: "text field"
-layer at (124,254) size 38x70 clip at (125,255) size 21x68 scrollHeight 85
+layer at (124,274) size 38x70 clip at (125,275) size 21x68 scrollHeight 85
   LayoutListBox {SELECT} at (2,2) size 38x70 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
     LayoutBlockFlow {OPTION} at (1,1) size 21x17
       LayoutText {#text} at (2,0) size 17x16
@@ -261,17 +261,17 @@
     LayoutBlockFlow {OPTION} at (1,69) size 21x17
       LayoutText {#text} at (2,0) size 7x16
         text run at (2,0) width 7: "5"
-layer at (416,254) size 179x36 clip at (417,255) size 177x34
-  LayoutTextControl {TEXTAREA} at (2,2) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+layer at (416,274) size 181x38 clip at (417,275) size 179x36
+  LayoutTextControl {TEXTAREA} at (2,2) size 181x38 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
     LayoutBlockFlow {DIV} at (3,3) size 175x16
       LayoutText {#text} at (0,0) size 64x16
         text run at (0,0) width 64: "textarea"
-layer at (36,491) size 99x16
+layer at (36,514) size 99x16
   LayoutBlockFlow {DIV} at (2,3) size 99x16
     LayoutText {#text} at (0,0) size 49x16
       text run at (0,0) width 49: "text field"
-layer at (383,468) size 179x36 clip at (384,469) size 177x34
-  LayoutTextControl {TEXTAREA} at (375,0) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+layer at (383,489) size 181x38 clip at (384,490) size 179x36
+  LayoutTextControl {TEXTAREA} at (375,0) size 181x38 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
     LayoutBlockFlow {DIV} at (3,3) size 175x16
       LayoutText {#text} at (0,0) size 64x16
         text run at (0,0) width 64: "textarea"
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug10565-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug10565-expected.png
index 9735298..6148dddf 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug10565-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug10565-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug113424-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug113424-expected.png
index 55acb0e..d0d62dc 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug113424-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug113424-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1188-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1188-expected.png
index 493fe89ae..04e7eff 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1188-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1188-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug26553-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug26553-expected.png
new file mode 100644
index 0000000..d2a6f5d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug26553-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4427-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4427-expected.png
index 75e71c4..56212c18 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4427-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4427-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4527-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4527-expected.png
index 1e4ee7c..f8e9483e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4527-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4527-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug5538-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug5538-expected.png
index 9ca9981..9c5cf70 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug5538-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug5538-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug78162-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug78162-expected.png
index 89943481..42c23e8 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug78162-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug78162-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug86708-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug86708-expected.png
index dae652b..83a90c01 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug86708-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug86708-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/core/bloomberg-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/core/bloomberg-expected.png
index a6a91a3..46cd39a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/core/bloomberg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/core/bloomberg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/other/ms-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/other/ms-expected.png
index b344180..a95114d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/other/ms-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/other/ms-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/bugs/bug23847-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/bugs/bug23847-expected.png
index 8454c73..7dc7649 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/bugs/bug23847-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/bugs/bug23847-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/bugs/bug72393-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/bugs/bug72393-expected.png
index 42d1cf8..450702b0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/bugs/bug72393-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/bugs/bug72393-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug10565.html b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug10565.html
index 4bbc1950..b646508d 100644
--- a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug10565.html
+++ b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug10565.html
@@ -1,3 +1,4 @@
+<!doctype html>
 <html>
 <head>
 <title>simplified "image/spacer image/image" table row testcase</title>
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug113424.html b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug113424.html
index 360364b..4e59e823 100644
--- a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug113424.html
+++ b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug113424.html
@@ -1,3 +1,4 @@
+<!doctype html>
 <table width="600" cellspacing="0" cellpadding="0" border="0">
  <tr>
   <td width="100%" align="center" valign="top">
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug1188.html b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug1188.html
index ad11d482..3d848f8 100644
--- a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug1188.html
+++ b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug1188.html
@@ -1,3 +1,4 @@
+<!doctype html>
 <form>
 <hr align=left width=600>
 <TABLE WIDTH=600>
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug26553-expected.png b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug26553-expected.png
deleted file mode 100644
index ddcd6f1..0000000
--- a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug26553-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug26553.html b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug26553.html
index 825e53b..1b497b6d 100644
--- a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug26553.html
+++ b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug26553.html
@@ -1,3 +1,4 @@
+<!doctype html>
 <html>
 <head>
 <style>
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug4427.html b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug4427.html
index e265c0c3..bc5dad1 100644
--- a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug4427.html
+++ b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug4427.html
@@ -1,3 +1,4 @@
+<!doctype html>
 the following is not the bug but is related. Nav put's the images in the 2nd cell
 on the same line. Border widths of cells are suspect here.
 <table border width=26 cellspacing=0 cellpadding=0>
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug4527.html b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug4527.html
index 643ded1..4dd8925 100644
--- a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug4527.html
+++ b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug4527.html
@@ -1,3 +1,4 @@
+<!doctype html>
 <HTML>
         <HEAD>
                 
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug5538.html b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug5538.html
index fc3e2358..975e9ed0d 100644
--- a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug5538.html
+++ b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug5538.html
@@ -1,3 +1,4 @@
+<!doctype html>
 <html>
 <head><title>Testcase for bug 5538 - distilled from www.fool.com</title></head>
 <body bgcolor='#ffffff'>
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug78162.html b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug78162.html
index c3f2810..8a2f538 100644
--- a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug78162.html
+++ b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug78162.html
@@ -1,3 +1,4 @@
+<!doctype html>
 <html><head><title>Testcase for bug 78162</title></head>
 <body bgcolor="#FFFFFF">
 
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug86708.html b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug86708.html
index 7198a3a8..5e76f09 100644
--- a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug86708.html
+++ b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug86708.html
@@ -1,3 +1,4 @@
+<!doctype html>
 <html>
 <head>
 <title>Title</title>
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/core/bloomberg.html b/third_party/WebKit/LayoutTests/tables/mozilla/core/bloomberg.html
index a762fe3..2e35157 100644
--- a/third_party/WebKit/LayoutTests/tables/mozilla/core/bloomberg.html
+++ b/third_party/WebKit/LayoutTests/tables/mozilla/core/bloomberg.html
@@ -1,3 +1,4 @@
+<!doctype html>
 <BODY text="#333333" link="#333333" vlink="#000000" alink="#c0c0c0" bgcolor="#ffffff">
 
 
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/other/ms.html b/third_party/WebKit/LayoutTests/tables/mozilla/other/ms.html
index b89af2ad..e77a296 100644
--- a/third_party/WebKit/LayoutTests/tables/mozilla/other/ms.html
+++ b/third_party/WebKit/LayoutTests/tables/mozilla/other/ms.html
@@ -1,3 +1,4 @@
+<!doctype html>
 <HTML>
 <HEAD>
 </HEAD>
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla_expected_failures/bugs/bug23847.html b/third_party/WebKit/LayoutTests/tables/mozilla_expected_failures/bugs/bug23847.html
index adafa12..66bca3c 100644
--- a/third_party/WebKit/LayoutTests/tables/mozilla_expected_failures/bugs/bug23847.html
+++ b/third_party/WebKit/LayoutTests/tables/mozilla_expected_failures/bugs/bug23847.html
@@ -1,3 +1,4 @@
+<!doctype html>
  <table border>
   <tr> 
    <td colspan=2 rowspan=2> <img src="img/teq1_02.gif" width=122 height=35></td>
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla_expected_failures/bugs/bug72393.html b/third_party/WebKit/LayoutTests/tables/mozilla_expected_failures/bugs/bug72393.html
index 107687d..669beba 100644
--- a/third_party/WebKit/LayoutTests/tables/mozilla_expected_failures/bugs/bug72393.html
+++ b/third_party/WebKit/LayoutTests/tables/mozilla_expected_failures/bugs/bug72393.html
@@ -1,3 +1,4 @@
+<!doctype html>
 <html>
 <head>
 <body>
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 4652d20..f5705d9 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
@@ -4836,6 +4836,11 @@
     setter onconnect
     setter onconnecting
     setter ondisconnect
+interface ReportingObserver
+    attribute @@toStringTag
+    method constructor
+    method disconnect
+    method observe
 interface Request
     attribute @@toStringTag
     getter bodyUsed
diff --git a/third_party/android_build_tools/README.chromium b/third_party/android_build_tools/README.chromium
new file mode 100644
index 0000000..4b768dca
--- /dev/null
+++ b/third_party/android_build_tools/README.chromium
@@ -0,0 +1,20 @@
+Name: Android SDK App Bundle related tools
+Short Name:  Android App bundle tools
+Version: 0
+License: Apache Version 2.0
+License File: NOT_SHIPPED
+URL: https://developer.android.com/guide/app-bundle/build
+Security Critical: No
+
+Description:
+Android App Bundle support requires more recent versions of the
+'bundletool' and 'aapt2' build tools than those provided with the
+copies of the Android SDK currently used by internal or public
+Chrome source checkouts.
+
+This directory contains their binaries, distributed through DEPS
+as two CIPD packages. See bundletool/cipd.yaml and aapt2/cipd.yaml
+for more details.
+
+Local Modifications:
+None
diff --git a/third_party/android_build_tools/aapt2/NOTICE b/third_party/android_build_tools/aapt2/NOTICE
new file mode 100644
index 0000000..6d357b0
--- /dev/null
+++ b/third_party/android_build_tools/aapt2/NOTICE
@@ -0,0 +1,189 @@
+   Copyright (c) 2005-2008, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/third_party/android_build_tools/aapt2/OWNERS b/third_party/android_build_tools/aapt2/OWNERS
new file mode 100644
index 0000000..636ee2d
--- /dev/null
+++ b/third_party/android_build_tools/aapt2/OWNERS
@@ -0,0 +1,3 @@
+digit@chromium.org
+agrieve@chromium.org
+jbudorick@chromium.org
diff --git a/third_party/android_build_tools/aapt2/README.chromium b/third_party/android_build_tools/aapt2/README.chromium
new file mode 100644
index 0000000..2b5880a
--- /dev/null
+++ b/third_party/android_build_tools/aapt2/README.chromium
@@ -0,0 +1,15 @@
+Name: Android SDK tool aapt2
+Short name: aapt2
+Version: 3.2.0-alpha18-4804415
+URL:  https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/${Version}/aapt2-${Version}-linux.jar
+Security Critical: no
+License: Apache Version 2.0
+License file: NOT_SHIPPED
+
+Description:
+The Linux host aapt2 tool is now released on Google Maven, however as a .jar
+file that contains host-specific binaries, which must be extracted. They are
+distributed here as a CIPD package instead. See cipd.yaml for details.
+
+Local Modifications:
+None
diff --git a/third_party/android_build_tools/aapt2/cipd.yaml b/third_party/android_build_tools/aapt2/cipd.yaml
new file mode 100644
index 0000000..843ebc8
--- /dev/null
+++ b/third_party/android_build_tools/aapt2/cipd.yaml
@@ -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.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:3.2.0-alpha18-4804415-cr0
+package: chromium/third_party/android_tools_aapt2
+description: Android SDK tool to build App Bundles
+data:
+  - file: aapt2
+  - file: lib64/libc++.so
diff --git a/third_party/android_build_tools/bundletool/LICENSE b/third_party/android_build_tools/bundletool/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/third_party/android_build_tools/bundletool/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/third_party/android_build_tools/bundletool/OWNERS b/third_party/android_build_tools/bundletool/OWNERS
new file mode 100644
index 0000000..636ee2d
--- /dev/null
+++ b/third_party/android_build_tools/bundletool/OWNERS
@@ -0,0 +1,3 @@
+digit@chromium.org
+agrieve@chromium.org
+jbudorick@chromium.org
diff --git a/third_party/android_build_tools/bundletool/README.chromium b/third_party/android_build_tools/bundletool/README.chromium
new file mode 100644
index 0000000..8caab5c
--- /dev/null
+++ b/third_party/android_build_tools/bundletool/README.chromium
@@ -0,0 +1,15 @@
+Name: Android SDK bundletool
+Short Name:  bundletool
+Version: 0.4.2
+License: Apache Version 2.0
+License File: NOT_SHIPPED
+Security Critical: No
+URL: https://github.com/google/bundletool
+
+Description:
+Bundletool is a tool to manipulate Android App Bundles.
+It is distributed here as a CIPD package. See cipd.yaml for details.
+
+Local Modifications:
+None
+
diff --git a/third_party/android_build_tools/bundletool/cipd.yaml b/third_party/android_build_tools/bundletool/cipd.yaml
new file mode 100644
index 0000000..fe5bc1f
--- /dev/null
+++ b/third_party/android_build_tools/bundletool/cipd.yaml
@@ -0,0 +1,10 @@
+# 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.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:0.4.2-cr0
+package: chromium/third_party/android_tools_bundletool
+description: Android SDK tool to manage App Bundles
+data:
+  - file: bundletool-all-0.4.2.jar
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn
index d3d02043..43eec0f5 100644
--- a/third_party/blink/public/BUILD.gn
+++ b/third_party/blink/public/BUILD.gn
@@ -531,12 +531,6 @@
     "web/web_shared_worker_client.h",
     "web/web_shared_worker_connect_listener.h",
     "web/web_shared_worker_repository_client.h",
-    "web/web_speech_grammar.h",
-    "web/web_speech_recognition_handle.h",
-    "web/web_speech_recognition_params.h",
-    "web/web_speech_recognition_result.h",
-    "web/web_speech_recognizer.h",
-    "web/web_speech_recognizer_client.h",
     "web/web_storage_event_dispatcher.h",
     "web/web_surrounding_text.h",
     "web/web_testing_support.h",
diff --git a/third_party/blink/public/platform/web_feature.mojom b/third_party/blink/public/platform/web_feature.mojom
index 38ac464..36f9a1b 100644
--- a/third_party/blink/public/platform/web_feature.mojom
+++ b/third_party/blink/public/platform/web_feature.mojom
@@ -73,7 +73,6 @@
   kLineClamp = 96,
   kSubFrameBeforeUnloadRegistered = 97,
   kSubFrameBeforeUnloadFired = 98,
-  kConsoleMarkTimeline = 102,
   kDocumentCreateAttribute = 111,
   kDocumentCreateAttributeNS = 112,
   kDocumentXMLEncoding = 115,    // Removed from DOM4.
@@ -316,8 +315,6 @@
   kNotificationCreated = 533,
   kNotificationClosed = 534,
   kNotificationPermissionRequested = 535,
-  kConsoleTimeline = 538,
-  kConsoleTimelineEnd = 539,
   kSRIElementWithMatchingIntegrityAttribute = 540,
   kSRIElementWithNonMatchingIntegrityAttribute = 541,
   kSRIElementWithUnparsableIntegrityAttribute = 542,
diff --git a/third_party/blink/public/platform/web_url_request.h b/third_party/blink/public/platform/web_url_request.h
index a9fc9af..f72e098506 100644
--- a/third_party/blink/public/platform/web_url_request.h
+++ b/third_party/blink/public/platform/web_url_request.h
@@ -346,6 +346,10 @@
   BLINK_PLATFORM_EXPORT const base::Optional<base::UnguessableToken>&
   GetDevToolsToken() const;
 
+  // Set the applicable Origin Policy.
+  BLINK_PLATFORM_EXPORT const WebString GetOriginPolicy() const;
+  BLINK_PLATFORM_EXPORT void SetOriginPolicy(const WebString& policy);
+
 #if INSIDE_BLINK
   BLINK_PLATFORM_EXPORT ResourceRequest& ToMutableResourceRequest();
   BLINK_PLATFORM_EXPORT const ResourceRequest& ToResourceRequest() const;
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
index a04ac6a..b0acd67 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -108,7 +108,6 @@
 class WebRTCPeerConnectionHandler;
 class WebRelatedAppsFetcher;
 class WebSocketHandshakeThrottle;
-class WebSpeechRecognizer;
 class WebString;
 class WebURL;
 class WebURLResponse;
@@ -798,11 +797,6 @@
     }
   }
 
-  // Speech --------------------------------------------------------------
-
-  // Access the embedder API for speech recognition services.
-  virtual WebSpeechRecognizer* SpeechRecognizer() { return nullptr; }
-
   // Visibility ----------------------------------------------------------
 
   // Returns the current visibility of the WebFrame.
diff --git a/third_party/blink/public/web/web_speech_grammar.h b/third_party/blink/public/web/web_speech_grammar.h
deleted file mode 100644
index c4f495b..0000000
--- a/third_party/blink/public/web/web_speech_grammar.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_GRAMMAR_H_
-#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_GRAMMAR_H_
-
-#include "third_party/blink/public/platform/web_common.h"
-#include "third_party/blink/public/platform/web_private_ptr.h"
-#include "third_party/blink/public/platform/web_url.h"
-
-namespace blink {
-
-class SpeechGrammar;
-
-class WebSpeechGrammar {
- public:
-  WebSpeechGrammar() = default;
-  WebSpeechGrammar(const WebSpeechGrammar& grammar) { Assign(grammar); }
-  ~WebSpeechGrammar() { Reset(); }
-
-  BLINK_EXPORT WebURL Src() const;
-  BLINK_EXPORT float Weight() const;
-
-  BLINK_EXPORT void Reset();
-  BLINK_EXPORT void Assign(const WebSpeechGrammar&);
-
-#if INSIDE_BLINK
-  WebSpeechGrammar& operator=(SpeechGrammar*);
-#endif
-
- private:
-  WebPrivatePtr<SpeechGrammar> private_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_GRAMMAR_H_
diff --git a/third_party/blink/public/web/web_speech_recognition_handle.h b/third_party/blink/public/web/web_speech_recognition_handle.h
deleted file mode 100644
index 003b5f0c..0000000
--- a/third_party/blink/public/web/web_speech_recognition_handle.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNITION_HANDLE_H_
-#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNITION_HANDLE_H_
-
-#include "third_party/blink/public/platform/web_common.h"
-#include "third_party/blink/public/platform/web_private_ptr.h"
-
-namespace blink {
-
-class SpeechRecognition;
-
-// WebSpeechRecognitionHandle is used by WebSpeechRecognizer to identify a
-// recognition session, and by WebSpeechRecognizerClient to route
-// recognition events.
-class WebSpeechRecognitionHandle {
- public:
-  ~WebSpeechRecognitionHandle() { Reset(); }
-  WebSpeechRecognitionHandle() = default;
-
-  WebSpeechRecognitionHandle(const WebSpeechRecognitionHandle& other) {
-    Assign(other);
-  }
-  WebSpeechRecognitionHandle& operator=(
-      const WebSpeechRecognitionHandle& other) {
-    Assign(other);
-    return *this;
-  }
-
-  BLINK_EXPORT void Reset();
-  BLINK_EXPORT void Assign(const WebSpeechRecognitionHandle&);
-
-  // Comparison functions are provided so that WebSpeechRecognitionHandle
-  // objects can be stored in a hash map.
-  BLINK_EXPORT bool Equals(const WebSpeechRecognitionHandle&) const;
-  BLINK_EXPORT bool LessThan(const WebSpeechRecognitionHandle&) const;
-
-#if INSIDE_BLINK
-  WebSpeechRecognitionHandle(SpeechRecognition*);
-  operator SpeechRecognition*() const;
-#endif
-
- private:
-  WebPrivatePtr<SpeechRecognition> private_;
-};
-
-inline bool operator==(const WebSpeechRecognitionHandle& a,
-                       const WebSpeechRecognitionHandle& b) {
-  return a.Equals(b);
-}
-
-inline bool operator!=(const WebSpeechRecognitionHandle& a,
-                       const WebSpeechRecognitionHandle& b) {
-  return !(a == b);
-}
-
-inline bool operator<(const WebSpeechRecognitionHandle& a,
-                      const WebSpeechRecognitionHandle& b) {
-  return a.LessThan(b);
-}
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNITION_HANDLE_H_
diff --git a/third_party/blink/public/web/web_speech_recognition_params.h b/third_party/blink/public/web/web_speech_recognition_params.h
deleted file mode 100644
index b1729b5..0000000
--- a/third_party/blink/public/web/web_speech_recognition_params.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNITION_PARAMS_H_
-#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNITION_PARAMS_H_
-
-#include "third_party/blink/public/platform/web_security_origin.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/public/web/web_speech_grammar.h"
-
-namespace blink {
-
-class WebSpeechGrammar;
-
-class WebSpeechRecognitionParams {
- public:
-  WebSpeechRecognitionParams(const WebVector<WebSpeechGrammar>& grammars,
-                             const WebString& language,
-                             bool continuous,
-                             bool interim_results,
-                             unsigned long max_alternatives,
-                             const WebSecurityOrigin& origin)
-      : grammars_(grammars),
-        language_(language),
-        continuous_(continuous),
-        interim_results_(interim_results),
-        max_alternatives_(max_alternatives),
-        origin_(origin) {}
-
-  const WebVector<WebSpeechGrammar>& Grammars() const { return grammars_; }
-  const WebString& Language() const { return language_; }
-  bool Continuous() const { return continuous_; }
-  bool InterimResults() const { return interim_results_; }
-  unsigned long MaxAlternatives() const { return max_alternatives_; }
-  const WebSecurityOrigin& Origin() const { return origin_; }
-
- private:
-  WebVector<WebSpeechGrammar> grammars_;
-  WebString language_;
-  bool continuous_;
-  bool interim_results_;
-  unsigned long max_alternatives_;
-  WebSecurityOrigin origin_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNITION_PARAMS_H_
diff --git a/third_party/blink/public/web/web_speech_recognition_result.h b/third_party/blink/public/web/web_speech_recognition_result.h
deleted file mode 100644
index e5587da..0000000
--- a/third_party/blink/public/web/web_speech_recognition_result.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNITION_RESULT_H_
-#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNITION_RESULT_H_
-
-#include "third_party/blink/public/platform/web_common.h"
-#include "third_party/blink/public/platform/web_private_ptr.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_vector.h"
-
-namespace blink {
-
-class SpeechRecognitionResult;
-
-class WebSpeechRecognitionResult {
- public:
-  WebSpeechRecognitionResult() = default;
-  WebSpeechRecognitionResult(const WebSpeechRecognitionResult& result) {
-    Assign(result);
-  }
-  ~WebSpeechRecognitionResult() { Reset(); }
-
-  BLINK_EXPORT void Assign(const WebVector<WebString>& transcripts,
-                           const WebVector<float>& confidences,
-                           bool final);
-  BLINK_EXPORT void Assign(const WebSpeechRecognitionResult&);
-  BLINK_EXPORT void Reset();
-
-#if INSIDE_BLINK
-  operator SpeechRecognitionResult*() const;
-#endif
-
- private:
-  WebPrivatePtr<SpeechRecognitionResult> private_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNITION_RESULT_H_
diff --git a/third_party/blink/public/web/web_speech_recognizer.h b/third_party/blink/public/web/web_speech_recognizer.h
deleted file mode 100644
index b9775ed..0000000
--- a/third_party/blink/public/web/web_speech_recognizer.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNIZER_H_
-#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNIZER_H_
-
-#include "third_party/blink/public/platform/web_common.h"
-#include "third_party/blink/public/web/web_speech_recognition_handle.h"
-
-namespace blink {
-
-class WebSpeechRecognitionParams;
-class WebSpeechRecognizerClient;
-
-// Interface for speech recognition, to be implemented by the embedder.
-class WebSpeechRecognizer {
- public:
-  // Start speech recognition for the specified handle using the specified
-  // parameters. Notifications on progress, results, and errors will be sent via
-  // the client.
-  virtual void Start(const WebSpeechRecognitionHandle&,
-                     const WebSpeechRecognitionParams&,
-                     const WebSpeechRecognizerClient&) = 0;
-
-  // Stop speech recognition for the specified handle, returning any results for
-  // the audio recorded so far. Notifications and errors are sent via the
-  // client.
-  virtual void Stop(const WebSpeechRecognitionHandle&,
-                    const WebSpeechRecognizerClient&) = 0;
-
-  // Abort speech recognition for the specified handle, discarding any recorded
-  // audio. Notifications and errors are sent via the client.
-  virtual void Abort(const WebSpeechRecognitionHandle&,
-                     const WebSpeechRecognizerClient&) = 0;
-
- protected:
-  virtual ~WebSpeechRecognizer() = default;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNIZER_H_
diff --git a/third_party/blink/public/web/web_speech_recognizer_client.h b/third_party/blink/public/web/web_speech_recognizer_client.h
deleted file mode 100644
index f397ef2b..0000000
--- a/third_party/blink/public/web/web_speech_recognizer_client.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNIZER_CLIENT_H_
-#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNIZER_CLIENT_H_
-
-#include "third_party/blink/public/platform/web_common.h"
-#include "third_party/blink/public/platform/web_private_ptr.h"
-#include "third_party/blink/public/platform/web_vector.h"
-
-namespace blink {
-
-class SpeechRecognitionClientProxy;
-class WebSpeechRecognitionResult;
-class WebSpeechRecognitionHandle;
-class WebString;
-
-// A client for reporting progress on speech recognition for a specific handle.
-class BLINK_EXPORT WebSpeechRecognizerClient {
- public:
-  enum ErrorCode {
-    kOtherError = 0,
-    kNoSpeechError = 1,
-    kAbortedError = 2,
-    kAudioCaptureError = 3,
-    kNetworkError = 4,
-    kNotAllowedError = 5,
-    kServiceNotAllowedError = 6,
-    kBadGrammarError = 7,
-    kLanguageNotSupportedError = 8
-  };
-
-  WebSpeechRecognizerClient() = default;
-  WebSpeechRecognizerClient(const WebSpeechRecognizerClient& other) {
-    Assign(other);
-  }
-  WebSpeechRecognizerClient& operator=(const WebSpeechRecognizerClient& other) {
-    Assign(other);
-    return *this;
-  }
-  ~WebSpeechRecognizerClient();
-
-  bool operator==(const WebSpeechRecognizerClient& other) const;
-  bool operator!=(const WebSpeechRecognizerClient& other) const;
-
-  void Reset();
-  bool IsNull() const { return private_.IsNull(); }
-
-  // These methods correspond to the events described in the spec:
-  // http://speech-javascript-api-spec.googlecode.com/git/speechapi.html#speechreco-events
-
-  // To be called when the embedder has started to capture audio.
-  void DidStartAudio(const WebSpeechRecognitionHandle&);
-
-  // To be called when some sound, possibly speech, has been detected.
-  // This is expected to be called after didStartAudio.
-  void DidStartSound(const WebSpeechRecognitionHandle&);
-
-  // To be called when sound is no longer detected.
-  // This is expected to be called after didEndSpeech.
-  void DidEndSound(const WebSpeechRecognitionHandle&);
-
-  // To be called when audio capture has stopped.
-  // This is expected to be called after didEndSound.
-  void DidEndAudio(const WebSpeechRecognitionHandle&);
-
-  // To be called when the speech recognizer provides new results.
-  // - newFinalResults contains zero or more final results that are new since
-  // the last time the function was called.
-  // - currentInterimResults contains zero or more inteirm results that
-  // replace the interim results that were reported the last time this
-  // function was called.
-  void DidReceiveResults(
-      const WebSpeechRecognitionHandle&,
-      const WebVector<WebSpeechRecognitionResult>& new_final_results,
-      const WebVector<WebSpeechRecognitionResult>& current_interim_results);
-
-  // To be called when the speech recognizer returns a final result with no
-  // recognizion hypothesis.
-  void DidReceiveNoMatch(const WebSpeechRecognitionHandle&,
-                         const WebSpeechRecognitionResult&);
-
-  // To be called when a speech recognition error occurs.
-  void DidReceiveError(const WebSpeechRecognitionHandle&,
-                       const WebString& message,
-                       ErrorCode);
-
-  // To be called when the recognizer has begun to listen to the audio with
-  // the intention of recognizing.
-  void DidStart(const WebSpeechRecognitionHandle&);
-
-  // To be called when the recognition session has ended. This must always be
-  // called, no matter the reason for the end.
-  void DidEnd(const WebSpeechRecognitionHandle&);
-
-#if INSIDE_BLINK
-  explicit WebSpeechRecognizerClient(SpeechRecognitionClientProxy*);
-#endif
-
- private:
-  void Assign(const WebSpeechRecognizerClient&);
-
-  WebPrivatePtr<SpeechRecognitionClientProxy> private_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SPEECH_RECOGNIZER_CLIENT_H_
diff --git a/third_party/blink/renderer/DEPS b/third_party/blink/renderer/DEPS
index d278ac48..e22674b 100644
--- a/third_party/blink/renderer/DEPS
+++ b/third_party/blink/renderer/DEPS
@@ -12,6 +12,7 @@
     "+base/memory/ptr_util.h",
     "+base/memory/weak_ptr.h",
     "+base/metrics/histogram_macros.h",
+    "+base/numerics/checked_math.h",
     "+base/optional.h",
     "+base/rand_util.h",
     "+base/sequenced_task_runner.h",
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.cc b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
index ac7fe5b..007a4f8 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
@@ -213,8 +213,7 @@
     return false;
 
   const int kJavascriptSchemeLength = sizeof("javascript:") - 1;
-  String script_source = DecodeURLEscapeSequences(url.GetString())
-                             .Substring(kJavascriptSchemeLength);
+  String script_source = DecodeURLEscapeSequences(url.GetString());
 
   bool should_bypass_main_world_content_security_policy =
       ContentSecurityPolicy::ShouldBypassMainWorld(GetFrame()->GetDocument());
@@ -229,6 +228,8 @@
     return true;
   }
 
+  script_source = script_source.Substring(kJavascriptSchemeLength);
+
   bool progress_notifications_needed =
       GetFrame()->Loader().StateMachine()->IsDisplayingInitialEmptyDocument() &&
       !GetFrame()->IsLoading();
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.h b/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.h
index 37cfb8d..7950b9f 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.h
@@ -24,7 +24,7 @@
 class ExecutionContext;
 class ScriptState;
 
-// TODO(yhirano): Remove NEVER_INLINE once we find the cause of crashes.
+// TODO(yhirano): Remove NOINLINE once we find the cause of crashes.
 class CORE_EXPORT ScriptPromisePropertyBase
     : public GarbageCollectedFinalized<ScriptPromisePropertyBase>,
       public ContextClient {
@@ -71,7 +71,7 @@
       v8::Isolate*,
       v8::Local<v8::Object> creation_context) = 0;
 
-  NEVER_INLINE void ResetBase();
+  NOINLINE void ResetBase();
 
  private:
   typedef Vector<std::unique_ptr<ScopedPersistent<v8::Object>>>
@@ -79,10 +79,10 @@
 
   void ResolveOrRejectInternal(v8::Local<v8::Promise::Resolver>);
   v8::Local<v8::Object> EnsureHolderWrapper(ScriptState*);
-  NEVER_INLINE void ClearWrappers();
+  NOINLINE void ClearWrappers();
   // TODO(yhirano): Remove these functions once we find the cause of crashes.
-  NEVER_INLINE void CheckThis();
-  NEVER_INLINE void CheckWrappers();
+  NOINLINE void CheckThis();
+  NOINLINE void CheckWrappers();
 
   V8PrivateProperty::Symbol PromiseSymbol();
   V8PrivateProperty::Symbol ResolverSymbol();
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
index 4ff1392..b0594b2 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
@@ -32,6 +32,7 @@
 
 #include <algorithm>
 #include <memory>
+#include "base/numerics/checked_math.h"
 #include "base/sys_byteorder.h"
 #include "third_party/blink/public/web/web_serialized_script_value_version.h"
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
@@ -57,7 +58,6 @@
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/shared_buffer.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/dtoa/utils.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_buffer.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
@@ -92,7 +92,7 @@
 
 scoped_refptr<SerializedScriptValue> SerializedScriptValue::Create(
     const String& data) {
-  CheckedNumeric<size_t> data_buffer_size = data.length();
+  base::CheckedNumeric<size_t> data_buffer_size = data.length();
   data_buffer_size *= 2;
   if (!data_buffer_size.IsValid())
     return Create();
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
index 1aada38e..840de22 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h"
 
+#include "base/numerics/checked_math.h"
 #include "third_party/blink/public/platform/web_blob_info.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h"
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
@@ -25,7 +26,6 @@
 #include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/date_math.h"
 
 namespace blink {
@@ -325,7 +325,7 @@
                                 canvas_opacity_mode,
                                 SerializedImageDataStorageFormat::kUint8Clamped)
               .GetCanvasColorParams();
-      CheckedNumeric<uint32_t> computed_byte_length = width;
+      base::CheckedNumeric<uint32_t> computed_byte_length = width;
       computed_byte_length *= height;
       computed_byte_length *= color_params.BytesPerPixel();
       if (!computed_byte_length.IsValid() ||
@@ -380,7 +380,7 @@
           canvas_color_space, SerializedPixelFormat::kRGBA8,
           SerializedOpacityMode::kNonOpaque, image_data_storage_format);
       ImageDataStorageFormat storage_format = color_params.GetStorageFormat();
-      CheckedNumeric<uint32_t> computed_byte_length = width;
+      base::CheckedNumeric<uint32_t> computed_byte_length = width;
       computed_byte_length *= height;
       computed_byte_length *= 4;
       computed_byte_length *= ImageData::StorageFormatDataSize(storage_format);
diff --git a/third_party/blink/renderer/core/clipboard/system_clipboard.cc b/third_party/blink/renderer/core/clipboard/system_clipboard.cc
index a51a2a3..bd4dad3 100644
--- a/third_party/blink/renderer/core/clipboard/system_clipboard.cc
+++ b/third_party/blink/renderer/core/clipboard/system_clipboard.cc
@@ -18,7 +18,6 @@
 #include "third_party/blink/renderer/platform/clipboard/clipboard_utilities.h"
 #include "third_party/blink/renderer/platform/graphics/image.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 
diff --git a/third_party/blink/renderer/core/dom/BUILD.gn b/third_party/blink/renderer/core/dom/BUILD.gn
index d8f6ddf..a24b087 100644
--- a/third_party/blink/renderer/core/dom/BUILD.gn
+++ b/third_party/blink/renderer/core/dom/BUILD.gn
@@ -291,14 +291,14 @@
 
   public_deps = [
     "//third_party/blink/public/mojom:mojom_core_blink",
+
+    # Needed to generate included files, e.g. add_event_listener_options.h
+    "//third_party/blink/renderer/bindings/core/v8:bindings_core_v8_generated",
   ]
 
   deps = [
     "//services/metrics/public/cpp:metrics_cpp",
     "//services/metrics/public/cpp:ukm_builders",
     "//services/metrics/public/mojom",
-
-    # Needed to generate add_event_listener_options.h
-    "//third_party/blink/renderer/bindings/core/v8:bindings_core_impl_generated",
   ]
 }
diff --git a/third_party/blink/renderer/core/dom/character_data.cc b/third_party/blink/renderer/core/dom/character_data.cc
index ff291a2..4fe5a46d 100644
--- a/third_party/blink/renderer/core/dom/character_data.cc
+++ b/third_party/blink/renderer/core/dom/character_data.cc
@@ -22,6 +22,7 @@
 
 #include "third_party/blink/renderer/core/dom/character_data.h"
 
+#include "base/numerics/checked_math.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/dom/mutation_observer_interest_group.h"
@@ -32,7 +33,6 @@
 #include "third_party/blink/renderer/core/events/mutation_event.h"
 #include "third_party/blink/renderer/core/probe/core_probes.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 
 namespace blink {
 
@@ -114,7 +114,7 @@
     return false;
   }
 
-  CheckedNumeric<unsigned> offset_count = offset;
+  base::CheckedNumeric<unsigned> offset_count = offset;
   offset_count += count;
 
   if (!offset_count.IsValid() || offset + count > length)
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index db0f7fd..a690c4e 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -4699,7 +4699,8 @@
               ContainingShadowRoot()->IsUserAgent()) ||
              GetDocument().GetContentSecurityPolicy()->AllowInlineStyle(
                  this, GetDocument().Url(), String(), start_line_number,
-                 new_style_string, ContentSecurityPolicy::InlineType::kBlock)) {
+                 new_style_string,
+                 ContentSecurityPolicy::InlineType::kAttribute)) {
     SetInlineStyleFromString(new_style_string);
   }
 
diff --git a/third_party/blink/renderer/core/dom/events/event_queue.cc b/third_party/blink/renderer/core/dom/events/event_queue.cc
index 5600b6e..1c457e0 100644
--- a/third_party/blink/renderer/core/dom/events/event_queue.cc
+++ b/third_party/blink/renderer/core/dom/events/event_queue.cc
@@ -41,7 +41,10 @@
 EventQueue::EventQueue(ExecutionContext* context, TaskType task_type)
     : ContextLifecycleObserver(context),
       task_type_(task_type),
-      is_closed_(false) {}
+      is_closed_(false) {
+  if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed())
+    Close(nullptr);
+}
 
 EventQueue::~EventQueue() = default;
 
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 0868b42..ac940abc 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
@@ -523,13 +523,13 @@
   const KURL& kurl = url;
   DCHECK(kurl.ProtocolIs("javascript"));
 
-  String script = DecodeURLEscapeSequences(
-      kurl.GetString().Substring(strlen("javascript:")));
+  String script = DecodeURLEscapeSequences(kurl.GetString());
 
   if (!element_->GetDocument().GetContentSecurityPolicy()->AllowJavaScriptURLs(
           element_, script, element_->GetDocument().Url(), OrdinalNumber())) {
     return WebString();
   }
+  script = script.Substring(strlen("javascript:"));
 
   std::unique_ptr<UserGestureIndicator> gesture_indicator;
   if (popups_allowed) {
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
index d3062cd..256ac154 100644
--- a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
+++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
@@ -501,9 +501,17 @@
     const String& context_url,
     const WTF::OrdinalNumber& context_line,
     SecurityViolationReportingPolicy reporting_policy) const {
+  // Javascript URLs may be whitelisted by hash, if
+  // 'unsafe-hashes' is present in a policy. Check against the digest
+  // of the |source| and also check whether inline script is allowed.
+  Vector<CSPHashValue> csp_hash_values;
+  FillInCSPHashValues(source, script_hash_algorithms_used_, csp_hash_values);
+
   bool is_allowed = true;
   for (const auto& policy : policies_) {
-    is_allowed &= policy->AllowJavaScriptURLs(element, source, context_url,
+    is_allowed &= CheckScriptHashAgainstPolicy(csp_hash_values, policy,
+                                               InlineType::kAttribute) ||
+                  policy->AllowJavaScriptURLs(element, source, context_url,
                                               context_line, reporting_policy);
   }
   return is_allowed;
@@ -516,7 +524,7 @@
     const WTF::OrdinalNumber& context_line,
     SecurityViolationReportingPolicy reporting_policy) const {
   // Inline event handlers may be whitelisted by hash, if
-  // 'unsafe-hash-attributes' is present in a policy. Check against the digest
+  // 'unsafe-hashes' is present in a policy. Check against the digest
   // of the |source| and also check whether inline script is allowed.
   Vector<CSPHashValue> csp_hash_values;
   FillInCSPHashValues(source, script_hash_algorithms_used_, csp_hash_values);
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
index 9a748e3e..caa84664 100644
--- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
+++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -236,9 +236,9 @@
   return !directive || directive->AllowHash(hash_value);
 }
 
-bool CSPDirectiveList::CheckHashedAttributes(
+bool CSPDirectiveList::CheckUnsafeHashesAllowed(
     SourceListDirective* directive) const {
-  return !directive || directive->AllowHashedAttributes();
+  return !directive || directive->AllowUnsafeHashes();
 }
 
 bool CSPDirectiveList::CheckDynamic(SourceListDirective* directive) const {
@@ -612,7 +612,7 @@
   if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
     return CheckInlineAndReportViolation(
         directive,
-        "Refused to execute JavaScript URL because it violates the following "
+        "Refused to run the JavaScript URL because it violates the following "
         "Content Security Policy directive: ",
         element, source, context_url, context_line, true, "sha256-...");
   }
@@ -972,24 +972,28 @@
              : CheckAncestors(frame_ancestors_.Get(), frame);
 }
 
-bool CSPDirectiveList::AllowScriptHash(
-    const CSPHashValue& hash_value,
-    ContentSecurityPolicy::InlineType type) const {
+bool CSPDirectiveList::AllowHash(const CSPHashValue& hash_value,
+                                 ContentSecurityPolicy::InlineType type,
+                                 SourceListDirective* directive) const {
   if (type == ContentSecurityPolicy::InlineType::kAttribute) {
     if (!policy_->ExperimentalFeaturesEnabled())
       return false;
-    if (!CheckHashedAttributes(OperativeDirective(script_src_.Get())))
+    if (!CheckUnsafeHashesAllowed(OperativeDirective(directive)))
       return false;
   }
-  return CheckHash(OperativeDirective(script_src_.Get()), hash_value);
+  return CheckHash(OperativeDirective(directive), hash_value);
+}
+
+bool CSPDirectiveList::AllowScriptHash(
+    const CSPHashValue& hash_value,
+    ContentSecurityPolicy::InlineType type) const {
+  return AllowHash(hash_value, type, script_src_.Get());
 }
 
 bool CSPDirectiveList::AllowStyleHash(
     const CSPHashValue& hash_value,
     ContentSecurityPolicy::InlineType type) const {
-  if (type != ContentSecurityPolicy::InlineType::kBlock)
-    return false;
-  return CheckHash(OperativeDirective(style_src_.Get()), hash_value);
+  return AllowHash(hash_value, type, style_src_.Get());
 }
 
 bool CSPDirectiveList::AllowDynamic() const {
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
index 7538884..16a5e70 100644
--- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
+++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
@@ -267,7 +267,7 @@
   bool AreAllMatchingHashesPresent(SourceListDirective*,
                                    const IntegrityMetadataSet&) const;
   bool CheckHash(SourceListDirective*, const CSPHashValue&) const;
-  bool CheckHashedAttributes(SourceListDirective*) const;
+  bool CheckUnsafeHashesAllowed(SourceListDirective*) const;
   bool CheckSource(SourceListDirective*,
                    const KURL&,
                    ResourceRequest::RedirectStatus) const;
@@ -330,6 +330,10 @@
       const ContentSecurityPolicy::DirectiveType&,
       const CSPDirectiveListVector& policies);
 
+  bool AllowHash(const CSPHashValue&,
+                 ContentSecurityPolicy::InlineType,
+                 SourceListDirective* directive) const;
+
   Member<ContentSecurityPolicy> policy_;
 
   String header_;
diff --git a/third_party/blink/renderer/core/frame/csp/source_list_directive.cc b/third_party/blink/renderer/core/frame/csp/source_list_directive.cc
index d01d351..7ad92d9 100644
--- a/third_party/blink/renderer/core/frame/csp/source_list_directive.cc
+++ b/third_party/blink/renderer/core/frame/csp/source_list_directive.cc
@@ -37,7 +37,7 @@
       allow_eval_(false),
       allow_wasm_eval_(false),
       allow_dynamic_(false),
-      allow_hashed_attributes_(false),
+      allow_unsafe_hashes_(false),
       report_sample_(false),
       hash_algorithms_used_(0) {
   Vector<UChar> characters;
@@ -108,8 +108,8 @@
   return hashes_.Contains(hash_value);
 }
 
-bool SourceListDirective::AllowHashedAttributes() const {
-  return allow_hashed_attributes_;
+bool SourceListDirective::AllowUnsafeHashes() const {
+  return allow_unsafe_hashes_;
 }
 
 bool SourceListDirective::AllowReportSample() const {
@@ -118,7 +118,7 @@
 
 bool SourceListDirective::IsNone() const {
   return !list_.size() && !allow_self_ && !allow_star_ && !allow_inline_ &&
-         !allow_hashed_attributes_ && !allow_eval_ && !allow_wasm_eval_ &&
+         !allow_unsafe_hashes_ && !allow_eval_ && !allow_wasm_eval_ &&
          !allow_dynamic_ && !nonces_.size() && !hashes_.size();
 }
 
@@ -234,8 +234,8 @@
     return true;
   }
 
-  if (EqualIgnoringASCIICase("'unsafe-hashed-attributes'", token)) {
-    AddSourceUnsafeHashedAttributes();
+  if (EqualIgnoringASCIICase("'unsafe-hashes'", token)) {
+    AddSourceUnsafeHashes();
     return true;
   }
 
@@ -632,8 +632,8 @@
   allow_dynamic_ = true;
 }
 
-void SourceListDirective::AddSourceUnsafeHashedAttributes() {
-  allow_hashed_attributes_ = true;
+void SourceListDirective::AddSourceUnsafeHashes() {
+  allow_unsafe_hashes_ = true;
 }
 
 void SourceListDirective::AddReportSample() {
@@ -719,7 +719,7 @@
   bool allow_eval_other = other[0]->allow_eval_;
   bool allow_wasm_eval_other = other[0]->allow_wasm_eval_;
   bool allow_dynamic_other = other[0]->allow_dynamic_;
-  bool allow_hashed_attributes_other = other[0]->allow_hashed_attributes_;
+  bool allow_unsafe_hashes = other[0]->allow_unsafe_hashes_;
   bool is_hash_or_nonce_present_other = other[0]->IsHashOrNoncePresent();
   HashSet<String> nonces_b = other[0]->nonces_;
   HashSet<CSPHashValue> hashes_b = other[0]->hashes_;
@@ -731,8 +731,7 @@
     allow_eval_other = allow_eval_other && other[i]->allow_eval_;
     allow_wasm_eval_other = allow_wasm_eval_other && other[i]->allow_wasm_eval_;
     allow_dynamic_other = allow_dynamic_other && other[i]->allow_dynamic_;
-    allow_hashed_attributes_other =
-        allow_hashed_attributes_other && other[i]->allow_hashed_attributes_;
+    allow_unsafe_hashes = allow_unsafe_hashes && other[i]->allow_unsafe_hashes_;
     is_hash_or_nonce_present_other =
         is_hash_or_nonce_present_other && other[i]->IsHashOrNoncePresent();
     nonces_b = other[i]->GetIntersectNonces(nonces_b);
@@ -751,7 +750,7 @@
       return false;
     if (!allow_wasm_eval_ && allow_wasm_eval_other)
       return false;
-    if (!allow_hashed_attributes_ && allow_hashed_attributes_other)
+    if (!allow_unsafe_hashes_ && allow_unsafe_hashes)
       return false;
     bool allow_all_inline_other =
         allow_inline_other && !is_hash_or_nonce_present_other &&
diff --git a/third_party/blink/renderer/core/frame/csp/source_list_directive.h b/third_party/blink/renderer/core/frame/csp/source_list_directive.h
index 87a85279..195c0af 100644
--- a/third_party/blink/renderer/core/frame/csp/source_list_directive.h
+++ b/third_party/blink/renderer/core/frame/csp/source_list_directive.h
@@ -43,7 +43,7 @@
   bool AllowDynamic() const;
   bool AllowNonce(const String& nonce) const;
   bool AllowHash(const CSPHashValue&) const;
-  bool AllowHashedAttributes() const;
+  bool AllowUnsafeHashes() const;
   bool AllowReportSample() const;
   bool IsNone() const;
   bool IsHashOrNoncePresent() const;
@@ -102,7 +102,7 @@
   void AddSourceUnsafeEval();
   void AddSourceWasmEval();
   void AddSourceStrictDynamic();
-  void AddSourceUnsafeHashedAttributes();
+  void AddSourceUnsafeHashes();
   void AddReportSample();
   void AddSourceNonce(const String& nonce);
   void AddSourceHash(const ContentSecurityPolicyHashAlgorithm&,
@@ -132,7 +132,7 @@
   bool allow_eval_;
   bool allow_wasm_eval_;
   bool allow_dynamic_;
-  bool allow_hashed_attributes_;
+  bool allow_unsafe_hashes_;
   bool allow_redirects_;
   bool report_sample_;
   HashSet<String> nonces_;
diff --git a/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc b/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc
index 225007a..97987c6e 100644
--- a/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc
+++ b/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc
@@ -74,11 +74,11 @@
   EXPECT_TRUE(source_list.AllowDynamic());
 }
 
-TEST_F(SourceListDirectiveTest, BasicMatchingUnsafeHashedAttributes) {
-  String sources = "'unsafe-hashed-attributes'";
+TEST_F(SourceListDirectiveTest, BasicMatchingUnsafeHashes) {
+  String sources = "'unsafe-hashes'";
   SourceListDirective source_list("script-src", sources, csp.Get());
 
-  EXPECT_TRUE(source_list.AllowHashedAttributes());
+  EXPECT_TRUE(source_list.AllowUnsafeHashes());
 }
 
 TEST_F(SourceListDirectiveTest, BasicMatchingStar) {
@@ -743,37 +743,37 @@
         "http://example1.com/foo/bar 'self' 'unsafe-eval'",
         "http://non-example.com/foo/ 'unsafe-eval' 'self'"},
        false},
-      // A or policiesB contain `unsafe-hashed-attributes`.
+      // A or policiesB contain `unsafe-hashes`.
       {false,
        "http://example1.com/foo/ 'self' 'unsafe-inline' 'unsafe-eval' "
        "'strict-dynamic' "
-       "'unsafe-hashed-attributes'",
-       {"http://example1.com/foo/bar.html 'unsafe-hashed-attributes'"},
+       "'unsafe-hashes'",
+       {"http://example1.com/foo/bar.html 'unsafe-hashes'"},
        true},
       {true,
-       "http://example1.com/foo/ 'self' 'unsafe-hashed-attributes'",
+       "http://example1.com/foo/ 'self' 'unsafe-hashes'",
        {"http://example1.com/foo/ 'unsafe-inline'"},
        false},
       {true,
-       "http://example1.com/foo/ 'self' 'unsafe-hashed-attributes'",
-       {"http://example1.com/foo/ 'unsafe-inline' 'unsafe-hashed-attributes'"},
+       "http://example1.com/foo/ 'self' 'unsafe-hashes'",
+       {"http://example1.com/foo/ 'unsafe-inline' 'unsafe-hashes'"},
        false},
       {true,
        "http://example1.com/foo/ 'self' 'unsafe-eval' "
-       "'unsafe-hashed-attributes'",
-       {"http://example1.com/foo/ 'unsafe-eval' 'unsafe-hashed-attributes'",
-        "http://example1.com/foo/bar 'self' 'unsafe-hashed-attributes'",
-        "http://non-example.com/foo/ 'unsafe-hashed-attributes' 'self'"},
+       "'unsafe-hashes'",
+       {"http://example1.com/foo/ 'unsafe-eval' 'unsafe-hashes'",
+        "http://example1.com/foo/bar 'self' 'unsafe-hashes'",
+        "http://non-example.com/foo/ 'unsafe-hashes' 'self'"},
        true},
       {true,
        "http://example1.com/foo/ 'self'",
-       {"http://example1.com/foo/ 'unsafe-hashed-attributes'"},
+       {"http://example1.com/foo/ 'unsafe-hashes'"},
        false},
       {true,
        "http://example1.com/foo/ 'self' 'unsafe-inline'",
-       {"http://example1.com/foo/ 'unsafe-hashed-attributes'",
-        "http://example1.com/foo/bar 'self' 'unsafe-hashed-attributes'",
-        "https://example1.com/foo/bar 'unsafe-hashed-attributes' 'self'"},
+       {"http://example1.com/foo/ 'unsafe-hashes'",
+        "http://example1.com/foo/bar 'self' 'unsafe-hashes'",
+        "https://example1.com/foo/bar 'unsafe-hashes' 'self'"},
        false},
   };
 
@@ -1130,13 +1130,13 @@
        {"'strict-dynamic' 'nonce-yay'", "'nonce-yay'", "'sha512-321abc'"},
        true},
       {true,
-       "http://example1.com/foo/ 'self' 'unsafe-hashed-attributes' "
+       "http://example1.com/foo/ 'self' 'unsafe-hashes' "
        "'strict-dynamic'",
-       {"'strict-dynamic' 'unsafe-hashed-attributes'"},
+       {"'strict-dynamic' 'unsafe-hashes'"},
        true},
       {true,
        "http://example1.com/foo/ 'self' 'nonce-yay' 'strict-dynamic'",
-       {"'strict-dynamic' 'nonce-yay' 'unsafe-hashed-attributes'"},
+       {"'strict-dynamic' 'nonce-yay' 'unsafe-hashes'"},
        false},
       {true,
        "http://example1.com/foo/ 'self' 'unsafe-eval' 'strict-dynamic'",
@@ -1209,12 +1209,12 @@
        {"'unsafe-eval' 'strict-dynamic'"},
        false},
       {true,
-       "'unsafe-hashed-attributes' 'self' 'sha512-321abc' 'strict-dynamic'",
-       {"'unsafe-hashed-attributes' 'strict-dynamic'"},
+       "'unsafe-hashes' 'self' 'sha512-321abc' 'strict-dynamic'",
+       {"'unsafe-hashes' 'strict-dynamic'"},
        true},
       {true,
        "http://example1.com/foo/ 'self' 'sha512-321abc' 'strict-dynamic'",
-       {"'unsafe-hashed-attributes' 'strict-dynamic'"},
+       {"'unsafe-hashes' 'strict-dynamic'"},
        false},
   };
 
@@ -1256,7 +1256,7 @@
       {"http://another.test", {"https:", "'self'"}, true},
       {"'self'", {"*", "'self'"}, true},
       {"'unsafe-eval' * ", {"'unsafe-eval'"}, true},
-      {"'unsafe-hashed-attributes' * ", {"'unsafe-hashed-attributes'"}, true},
+      {"'unsafe-hashes' * ", {"'unsafe-hashes'"}, true},
       {"'unsafe-inline' * ", {"'unsafe-inline'"}, true},
       {"*", {"*", "http://a.com ws://b.com ftp://c.com"}, true},
       {"*", {"* data: blob:", "http://a.com ws://b.com ftp://c.com"}, true},
@@ -1279,10 +1279,10 @@
        false},
       {"https://another.test", {"*"}, false},
       {"*", {"* 'unsafe-eval'"}, false},
-      {"*", {"* 'unsafe-hashed-attributes'"}, false},
+      {"*", {"* 'unsafe-hashes'"}, false},
       {"*", {"* 'unsafe-inline'"}, false},
       {"'unsafe-eval'", {"* 'unsafe-eval'"}, false},
-      {"'unsafe-hashed-attributes'", {"* 'unsafe-hashed-attributes'"}, false},
+      {"'unsafe-hashes'", {"* 'unsafe-hashes'"}, false},
       {"'unsafe-inline'", {"* 'unsafe-inline'"}, false},
       {"*", {"data: blob:", "data://a.com ws://b.com ftp://c.com"}, false},
       {"* data:",
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc
index 7ee5229..057528e 100644
--- a/third_party/blink/renderer/core/frame/deprecation.cc
+++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -182,10 +182,6 @@
                          "'navigator.webkitTemporaryStorage' or "
                          "'navigator.webkitPersistentStorage'")};
 
-    case WebFeature::kConsoleMarkTimeline:
-      return {"ConsoleMarkTimeline", kUnknown,
-              ReplacedBy("'console.markTimeline'", "'console.timeStamp'")};
-
     case WebFeature::kPrefixedVideoSupportsFullscreen:
       return {"PrefixedVideoSupportsFullscreen", kUnknown,
               ReplacedBy("'HTMLVideoElement.webkitSupportsFullscreen'",
@@ -231,14 +227,6 @@
               "<source src> with a <picture> parent is invalid and therefore "
               "ignored. Please use <source srcset> instead."};
 
-    case WebFeature::kConsoleTimeline:
-      return {"ConsoleTimeline", kUnknown,
-              ReplacedBy("'console.timeline'", "'console.time'")};
-
-    case WebFeature::kConsoleTimelineEnd:
-      return {"ConsoleTimelineEnd", kUnknown,
-              ReplacedBy("'console.timelineEnd'", "'console.timeEnd'")};
-
     case WebFeature::kXMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload:
       return {"XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload",
               kUnknown,
diff --git a/third_party/blink/renderer/core/frame/deprecation_report_body.idl b/third_party/blink/renderer/core/frame/deprecation_report_body.idl
index 41b6e3d4..780cc3c 100644
--- a/third_party/blink/renderer/core/frame/deprecation_report_body.idl
+++ b/third_party/blink/renderer/core/frame/deprecation_report_body.idl
@@ -6,7 +6,7 @@
 
 [
     NoInterfaceObject,
-    RuntimeEnabled=ReportingObserver
+    RuntimeEnabled=DeprecationReporting
 ] interface DeprecationReportBody : ReportBody {
   readonly attribute DOMString id;
   readonly attribute Date? anticipatedRemoval;
diff --git a/third_party/blink/renderer/core/frame/intervention_report_body.idl b/third_party/blink/renderer/core/frame/intervention_report_body.idl
index 52f0b82..c5d0dd4 100644
--- a/third_party/blink/renderer/core/frame/intervention_report_body.idl
+++ b/third_party/blink/renderer/core/frame/intervention_report_body.idl
@@ -6,7 +6,7 @@
 
 [
     NoInterfaceObject,
-    RuntimeEnabled=ReportingObserver
+    RuntimeEnabled=InterventionReporting
 ] interface InterventionReportBody : ReportBody {
   // TODO(paulmeyer): Add additional data, such as id.
   readonly attribute DOMString message;
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
index fcbd602..9bed705c 100644
--- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
+++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -32,6 +32,7 @@
 #include <memory>
 
 #include "base/location.h"
+#include "base/numerics/checked_math.h"
 #include "build/build_config.h"
 #include "gpu/config/gpu_feature_info.h"
 #include "third_party/blink/public/platform/task_type.h"
@@ -82,7 +83,6 @@
 #include "third_party/blink/renderer/platform/histogram.h"
 #include "third_party/blink/renderer/platform/image-encoders/image_encoder_utils.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "v8/include/v8.h"
 
 namespace blink {
@@ -936,7 +936,7 @@
   if (GetLayoutBox() && !GetLayoutBox()->HasAcceleratedCompositing())
     return false;
 
-  CheckedNumeric<int> checked_canvas_pixel_count = Size().Width();
+  base::CheckedNumeric<int> checked_canvas_pixel_count = Size().Width();
   checked_canvas_pixel_count *= Size().Height();
   if (!checked_canvas_pixel_count.IsValid())
     return false;
@@ -1468,7 +1468,8 @@
   // a change from acceleration to non-accleration or vice versa.
   if (gpu_buffer_count && !gpu_memory_usage_) {
     // Switch from non-acceleration mode to acceleration mode
-    CheckedNumeric<intptr_t> checked_usage = gpu_buffer_count * bytes_per_pixel;
+    base::CheckedNumeric<intptr_t> checked_usage =
+        gpu_buffer_count * bytes_per_pixel;
     checked_usage *= width();
     checked_usage *= height();
     intptr_t gpu_memory_usage =
@@ -1487,7 +1488,7 @@
 
   // Recomputation of externally memory usage computation is carried out
   // in all cases.
-  CheckedNumeric<intptr_t> checked_usage =
+  base::CheckedNumeric<intptr_t> checked_usage =
       non_gpu_buffer_count * bytes_per_pixel;
   checked_usage *= width();
   checked_usage *= height();
diff --git a/third_party/blink/renderer/core/html/canvas/image_data.cc b/third_party/blink/renderer/core/html/canvas/image_data.cc
index 67a66dc..984fa750 100644
--- a/third_party/blink/renderer/core/html/canvas/image_data.cc
+++ b/third_party/blink/renderer/core/html/canvas/image_data.cc
@@ -73,7 +73,7 @@
   }
 
   if (param_flags & (kParamWidth | kParamHeight)) {
-    CheckedNumeric<unsigned> data_size = 4;
+    base::CheckedNumeric<unsigned> data_size = 4;
     if (color_settings) {
       data_size *=
           ImageData::StorageFormatDataSize(color_settings->storageFormat());
@@ -133,7 +133,7 @@
   if (param_flags & kParamSize) {
     if (size->Width() <= 0 || size->Height() <= 0)
       return false;
-    CheckedNumeric<unsigned> data_size = 4;
+    base::CheckedNumeric<unsigned> data_size = 4;
     data_size *= size->Width();
     data_size *= size->Height();
     if (!data_size.IsValid() ||
@@ -493,7 +493,7 @@
 // This function accepts size (0, 0) and always returns the ImageData in
 // "srgb" color space and "uint8" storage format.
 ImageData* ImageData::CreateForTest(const IntSize& size) {
-  CheckedNumeric<unsigned> data_size = 4;
+  base::CheckedNumeric<unsigned> data_size = 4;
   data_size *= size.Width();
   data_size *= size.Height();
   if (!data_size.IsValid() ||
diff --git a/third_party/blink/renderer/core/html/canvas/image_data.h b/third_party/blink/renderer/core/html/canvas/image_data.h
index e3994227..ff86ba4d 100644
--- a/third_party/blink/renderer/core/html/canvas/image_data.h
+++ b/third_party/blink/renderer/core/html/canvas/image_data.h
@@ -29,6 +29,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_IMAGE_DATA_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_IMAGE_DATA_H_
 
+#include "base/numerics/checked_math.h"
 #include "third_party/blink/renderer/bindings/core/v8/uint8_clamped_array_or_uint16_array_or_float32_array.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
@@ -42,7 +43,6 @@
 #include "third_party/blink/renderer/platform/graphics/canvas_color_params.h"
 #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/compiler.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "third_party/skia/include/core/SkColorSpace.h"
diff --git a/third_party/blink/renderer/core/html/media/autoplay_policy.cc b/third_party/blink/renderer/core/html/media/autoplay_policy.cc
index f8fddfc9..b6d8c82a 100644
--- a/third_party/blink/renderer/core/html/media/autoplay_policy.cc
+++ b/third_party/blink/renderer/core/html/media/autoplay_policy.cc
@@ -332,6 +332,12 @@
   return *autoplay_initiated_;
 }
 
+void AutoplayPolicy::EnsureAutoplayInitiatedSet() {
+  if (autoplay_initiated_)
+    return;
+  autoplay_initiated_ = false;
+}
+
 bool AutoplayPolicy::IsGestureNeededForPlaybackIfPendingUserGestureIsLocked()
     const {
   if (element_->GetLoadType() == WebMediaPlayer::kLoadTypeMediaStream)
diff --git a/third_party/blink/renderer/core/html/media/autoplay_policy.h b/third_party/blink/renderer/core/html/media/autoplay_policy.h
index 81c12a3..c35f132f 100644
--- a/third_party/blink/renderer/core/html/media/autoplay_policy.h
+++ b/third_party/blink/renderer/core/html/media/autoplay_policy.h
@@ -99,6 +99,10 @@
   // should only return `true` when MEI allowed autoplay.
   bool WasAutoplayInitiated() const;
 
+  // Ensure that `autoplay_initiated_` has a value. It is set to `false` to
+  // avoid false positives.
+  void EnsureAutoplayInitiatedSet();
+
   virtual void Trace(blink::Visitor*);
 
  private:
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc
index 60e732cc..d0fc98fa 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -4279,6 +4279,7 @@
 }
 
 void HTMLMediaElement::RequestPlay() {
+  autoplay_policy_->EnsureAutoplayInitiatedSet();
   PlayInternal();
 }
 
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
index 381bb953..5eb37a9b 100644
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
+++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 #include "base/memory/scoped_refptr.h"
+#include "base/numerics/checked_math.h"
 #include "base/single_thread_task_runner.h"
 #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
 #include "third_party/blink/renderer/core/html/canvas/image_data.h"
@@ -17,7 +18,6 @@
 #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
 #include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
 #include "third_party/blink/renderer/platform/threading/background_task_runner.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkColorSpaceXformCanvas.h"
 #include "third_party/skia/include/core/SkImageInfo.h"
@@ -138,7 +138,7 @@
 // each ImageBitmap() constructor, which makes sure that doing
 // width * height * bytesPerPixel will never overflow unsigned.
 bool DstBufferSizeHasOverflow(const ImageBitmap::ParsedOptions& options) {
-  CheckedNumeric<unsigned> total_bytes = options.crop_rect.Width();
+  base::CheckedNumeric<unsigned> total_bytes = options.crop_rect.Width();
   total_bytes *= options.crop_rect.Height();
   total_bytes *=
       SkColorTypeBytesPerPixel(options.color_params.GetSkColorType());
diff --git a/third_party/blink/renderer/core/layout/counter_node.cc b/third_party/blink/renderer/core/layout/counter_node.cc
index 36feb40..b700966 100644
--- a/third_party/blink/renderer/core/layout/counter_node.cc
+++ b/third_party/blink/renderer/core/layout/counter_node.cc
@@ -21,8 +21,8 @@
 
 #include "third_party/blink/renderer/core/layout/counter_node.h"
 
+#include "base/numerics/checked_math.h"
 #include "third_party/blink/renderer/core/layout/layout_counter.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 
 #ifndef NDEBUG
 #include <stdio.h>
@@ -148,11 +148,11 @@
   // https://drafts.csswg.org/css-lists-3/#valdef-counter-reset-custom-ident-integer
   int increment = ActsAsReset() ? 0 : value_;
   if (previous_sibling_) {
-    return WTF::CheckAdd(previous_sibling_->count_in_parent_, increment)
+    return base::CheckAdd(previous_sibling_->count_in_parent_, increment)
         .ValueOrDefault(previous_sibling_->count_in_parent_);
   }
   DCHECK_EQ(parent_->first_child_, this);
-  return WTF::CheckAdd(parent_->value_, increment)
+  return base::CheckAdd(parent_->value_, increment)
       .ValueOrDefault(parent_->value_);
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.cc b/third_party/blink/renderer/core/layout/layout_block_flow.cc
index 6669454c..00c6463 100644
--- a/third_party/blink/renderer/core/layout/layout_block_flow.cc
+++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -55,6 +55,7 @@
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_line_height_metrics.h"
 #include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h"
 #include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
@@ -4603,44 +4604,9 @@
   return *rare_data_;
 }
 
-base::Optional<LayoutUnit> LayoutBlockFlow::ComputeDialogYPosition(
-    LayoutUnit height) const {
-  DCHECK(IsHTMLDialogElement(GetNode()));
-  HTMLDialogElement* dialog = ToHTMLDialogElement(GetNode());
-  if (dialog->GetCenteringMode() == HTMLDialogElement::kNotCentered)
-    return base::nullopt;
-
-  bool can_center_dialog = (Style()->GetPosition() == EPosition::kAbsolute ||
-                            Style()->GetPosition() == EPosition::kFixed) &&
-                           Style()->HasAutoTopAndBottom();
-
-  if (dialog->GetCenteringMode() == HTMLDialogElement::kCentered) {
-    if (can_center_dialog)
-      return dialog->CenteredPosition();
-    return base::nullopt;
-  }
-
-  DCHECK_EQ(dialog->GetCenteringMode(), HTMLDialogElement::kNeedsCentering);
-  if (!can_center_dialog) {
-    dialog->SetNotCentered();
-    return base::nullopt;
-  }
-
-  auto* scrollable_area = GetDocument().View()->LayoutViewport();
-  LayoutUnit top =
-      LayoutUnit((Style()->GetPosition() == EPosition::kFixed)
-                     ? 0
-                     : scrollable_area->ScrollOffsetInt().Height());
-
-  int visible_height = GetDocument().View()->Height();
-  if (height < visible_height)
-    top += (visible_height - height) / 2;
-  dialog->SetCentered(top);
-  return top;
-}
-
 void LayoutBlockFlow::PositionDialog() {
-  base::Optional<LayoutUnit> y = ComputeDialogYPosition(Size().Height());
+  base::Optional<LayoutUnit> y =
+      ComputeAbsoluteDialogYPosition(*this, Size().Height());
   if (y.has_value())
     SetY(y.value());
 }
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.h b/third_party/blink/renderer/core/layout/layout_block_flow.h
index 6a6b67b6..8003efb0b 100644
--- a/third_party/blink/renderer/core/layout/layout_block_flow.h
+++ b/third_party/blink/renderer/core/layout/layout_block_flow.h
@@ -808,8 +808,6 @@
 
   bool ShouldTruncateOverflowingText() const;
 
-  base::Optional<LayoutUnit> ComputeDialogYPosition(LayoutUnit height) const;
-
   int GetLayoutPassCountForTesting();
 
  protected:
diff --git a/third_party/blink/renderer/core/layout/layout_replaced.cc b/third_party/blink/renderer/core/layout/layout_replaced.cc
index 046da37..b97f2085 100644
--- a/third_party/blink/renderer/core/layout/layout_replaced.cc
+++ b/third_party/blink/renderer/core/layout/layout_replaced.cc
@@ -639,6 +639,11 @@
 
 void LayoutReplaced::ComputeIntrinsicSizingInfo(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  if (ShouldApplySizeContainment()) {
+    intrinsic_sizing_info.size = FloatSize();
+    return;
+  }
+
   intrinsic_sizing_info.size = FloatSize(IntrinsicLogicalWidth().ToFloat(),
                                          IntrinsicLogicalHeight().ToFloat());
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc
index bb5a636..9572166f 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc
@@ -9,6 +9,8 @@
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
 #include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
 #include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.h"
+#include "third_party/blink/renderer/platform/fonts/character_range.h"
+#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h"
 
 namespace blink {
 
@@ -138,7 +140,24 @@
 void NGAbstractInlineTextBox::CharacterWidths(Vector<float>& widths) const {
   if (!fragment_)
     return;
-  // TODO(layout-dev): We should implement |CharacterWidths()|.
+  if (!PhysicalTextFragment().TextShapeResult()) {
+    // When |fragment_| for BR, we don't have shape result.
+    // "aom-computed-boolean-properties.html" reaches here.
+    widths.resize(Len());
+    return;
+  }
+  const ShapeResult& shape_result = *PhysicalTextFragment().TextShapeResult();
+  ShapeResultBuffer buffer;
+  buffer.AppendResult(&shape_result);
+  const Vector<CharacterRange> ranges = buffer.IndividualCharacterRanges(
+      shape_result.Direction(), shape_result.Width());
+  widths.ReserveCapacity(ranges.size());
+  widths.resize(0);
+  for (const auto& range : ranges)
+    widths.push_back(range.Width());
+  // The shaper can fail to return glyph metrics for all characters (see
+  // crbug.com/613915 and crbug.com/615661) so add empty ranges to ensure all
+  // characters have an associated range.
   widths.resize(Len());
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc
index cadd9c3..d671935 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc
@@ -289,25 +289,40 @@
 }
 
 Position NGCaretPosition::ToPositionInDOMTree() const {
+  return ToPositionInDOMTreeWithAffinity().GetPosition();
+}
+
+PositionWithAffinity NGCaretPosition::ToPositionInDOMTreeWithAffinity() const {
   if (!fragment)
-    return Position();
+    return PositionWithAffinity();
   switch (position_type) {
     case NGCaretPositionType::kBeforeBox:
       if (!fragment->GetNode())
-        return Position();
-      return Position::BeforeNode(*fragment->GetNode());
+        return PositionWithAffinity();
+      return PositionWithAffinity(Position::BeforeNode(*fragment->GetNode()),
+                                  TextAffinity::kDownstream);
     case NGCaretPositionType::kAfterBox:
       if (!fragment->GetNode())
-        return Position();
-      return Position::AfterNode(*fragment->GetNode());
+        return PositionWithAffinity();
+      return PositionWithAffinity(Position::AfterNode(*fragment->GetNode()),
+                                  TextAffinity::kUpstreamIfPossible);
     case NGCaretPositionType::kAtTextOffset:
       DCHECK(text_offset.has_value());
       const NGOffsetMapping* mapping =
           NGOffsetMapping::GetFor(fragment->GetLayoutObject());
-      return mapping->GetFirstPosition(*text_offset);
+      const Position position = mapping->GetFirstPosition(*text_offset);
+      if (position.IsNull())
+        return PositionWithAffinity();
+      const NGPhysicalTextFragment& text_fragment =
+          ToNGPhysicalTextFragment(fragment->PhysicalFragment());
+      const TextAffinity affinity =
+          text_offset.value() == text_fragment.EndOffset()
+              ? TextAffinity::kUpstreamIfPossible
+              : TextAffinity::kDownstream;
+      return PositionWithAffinity(position, affinity);
   }
   NOTREACHED();
-  return Position();
+  return PositionWithAffinity();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.h b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.h
index e6a963099..cb3beefd 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.h
@@ -32,6 +32,7 @@
   bool IsNull() const { return !fragment; }
 
   Position ToPositionInDOMTree() const;
+  PositionWithAffinity ToPositionInDOMTreeWithAffinity() const;
 
   const NGPaintFragment* fragment = nullptr;  // owned by root LayoutNGMixin
   NGCaretPositionType position_type;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
index c505a88..39ab24ad 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
@@ -4,9 +4,12 @@
 
 #include "third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h"
 
+#include "third_party/blink/renderer/core/html/html_dialog_element.h"
+#include "third_party/blink/renderer/core/layout/layout_object.h"
 #include "third_party/blink/renderer/core/layout/ng/geometry/ng_static_position.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
+#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
 #include "third_party/blink/renderer/core/style/computed_style.h"
 #include "third_party/blink/renderer/platform/length_functions.h"
 
@@ -495,6 +498,50 @@
     return AbsoluteVerticalNeedsEstimate(style);
 }
 
+base::Optional<LayoutUnit> ComputeAbsoluteDialogYPosition(
+    const LayoutObject& dialog,
+    LayoutUnit height) {
+  if (!IsHTMLDialogElement(dialog.GetNode()))
+    return base::nullopt;
+
+  // This code implements <dialog> static position spec.
+  // //
+  // https://html.spec.whatwg.org/multipage/interactive-elements.html#the-dialog-element
+  HTMLDialogElement* dialog_node = ToHTMLDialogElement(dialog.GetNode());
+  if (dialog_node->GetCenteringMode() == HTMLDialogElement::kNotCentered)
+    return base::nullopt;
+
+  bool can_center_dialog =
+      (dialog.Style()->GetPosition() == EPosition::kAbsolute ||
+       dialog.Style()->GetPosition() == EPosition::kFixed) &&
+      dialog.Style()->HasAutoTopAndBottom();
+
+  if (dialog_node->GetCenteringMode() == HTMLDialogElement::kCentered) {
+    if (can_center_dialog)
+      return dialog_node->CenteredPosition();
+    return base::nullopt;
+  }
+
+  DCHECK_EQ(dialog_node->GetCenteringMode(),
+            HTMLDialogElement::kNeedsCentering);
+  if (!can_center_dialog) {
+    dialog_node->SetNotCentered();
+    return base::nullopt;
+  }
+
+  auto* scrollable_area = dialog.GetDocument().View()->LayoutViewport();
+  LayoutUnit top =
+      LayoutUnit((dialog.Style()->GetPosition() == EPosition::kFixed)
+                     ? 0
+                     : scrollable_area->ScrollOffsetInt().Height());
+
+  int visible_height = dialog.GetDocument().View()->Height();
+  if (height < visible_height)
+    top += (visible_height - height) / 2;
+  dialog_node->SetCentered(top);
+  return top;
+}
+
 NGAbsolutePhysicalPosition ComputePartialAbsoluteWithChildInlineSize(
     const NGConstraintSpace& space,
     const ComputedStyle& style,
diff --git a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h
index ede1012..2401a51 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h
@@ -15,6 +15,7 @@
 namespace blink {
 
 class ComputedStyle;
+class LayoutObject;
 class NGConstraintSpace;
 struct NGStaticPosition;
 
@@ -24,6 +25,13 @@
   String ToString() const;
 };
 
+// Implements <dialog> special case abspos static positining.
+// Returns new dialog top position if layout_dialog requires
+// <dialog> abspos centering.
+CORE_EXPORT base::Optional<LayoutUnit> ComputeAbsoluteDialogYPosition(
+    const LayoutObject& layout_dialog,
+    LayoutUnit height);
+
 // The following routines implement absolute size resolution algorithm.
 // https://www.w3.org/TR/css-position-3/#abs-non-replaced-width
 //
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
index f984494..652d49e 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -4,8 +4,6 @@
 
 #include "third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h"
 
-#include "third_party/blink/renderer/core/html/html_dialog_element.h"
-#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
 #include "third_party/blink/renderer/core/layout/layout_object.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h"
@@ -379,18 +377,14 @@
       container_info.default_container_offset.inline_offset;
   offset->block_offset += container_info.default_container_offset.block_offset;
 
-  LayoutObject* layout_object = descendant.node.GetLayoutObject();
-  if (IsHTMLDialogElement(layout_object->GetNode())) {
-    base::Optional<LayoutUnit> y =
-        ToLayoutBlockFlow(layout_object)
-            ->ComputeDialogYPosition(
-                layout_result->PhysicalFragment()->Size().height);
-    if (y.has_value()) {
-      if (IsHorizontalWritingMode(container_writing_mode))
-        offset->block_offset = y.value();
-      else
-        offset->inline_offset = y.value();
-    }
+  base::Optional<LayoutUnit> y = ComputeAbsoluteDialogYPosition(
+      *descendant.node.GetLayoutObject(),
+      layout_result->PhysicalFragment()->Size().height);
+  if (y.has_value()) {
+    if (IsHorizontalWritingMode(container_writing_mode))
+      offset->block_offset = y.value();
+    else
+      offset->inline_offset = y.value();
   }
 
   return layout_result;
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context.cc b/third_party/blink/renderer/core/loader/base_fetch_context.cc
index ab749f8..5c6540d 100644
--- a/third_party/blink/renderer/core/loader/base_fetch_context.cc
+++ b/third_party/blink/renderer/core/loader/base_fetch_context.cc
@@ -40,7 +40,7 @@
     case WebURLRequest::kRequestContextXMLHttpRequest:
     case WebURLRequest::kRequestContextSubresource:
     case WebURLRequest::kRequestContextPrefetch:
-      return "\"\"";
+      return "";
     case WebURLRequest::kRequestContextCSPReport:
       return "report";
     case WebURLRequest::kRequestContextAudio:
@@ -131,9 +131,9 @@
         }
       }
 
-      String value =
-          String::Format("destination=%s, target=subresource, site=%s",
-                         destination_value, site_value);
+      String value = String::Format(
+          "destination=\"%s\", target=\"subresource\", site=\"%s\"",
+          destination_value, site_value);
       request.AddHTTPHeaderField("Sec-Metadata", AtomicString(value));
     }
   }
diff --git a/third_party/blink/renderer/core/page/create_window.cc b/third_party/blink/renderer/core/page/create_window.cc
index e025372..475a2ac 100644
--- a/third_party/blink/renderer/core/page/create_window.cc
+++ b/third_party/blink/renderer/core/page/create_window.cc
@@ -337,9 +337,7 @@
       opener_frame.GetDocument()->GetContentSecurityPolicy() &&
       !ContentSecurityPolicy::ShouldBypassMainWorld(
           opener_frame.GetDocument())) {
-    const int kJavascriptSchemeLength = sizeof("javascript:") - 1;
-    String script_source = DecodeURLEscapeSequences(completed_url.GetString())
-                               .Substring(kJavascriptSchemeLength);
+    String script_source = DecodeURLEscapeSequences(completed_url.GetString());
 
     if (!opener_frame.GetDocument()
              ->GetContentSecurityPolicy()
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 0818a677..3e93708 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
@@ -72,6 +72,14 @@
          LayoutSize(parent_inline_offset.X(), parent_inline_offset.Y());
 }
 
+bool FragmentVisibleToHitTestRequest(const NGPaintFragment& fragment,
+                                     const HitTestRequest& request) {
+  return fragment.Style().Visibility() == EVisibility::kVisible &&
+         (request.IgnorePointerEventsNone() ||
+          fragment.Style().PointerEvents() != EPointerEvents::kNone) &&
+         !(fragment.GetNode() && fragment.GetNode()->IsInert());
+}
+
 }  // anonymous namespace
 
 NGBoxFragmentPainter::NGBoxFragmentPainter(const NGPaintFragment& box)
@@ -900,10 +908,7 @@
 
 bool NGBoxFragmentPainter::VisibleToHitTestRequest(
     const HitTestRequest& request) const {
-  return box_fragment_.Style().Visibility() == EVisibility::kVisible &&
-         (request.IgnorePointerEventsNone() ||
-          box_fragment_.Style().PointerEvents() != EPointerEvents::kNone) &&
-         !(box_fragment_.GetNode() && box_fragment_.GetNode()->IsInert());
+  return FragmentVisibleToHitTestRequest(box_fragment_, request);
 }
 
 bool NGBoxFragmentPainter::HitTestTextFragment(
@@ -930,7 +935,8 @@
 
   // TODO(layout-dev): Clip to line-top/bottom.
   LayoutRect rect = LayoutRect(PixelSnappedIntRect(border_rect));
-  if (VisibleToHitTestRequest(result.GetHitTestRequest()) &&
+  if (FragmentVisibleToHitTestRequest(text_paint_fragment,
+                                      result.GetHitTestRequest()) &&
       location_in_container.Intersects(rect)) {
     Node* node = text_paint_fragment.NodeForHitTest();
     if (!result.InnerNode() && node) {
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 82797f4..052bcb99 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
@@ -439,16 +439,12 @@
       text_offset < text_fragment.EndOffset()) {
     const Position position = NGOffsetMapping::GetFor(GetLayoutObject())
                                   ->GetFirstPosition(text_offset);
-    // TODO(xiaochengh): Adjust TextAffinity.
     return PositionWithAffinity(position, TextAffinity::kDownstream);
   }
   const NGCaretPosition unadjusted_position{
       this, NGCaretPositionType::kAtTextOffset, text_offset};
-  const Position adjusted_position =
-      BidiAdjustment::AdjustForHitTest(unadjusted_position)
-          .ToPositionInDOMTree();
-  // TODO(xiaochengh): Adjust TextAffinity.
-  return PositionWithAffinity(adjusted_position, TextAffinity::kDownstream);
+  return BidiAdjustment::AdjustForHitTest(unadjusted_position)
+      .ToPositionInDOMTreeWithAffinity();
 }
 
 PositionWithAffinity NGPaintFragment::PositionForPointInInlineLevelBox(
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index 1484abd..7cd6863 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -44,6 +44,7 @@
 
 #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
 
+#include "base/numerics/checked_math.h"
 #include "base/single_thread_task_runner.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/task_type.h"
@@ -94,7 +95,6 @@
 #include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
 #include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
 #include "third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/style/counter_directives.h b/third_party/blink/renderer/core/style/counter_directives.h
index 8e08412..8f62ffa0 100644
--- a/third_party/blink/renderer/core/style/counter_directives.h
+++ b/third_party/blink/renderer/core/style/counter_directives.h
@@ -29,8 +29,8 @@
 
 #include "base/memory/ptr_util.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/numerics/checked_math.h"
 #include "third_party/blink/renderer/platform/wtf/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 #include "third_party/blink/renderer/platform/wtf/math_extras.h"
 #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
@@ -89,7 +89,7 @@
     // According to the spec, if an increment would overflow or underflow the
     // counter, we are allowed to ignore the increment.
     // https://drafts.csswg.org/css-lists-3/#valdef-counter-reset-custom-ident-integer
-    return WTF::CheckAdd(reset_value_, increment_value_)
+    return base::CheckAdd(reset_value_, increment_value_)
         .ValueOrDefault(reset_value_);
   }
 
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc b/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc
index 23070b7..ab73dab 100644
--- a/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc
+++ b/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc
@@ -4,9 +4,9 @@
 
 #include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h"
 
+#include "base/numerics/checked_math.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h"
 #include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_view.h"
 
 namespace blink {
@@ -18,7 +18,7 @@
   static scoped_refptr<DataView> Create(ArrayBuffer* buffer,
                                         unsigned byte_offset,
                                         unsigned byte_length) {
-    CheckedNumeric<uint32_t> checked_max = byte_offset;
+    base::CheckedNumeric<uint32_t> checked_max = byte_offset;
     checked_max += byte_length;
     CHECK_LE(checked_max.ValueOrDie(), buffer->ByteLength());
     return base::AdoptRef(new DataView(buffer, byte_offset, byte_length));
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
index 14dc658..8718795a 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h"
 
+#include "base/numerics/checked_math.h"
 #include "third_party/blink/renderer/core/css/cssom/css_url_image_value.h"
 #include "third_party/blink/renderer/core/css/parser/css_parser.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -31,7 +32,6 @@
 #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
 #include "third_party/blink/renderer/platform/graphics/stroke_data.h"
 #include "third_party/blink/renderer/platform/histogram.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/math_extras.h"
 
 namespace blink {
@@ -1608,7 +1608,7 @@
     int sw,
     int sh,
     ExceptionState& exception_state) {
-  if (!WTF::CheckMul(sw, sh).IsValid<int>()) {
+  if (!base::CheckMul(sw, sh).IsValid<int>()) {
     exception_state.ThrowRangeError("Out of memory at ImageData creation");
     return nullptr;
   }
@@ -1628,7 +1628,7 @@
     return nullptr;
 
   if (sw < 0) {
-    if (!WTF::CheckAdd(sx, sw).IsValid<int>()) {
+    if (!base::CheckAdd(sx, sw).IsValid<int>()) {
       exception_state.ThrowRangeError("Out of memory at ImageData creation");
       return nullptr;
     }
@@ -1636,7 +1636,7 @@
     sw = -sw;
   }
   if (sh < 0) {
-    if (!WTF::CheckAdd(sy, sh).IsValid<int>()) {
+    if (!base::CheckAdd(sy, sh).IsValid<int>()) {
       exception_state.ThrowRangeError("Out of memory at ImageData creation");
       return nullptr;
     }
@@ -1644,8 +1644,8 @@
     sh = -sh;
   }
 
-  if (!WTF::CheckAdd(sx, sw).IsValid<int>() ||
-      !WTF::CheckAdd(sy, sh).IsValid<int>()) {
+  if (!base::CheckAdd(sx, sw).IsValid<int>() ||
+      !base::CheckAdd(sy, sh).IsValid<int>()) {
     exception_state.ThrowRangeError("Out of memory at ImageData creation");
     return nullptr;
   }
@@ -1731,7 +1731,7 @@
                                           int dirty_width,
                                           int dirty_height,
                                           ExceptionState& exception_state) {
-  if (!WTF::CheckMul(dirty_width, dirty_height).IsValid<int>()) {
+  if (!base::CheckMul(dirty_width, dirty_height).IsValid<int>()) {
     return;
   }
   usage_counters_.num_put_image_data_calls++;
diff --git a/third_party/blink/renderer/modules/exported/BUILD.gn b/third_party/blink/renderer/modules/exported/BUILD.gn
index 686411e..e27cd8b 100644
--- a/third_party/blink/renderer/modules/exported/BUILD.gn
+++ b/third_party/blink/renderer/modules/exported/BUILD.gn
@@ -16,10 +16,6 @@
     "web_idb_key_range.cc",
     "web_idb_value.cc",
     "web_media_stream_registry.cc",
-    "web_speech_grammar.cc",
-    "web_speech_recognition_handle.cc",
-    "web_speech_recognition_result.cc",
-    "web_speech_recognizer_client.cc",
     "web_storage_event_dispatcher_impl.cc",
     "web_user_media_request.cc",
   ]
diff --git a/third_party/blink/renderer/modules/exported/web_speech_grammar.cc b/third_party/blink/renderer/modules/exported/web_speech_grammar.cc
deleted file mode 100644
index ef6e7dc..0000000
--- a/third_party/blink/renderer/modules/exported/web_speech_grammar.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/public/web/web_speech_grammar.h"
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/modules/speech/speech_grammar.h"
-
-namespace blink {
-
-void WebSpeechGrammar::Reset() {
-  private_.Reset();
-}
-
-void WebSpeechGrammar::Assign(const WebSpeechGrammar& other) {
-  private_ = other.private_;
-}
-
-WebSpeechGrammar& WebSpeechGrammar::operator=(SpeechGrammar* value) {
-  private_ = value;
-  return *this;
-}
-
-WebURL WebSpeechGrammar::Src() const {
-  DCHECK(private_.Get());
-  return private_->src();
-}
-
-float WebSpeechGrammar::Weight() const {
-  DCHECK(private_.Get());
-  return private_->weight();
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/modules/exported/web_speech_recognition_handle.cc b/third_party/blink/renderer/modules/exported/web_speech_recognition_handle.cc
deleted file mode 100644
index 1278205b9..0000000
--- a/third_party/blink/renderer/modules/exported/web_speech_recognition_handle.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/public/web/web_speech_recognition_handle.h"
-
-#include "third_party/blink/renderer/modules/speech/speech_recognition.h"
-
-namespace blink {
-
-void WebSpeechRecognitionHandle::Reset() {
-  private_.Reset();
-}
-
-void WebSpeechRecognitionHandle::Assign(
-    const WebSpeechRecognitionHandle& other) {
-  private_ = other.private_;
-}
-
-bool WebSpeechRecognitionHandle::Equals(
-    const WebSpeechRecognitionHandle& other) const {
-  return private_.Get() == other.private_.Get();
-}
-
-bool WebSpeechRecognitionHandle::LessThan(
-    const WebSpeechRecognitionHandle& other) const {
-  return private_.Get() < other.private_.Get();
-}
-
-WebSpeechRecognitionHandle::WebSpeechRecognitionHandle(
-    SpeechRecognition* speech_recognition)
-    : private_(speech_recognition) {}
-
-WebSpeechRecognitionHandle::operator SpeechRecognition*() const {
-  return private_.Get();
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/modules/exported/web_speech_recognition_result.cc b/third_party/blink/renderer/modules/exported/web_speech_recognition_result.cc
deleted file mode 100644
index d259120..0000000
--- a/third_party/blink/renderer/modules/exported/web_speech_recognition_result.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/public/web/web_speech_recognition_result.h"
-
-#include "third_party/blink/renderer/modules/speech/speech_recognition_alternative.h"
-#include "third_party/blink/renderer/modules/speech/speech_recognition_result.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-namespace blink {
-
-void WebSpeechRecognitionResult::Assign(
-    const WebSpeechRecognitionResult& other) {
-  private_ = other.private_;
-}
-
-void WebSpeechRecognitionResult::Assign(const WebVector<WebString>& transcripts,
-                                        const WebVector<float>& confidences,
-                                        bool final) {
-  DCHECK_EQ(transcripts.size(), confidences.size());
-
-  HeapVector<Member<SpeechRecognitionAlternative>> alternatives(
-      transcripts.size());
-  for (size_t i = 0; i < transcripts.size(); ++i) {
-    alternatives[i] =
-        SpeechRecognitionAlternative::Create(transcripts[i], confidences[i]);
-  }
-
-  private_ = SpeechRecognitionResult::Create(alternatives, final);
-}
-
-void WebSpeechRecognitionResult::Reset() {
-  private_.Reset();
-}
-
-WebSpeechRecognitionResult::operator SpeechRecognitionResult*() const {
-  return private_.Get();
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/modules/exported/web_speech_recognizer_client.cc b/third_party/blink/renderer/modules/exported/web_speech_recognizer_client.cc
deleted file mode 100644
index 8aa1aebe..0000000
--- a/third_party/blink/renderer/modules/exported/web_speech_recognizer_client.cc
+++ /dev/null
@@ -1,98 +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 "third_party/blink/public/web/web_speech_recognizer_client.h"
-
-#include "third_party/blink/public/web/web_speech_recognition_handle.h"
-#include "third_party/blink/renderer/modules/speech/speech_recognition_client_proxy.h"
-
-namespace blink {
-
-WebSpeechRecognizerClient::WebSpeechRecognizerClient(
-    SpeechRecognitionClientProxy* proxy)
-    : private_(proxy) {}
-
-WebSpeechRecognizerClient::~WebSpeechRecognizerClient() {
-  Reset();
-}
-
-bool WebSpeechRecognizerClient::operator==(
-    const WebSpeechRecognizerClient& other) const {
-  return private_.Get() == other.private_.Get();
-}
-
-bool WebSpeechRecognizerClient::operator!=(
-    const WebSpeechRecognizerClient& other) const {
-  return !operator==(other);
-}
-
-void WebSpeechRecognizerClient::Reset() {
-  private_.Reset();
-}
-
-void WebSpeechRecognizerClient::Assign(const WebSpeechRecognizerClient& other) {
-  private_ = other.private_;
-}
-
-void WebSpeechRecognizerClient::DidStartAudio(
-    const WebSpeechRecognitionHandle& handle) {
-  DCHECK(!private_.IsNull());
-  private_->DidStartAudio(handle);
-}
-
-void WebSpeechRecognizerClient::DidStartSound(
-    const WebSpeechRecognitionHandle& handle) {
-  DCHECK(!private_.IsNull());
-  private_->DidStartSound(handle);
-}
-
-void WebSpeechRecognizerClient::DidEndSound(
-    const WebSpeechRecognitionHandle& handle) {
-  DCHECK(!private_.IsNull());
-  private_->DidEndSound(handle);
-}
-
-void WebSpeechRecognizerClient::DidEndAudio(
-    const WebSpeechRecognitionHandle& handle) {
-  DCHECK(!private_.IsNull());
-  private_->DidEndAudio(handle);
-}
-
-void WebSpeechRecognizerClient::DidReceiveResults(
-    const WebSpeechRecognitionHandle& handle,
-    const WebVector<WebSpeechRecognitionResult>& new_final_results,
-    const WebVector<WebSpeechRecognitionResult>& current_interim_results) {
-  DCHECK(!private_.IsNull());
-  private_->DidReceiveResults(handle, new_final_results,
-                              current_interim_results);
-}
-
-void WebSpeechRecognizerClient::DidReceiveNoMatch(
-    const WebSpeechRecognitionHandle& handle,
-    const WebSpeechRecognitionResult& result) {
-  DCHECK(!private_.IsNull());
-  private_->DidReceiveNoMatch(handle, result);
-}
-
-void WebSpeechRecognizerClient::DidReceiveError(
-    const WebSpeechRecognitionHandle& handle,
-    const WebString& message,
-    ErrorCode error_code) {
-  DCHECK(!private_.IsNull());
-  private_->DidReceiveError(handle, message, error_code);
-}
-
-void WebSpeechRecognizerClient::DidStart(
-    const WebSpeechRecognitionHandle& handle) {
-  DCHECK(!private_.IsNull());
-  private_->DidStart(handle);
-}
-
-void WebSpeechRecognizerClient::DidEnd(
-    const WebSpeechRecognitionHandle& handle) {
-  DCHECK(!private_.IsNull());
-  private_->DidEnd(handle);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/modules/modules_initializer.cc b/third_party/blink/renderer/modules/modules_initializer.cc
index 108e1934..9938c954 100644
--- a/third_party/blink/renderer/modules/modules_initializer.cc
+++ b/third_party/blink/renderer/modules/modules_initializer.cc
@@ -72,7 +72,7 @@
 #include "third_party/blink/renderer/modules/remoteplayback/remote_playback.h"
 #include "third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h"
 #include "third_party/blink/renderer/modules/serviceworkers/navigator_service_worker.h"
-#include "third_party/blink/renderer/modules/speech/speech_recognition_client_proxy.h"
+#include "third_party/blink/renderer/modules/speech/speech_recognition_controller.h"
 #include "third_party/blink/renderer/modules/storage/dom_window_storage_controller.h"
 #include "third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h"
 #include "third_party/blink/renderer/modules/storage/storage_namespace_controller.h"
@@ -176,8 +176,7 @@
                                      new AudioOutputDeviceClientImpl(frame));
   }
   InstalledAppController::ProvideTo(frame, client->GetRelatedAppsFetcher());
-  ::blink::ProvideSpeechRecognitionTo(
-      frame, SpeechRecognitionClientProxy::Create(client->SpeechRecognizer()));
+  ::blink::ProvideSpeechRecognitionTo(frame);
 }
 
 void ModulesInitializer::ProvideLocalFileSystemToWorker(
diff --git a/third_party/blink/renderer/modules/shapedetection/shape_detector.cc b/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
index ddab89b0..d05cc4af 100644
--- a/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
+++ b/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/shapedetection/shape_detector.h"
 
+#include "base/numerics/checked_math.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -15,7 +16,6 @@
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
 #include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
 #include "third_party/blink/renderer/platform/graphics/image.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/core/SkImageInfo.h"
 
@@ -121,7 +121,7 @@
     return promise;
   }
 
-  WTF::CheckedNumeric<int> allocation_size = image_data->Size().Area() * 4;
+  base::CheckedNumeric<int> allocation_size = image_data->Size().Area() * 4;
   CHECK_EQ(allocation_size.ValueOrDefault(0), sk_bitmap.computeByteSize());
 
   memcpy(sk_bitmap.getPixels(), image_data->data()->Data(),
diff --git a/third_party/blink/renderer/modules/speech/BUILD.gn b/third_party/blink/renderer/modules/speech/BUILD.gn
index f9f8f4585..df1bbde 100644
--- a/third_party/blink/renderer/modules/speech/BUILD.gn
+++ b/third_party/blink/renderer/modules/speech/BUILD.gn
@@ -18,8 +18,6 @@
     "speech_recognition_alternative.cc",
     "speech_recognition_alternative.h",
     "speech_recognition_client.h",
-    "speech_recognition_client_proxy.cc",
-    "speech_recognition_client_proxy.h",
     "speech_recognition_controller.cc",
     "speech_recognition_controller.h",
     "speech_recognition_error.cc",
diff --git a/third_party/blink/renderer/modules/speech/DEPS b/third_party/blink/renderer/modules/speech/DEPS
index f26ccc26..04e6d62 100644
--- a/third_party/blink/renderer/modules/speech/DEPS
+++ b/third_party/blink/renderer/modules/speech/DEPS
@@ -5,4 +5,5 @@
     "+third_party/blink/renderer/modules/modules_export.h",
     "+third_party/blink/renderer/modules/mediastream",
     "+third_party/blink/renderer/modules/speech",
+    "+mojo/public/cpp/bindings/binding.h"
 ]
diff --git a/third_party/blink/renderer/modules/speech/speech_recognition.cc b/third_party/blink/renderer/modules/speech/speech_recognition.cc
index b9970e8..f6f32b4 100644
--- a/third_party/blink/renderer/modules/speech/speech_recognition.cc
+++ b/third_party/blink/renderer/modules/speech/speech_recognition.cc
@@ -25,6 +25,7 @@
 
 #include "third_party/blink/renderer/modules/speech/speech_recognition.h"
 
+#include "build/build_config.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/modules/speech/speech_recognition_controller.h"
@@ -53,7 +54,18 @@
   }
 
   final_results_.clear();
-  controller_->Start(this, grammars_, lang_, continuous_, interim_results_,
+
+  mojom::blink::SpeechRecognitionSessionClientPtrInfo session_client;
+  binding_.Bind(mojo::MakeRequest(&session_client),
+                GetExecutionContext()->GetInterfaceInvalidator());
+  binding_.set_connection_error_handler(WTF::Bind(
+      &SpeechRecognition::OnConnectionError, WrapWeakPersistent(this)));
+
+  mojom::blink::SpeechRecognitionSessionRequest session_request =
+      MakeRequest(&session_, GetExecutionContext()->GetInterfaceInvalidator());
+
+  controller_->Start(std::move(session_request), std::move(session_client),
+                     grammars_, lang_, continuous_, interim_results_,
                      max_alternatives_);
   started_ = true;
 }
@@ -64,7 +76,7 @@
 
   if (started_ && !stopping_) {
     stopping_ = true;
-    controller_->Stop(this);
+    session_->StopCapture();
   }
 }
 
@@ -74,70 +86,94 @@
 
   if (started_ && !stopping_) {
     stopping_ = true;
-    controller_->Abort(this);
+    session_->Abort();
   }
 }
 
-void SpeechRecognition::DidStartAudio() {
-  DispatchEvent(Event::Create(EventTypeNames::audiostart));
+void SpeechRecognition::ResultRetrieved(
+    WTF::Vector<mojom::blink::SpeechRecognitionResultPtr> results) {
+  auto* it = std::stable_partition(
+      results.begin(), results.end(),
+      [](const auto& result) { return !result->is_provisional; });
+  size_t provisional_count = results.end() - it;
+
+  // Add the new results to the previous final results.
+  HeapVector<Member<SpeechRecognitionResult>> aggregated_results =
+      std::move(final_results_);
+  aggregated_results.ReserveCapacity(aggregated_results.size() +
+                                     results.size());
+
+  for (const auto& result : results) {
+    HeapVector<Member<SpeechRecognitionAlternative>> alternatives;
+    alternatives.ReserveInitialCapacity(result->hypotheses.size());
+    for (const auto& hypothesis : result->hypotheses) {
+      alternatives.push_back(SpeechRecognitionAlternative::Create(
+          hypothesis->utterance, hypothesis->confidence));
+    }
+    aggregated_results.push_back(SpeechRecognitionResult::Create(
+        std::move(alternatives), !result->is_provisional));
+  }
+
+  // |aggregated_results| now contains the following (in the given order):
+  //
+  // (1) previous final results from |final_results_|
+  // (2) new final results from |results|
+  // (3) new provisional results from |results|
+
+  // |final_results_| = (1) + (2).
+  HeapVector<Member<SpeechRecognitionResult>> new_final_results;
+  new_final_results.ReserveInitialCapacity(aggregated_results.size() -
+                                           provisional_count);
+  new_final_results.AppendRange(aggregated_results.begin(),
+                                aggregated_results.end() - provisional_count);
+  final_results_ = std::move(new_final_results);
+
+  // We dispatch an event with (1) + (2) + (3).
+  DispatchEvent(SpeechRecognitionEvent::CreateResult(
+      aggregated_results.size() - results.size(),
+      std::move(aggregated_results)));
 }
 
-void SpeechRecognition::DidStartSound() {
-  DispatchEvent(Event::Create(EventTypeNames::soundstart));
+void SpeechRecognition::ErrorOccurred(
+    mojom::blink::SpeechRecognitionErrorPtr error) {
+  if (error->code == mojom::blink::SpeechRecognitionErrorCode::kNoMatch) {
+    DispatchEvent(SpeechRecognitionEvent::CreateNoMatch(nullptr));
+  } else {
+    SpeechRecognitionError::ErrorCode error_code =
+        static_cast<SpeechRecognitionError::ErrorCode>(error->code);
+    // TODO(primiano): message?
+    DispatchEvent(SpeechRecognitionError::Create(error_code, String()));
+  }
 }
 
-void SpeechRecognition::DidStartSpeech() {
-  DispatchEvent(Event::Create(EventTypeNames::speechstart));
-}
-
-void SpeechRecognition::DidEndSpeech() {
-  DispatchEvent(Event::Create(EventTypeNames::speechend));
-}
-
-void SpeechRecognition::DidEndSound() {
-  DispatchEvent(Event::Create(EventTypeNames::soundend));
-}
-
-void SpeechRecognition::DidEndAudio() {
-  DispatchEvent(Event::Create(EventTypeNames::audioend));
-}
-
-void SpeechRecognition::DidReceiveResults(
-    const HeapVector<Member<SpeechRecognitionResult>>& new_final_results,
-    const HeapVector<Member<SpeechRecognitionResult>>&
-        current_interim_results) {
-  size_t result_index = final_results_.size();
-
-  for (size_t i = 0; i < new_final_results.size(); ++i)
-    final_results_.push_back(new_final_results[i]);
-
-  HeapVector<Member<SpeechRecognitionResult>> results = final_results_;
-  for (size_t i = 0; i < current_interim_results.size(); ++i)
-    results.push_back(current_interim_results[i]);
-
-  DispatchEvent(SpeechRecognitionEvent::CreateResult(result_index, results));
-}
-
-void SpeechRecognition::DidReceiveNoMatch(SpeechRecognitionResult* result) {
-  DispatchEvent(SpeechRecognitionEvent::CreateNoMatch(result));
-}
-
-void SpeechRecognition::DidReceiveError(SpeechRecognitionError* error) {
-  DispatchEvent(error);
-  started_ = false;
-}
-
-void SpeechRecognition::DidStart() {
+void SpeechRecognition::Started() {
   DispatchEvent(Event::Create(EventTypeNames::start));
 }
 
-void SpeechRecognition::DidEnd() {
+void SpeechRecognition::AudioStarted() {
+  DispatchEvent(Event::Create(EventTypeNames::audiostart));
+}
+
+void SpeechRecognition::SoundStarted() {
+  DispatchEvent(Event::Create(EventTypeNames::soundstart));
+  DispatchEvent(Event::Create(EventTypeNames::speechstart));
+}
+
+void SpeechRecognition::SoundEnded() {
+  DispatchEvent(Event::Create(EventTypeNames::speechend));
+  DispatchEvent(Event::Create(EventTypeNames::soundend));
+}
+
+void SpeechRecognition::AudioEnded() {
+  DispatchEvent(Event::Create(EventTypeNames::audioend));
+}
+
+void SpeechRecognition::Ended() {
   started_ = false;
   stopping_ = false;
-  // If m_controller is null, this is being aborted from the ExecutionContext
-  // being detached, so don't dispatch an event.
-  if (controller_)
-    DispatchEvent(Event::Create(EventTypeNames::end));
+  session_.reset();
+  binding_.Close();
+  DispatchEvent(Event::Create(EventTypeNames::end));
 }
 
 const AtomicString& SpeechRecognition::InterfaceName() const {
@@ -150,17 +186,30 @@
 
 void SpeechRecognition::ContextDestroyed(ExecutionContext*) {
   controller_ = nullptr;
-  if (HasPendingActivity())
-    abort();
 }
 
 bool SpeechRecognition::HasPendingActivity() const {
   return started_;
 }
 
+void SpeechRecognition::PageVisibilityChanged() {
+#if defined(OS_ANDROID)
+  if (!GetPage()->IsPageVisible())
+    abort();
+#endif
+}
+
+void SpeechRecognition::OnConnectionError() {
+  ErrorOccurred(mojom::blink::SpeechRecognitionError::New(
+      mojom::blink::SpeechRecognitionErrorCode::kNetwork,
+      mojom::blink::SpeechAudioErrorDetails::kNone));
+  Ended();
+}
+
 SpeechRecognition::SpeechRecognition(LocalFrame* frame,
                                      ExecutionContext* context)
     : ContextLifecycleObserver(context),
+      PageVisibilityObserver(frame ? frame->GetPage() : nullptr),
       grammars_(SpeechGrammarList::Create()),  // FIXME: The spec is not clear
                                                // on the default value for the
                                                // grammars attribute.
@@ -169,7 +218,8 @@
       max_alternatives_(1),
       controller_(SpeechRecognitionController::From(frame)),
       started_(false),
-      stopping_(false) {
+      stopping_(false),
+      binding_(this) {
   // FIXME: Need to hook up to get notified when the visibility changes.
 }
 
@@ -181,6 +231,7 @@
   visitor->Trace(final_results_);
   EventTargetWithInlineData::Trace(visitor);
   ContextLifecycleObserver::Trace(visitor);
+  PageVisibilityObserver::Trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/speech/speech_recognition.h b/third_party/blink/renderer/modules/speech/speech_recognition.h
index da7aafd..b4e08c6 100644
--- a/third_party/blink/renderer/modules/speech/speech_recognition.h
+++ b/third_party/blink/renderer/modules/speech/speech_recognition.h
@@ -26,14 +26,17 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_H_
 
+#include "third_party/blink/public/mojom/speech/speech_recognizer.mojom-blink.h"
 #include "third_party/blink/public/platform/web_private_ptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/page/page_visibility_observer.h"
 #include "third_party/blink/renderer/modules/event_target_modules.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/modules/speech/speech_grammar_list.h"
 #include "third_party/blink/renderer/modules/speech/speech_recognition_result.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/mojo/revocable_binding.h"
 #include "third_party/blink/renderer/platform/wtf/compiler.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
@@ -43,12 +46,13 @@
 class ExecutionContext;
 class LocalFrame;
 class SpeechRecognitionController;
-class SpeechRecognitionError;
 
 class MODULES_EXPORT SpeechRecognition final
     : public EventTargetWithInlineData,
       public ActiveScriptWrappable<SpeechRecognition>,
-      public ContextLifecycleObserver {
+      public ContextLifecycleObserver,
+      public mojom::blink::SpeechRecognitionSessionClient,
+      public PageVisibilityObserver {
   USING_GARBAGE_COLLECTED_MIXIN(SpeechRecognition);
   DEFINE_WRAPPERTYPEINFO();
 
@@ -78,21 +82,16 @@
   void stopFunction();
   void abort();
 
-  // Called by the SpeechRecognitionClient.
-  void DidStartAudio();
-  void DidStartSound();
-  void DidStartSpeech();
-  void DidEndSpeech();
-  void DidEndSound();
-  void DidEndAudio();
-  void DidReceiveResults(
-      const HeapVector<Member<SpeechRecognitionResult>>& new_final_results,
-      const HeapVector<Member<SpeechRecognitionResult>>&
-          current_interim_results);
-  void DidReceiveNoMatch(SpeechRecognitionResult*);
-  void DidReceiveError(SpeechRecognitionError*);
-  void DidStart();
-  void DidEnd();
+  // mojom::blink::SpeechRecognitionSessionClient
+  void ResultRetrieved(
+      WTF::Vector<mojom::blink::SpeechRecognitionResultPtr> results) override;
+  void ErrorOccurred(mojom::blink::SpeechRecognitionErrorPtr error) override;
+  void Started() override;
+  void AudioStarted() override;
+  void SoundStarted() override;
+  void SoundEnded() override;
+  void AudioEnded() override;
+  void Ended() override;
 
   // EventTarget
   const AtomicString& InterfaceName() const override;
@@ -104,6 +103,9 @@
   // ContextLifecycleObserver
   void ContextDestroyed(ExecutionContext*) override;
 
+  // PageVisibilityObserver
+  void PageVisibilityChanged() override;
+
   DEFINE_ATTRIBUTE_EVENT_LISTENER(audiostart);
   DEFINE_ATTRIBUTE_EVENT_LISTENER(soundstart);
   DEFINE_ATTRIBUTE_EVENT_LISTENER(speechstart);
@@ -121,6 +123,8 @@
  private:
   SpeechRecognition(LocalFrame*, ExecutionContext*);
 
+  void OnConnectionError();
+
   Member<SpeechGrammarList> grammars_;
   String lang_;
   bool continuous_;
@@ -131,6 +135,8 @@
   bool started_;
   bool stopping_;
   HeapVector<Member<SpeechRecognitionResult>> final_results_;
+  RevocableBinding<mojom::blink::SpeechRecognitionSessionClient> binding_;
+  mojom::blink::RevocableSpeechRecognitionSessionPtr session_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/speech/speech_recognition_client.h b/third_party/blink/renderer/modules/speech/speech_recognition_client.h
deleted file mode 100644
index eda5bfc8..0000000
--- a/third_party/blink/renderer/modules/speech/speech_recognition_client.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_CLIENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_CLIENT_H_
-
-#include <memory>
-
-#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-class LocalFrame;
-class SpeechGrammarList;
-class SpeechRecognition;
-
-class SpeechRecognitionClient
-    : public GarbageCollectedFinalized<SpeechRecognitionClient> {
- public:
-  virtual void Start(SpeechRecognition*,
-                     const SpeechGrammarList*,
-                     const String& lang,
-                     bool continuous,
-                     bool interim_results,
-                     unsigned long max_alternatives) = 0;
-  virtual void Stop(SpeechRecognition*) = 0;
-  virtual void Abort(SpeechRecognition*) = 0;
-  virtual void Trace(blink::Visitor*) {}
-
-  virtual ~SpeechRecognitionClient() = default;
-};
-
-MODULES_EXPORT void ProvideSpeechRecognitionTo(LocalFrame&,
-                                               SpeechRecognitionClient*);
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_CLIENT_H_
diff --git a/third_party/blink/renderer/modules/speech/speech_recognition_client_proxy.cc b/third_party/blink/renderer/modules/speech/speech_recognition_client_proxy.cc
deleted file mode 100644
index b92e32a..0000000
--- a/third_party/blink/renderer/modules/speech/speech_recognition_client_proxy.cc
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/modules/speech/speech_recognition_client_proxy.h"
-
-#include <memory>
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/web_security_origin.h"
-#include "third_party/blink/public/web/web_speech_grammar.h"
-#include "third_party/blink/public/web/web_speech_recognition_handle.h"
-#include "third_party/blink/public/web/web_speech_recognition_params.h"
-#include "third_party/blink/public/web/web_speech_recognition_result.h"
-#include "third_party/blink/public/web/web_speech_recognizer.h"
-#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/modules/speech/speech_grammar_list.h"
-#include "third_party/blink/renderer/modules/speech/speech_recognition.h"
-#include "third_party/blink/renderer/modules/speech/speech_recognition_error.h"
-#include "third_party/blink/renderer/modules/speech/speech_recognition_result.h"
-#include "third_party/blink/renderer/modules/speech/speech_recognition_result_list.h"
-#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
-
-namespace blink {
-
-SpeechRecognitionClientProxy::~SpeechRecognitionClientProxy() = default;
-
-SpeechRecognitionClientProxy* SpeechRecognitionClientProxy::Create(
-    WebSpeechRecognizer* recognizer) {
-  return new SpeechRecognitionClientProxy(recognizer);
-}
-
-void SpeechRecognitionClientProxy::Start(SpeechRecognition* recognition,
-                                         const SpeechGrammarList* grammar_list,
-                                         const String& lang,
-                                         bool continuous,
-                                         bool interim_results,
-                                         unsigned long max_alternatives) {
-  size_t length =
-      grammar_list ? static_cast<size_t>(grammar_list->length()) : 0U;
-  WebVector<WebSpeechGrammar> web_speech_grammars(length);
-  for (unsigned long i = 0; i < length; ++i)
-    web_speech_grammars[i] = grammar_list->item(i);
-
-  WebSpeechRecognitionParams params(
-      web_speech_grammars, lang, continuous, interim_results, max_alternatives,
-      WebSecurityOrigin(
-          recognition->GetExecutionContext()->GetSecurityOrigin()));
-  recognizer_->Start(recognition, params, WebSpeechRecognizerClient(this));
-}
-
-void SpeechRecognitionClientProxy::Stop(SpeechRecognition* recognition) {
-  recognizer_->Stop(recognition, WebSpeechRecognizerClient(this));
-}
-
-void SpeechRecognitionClientProxy::Abort(SpeechRecognition* recognition) {
-  recognizer_->Abort(recognition, WebSpeechRecognizerClient(this));
-}
-
-void SpeechRecognitionClientProxy::DidStartAudio(
-    const WebSpeechRecognitionHandle& handle) {
-  SpeechRecognition* recognition(handle);
-  recognition->DidStartAudio();
-}
-
-void SpeechRecognitionClientProxy::DidStartSound(
-    const WebSpeechRecognitionHandle& handle) {
-  SpeechRecognition* recognition(handle);
-  recognition->DidStartSound();
-  recognition->DidStartSpeech();
-}
-
-void SpeechRecognitionClientProxy::DidEndSound(
-    const WebSpeechRecognitionHandle& handle) {
-  SpeechRecognition* recognition(handle);
-  recognition->DidEndSpeech();
-  recognition->DidEndSound();
-}
-
-void SpeechRecognitionClientProxy::DidEndAudio(
-    const WebSpeechRecognitionHandle& handle) {
-  SpeechRecognition* recognition(handle);
-  recognition->DidEndAudio();
-}
-
-void SpeechRecognitionClientProxy::DidReceiveResults(
-    const WebSpeechRecognitionHandle& handle,
-    const WebVector<WebSpeechRecognitionResult>& new_final_results,
-    const WebVector<WebSpeechRecognitionResult>& current_interim_results) {
-  SpeechRecognition* recognition(handle);
-
-  HeapVector<Member<SpeechRecognitionResult>> final_results_vector(
-      new_final_results.size());
-  for (size_t i = 0; i < new_final_results.size(); ++i) {
-    final_results_vector[i] =
-        Member<SpeechRecognitionResult>(new_final_results[i]);
-  }
-
-  HeapVector<Member<SpeechRecognitionResult>> interim_results_vector(
-      current_interim_results.size());
-  for (size_t i = 0; i < current_interim_results.size(); ++i) {
-    interim_results_vector[i] =
-        Member<SpeechRecognitionResult>(current_interim_results[i]);
-  }
-
-  recognition->DidReceiveResults(final_results_vector, interim_results_vector);
-}
-
-void SpeechRecognitionClientProxy::DidReceiveNoMatch(
-    const WebSpeechRecognitionHandle& handle,
-    const WebSpeechRecognitionResult& result) {
-  SpeechRecognition* recognition(handle);
-  recognition->DidReceiveNoMatch(result);
-}
-
-void SpeechRecognitionClientProxy::DidReceiveError(
-    const WebSpeechRecognitionHandle& handle,
-    const WebString& message,
-    WebSpeechRecognizerClient::ErrorCode code) {
-  SpeechRecognition* recognition(handle);
-  SpeechRecognitionError::ErrorCode error_code =
-      static_cast<SpeechRecognitionError::ErrorCode>(code);
-  recognition->DidReceiveError(
-      SpeechRecognitionError::Create(error_code, message));
-}
-
-void SpeechRecognitionClientProxy::DidStart(
-    const WebSpeechRecognitionHandle& handle) {
-  SpeechRecognition* recognition(handle);
-  recognition->DidStart();
-}
-
-void SpeechRecognitionClientProxy::DidEnd(
-    const WebSpeechRecognitionHandle& handle) {
-  SpeechRecognition* recognition(handle);
-  recognition->DidEnd();
-}
-
-void SpeechRecognitionClientProxy::Trace(blink::Visitor* visitor) {
-  SpeechRecognitionClient::Trace(visitor);
-}
-
-SpeechRecognitionClientProxy::SpeechRecognitionClientProxy(
-    WebSpeechRecognizer* recognizer)
-    : recognizer_(recognizer) {}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/modules/speech/speech_recognition_client_proxy.h b/third_party/blink/renderer/modules/speech/speech_recognition_client_proxy.h
deleted file mode 100644
index 1fee3a4..0000000
--- a/third_party/blink/renderer/modules/speech/speech_recognition_client_proxy.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_CLIENT_PROXY_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_CLIENT_PROXY_H_
-
-#include <memory>
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/public/web/web_speech_recognizer_client.h"
-#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/speech/speech_recognition_client.h"
-#include "third_party/blink/renderer/platform/wtf/compiler.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-class WebSpeechRecognitionHandle;
-class WebSpeechRecognitionResult;
-class WebSpeechRecognizer;
-class WebString;
-
-class MODULES_EXPORT SpeechRecognitionClientProxy final
-    : public SpeechRecognitionClient {
- public:
-  ~SpeechRecognitionClientProxy() override;
-
-  // Constructing a proxy object with a null WebSpeechRecognizer is safe in
-  // itself, but attempting to call start/stop/abort on it will crash.
-  static SpeechRecognitionClientProxy* Create(WebSpeechRecognizer*);
-
-  // SpeechRecognitionClient:
-  void Start(SpeechRecognition*,
-             const SpeechGrammarList*,
-             const String& lang,
-             bool continuous,
-             bool interim_results,
-             unsigned long max_alternatives) override;
-  void Stop(SpeechRecognition*) override;
-  void Abort(SpeechRecognition*) override;
-
-  void DidStartAudio(const WebSpeechRecognitionHandle&);
-  void DidStartSound(const WebSpeechRecognitionHandle&);
-  void DidEndSound(const WebSpeechRecognitionHandle&);
-  void DidEndAudio(const WebSpeechRecognitionHandle&);
-  void DidReceiveResults(
-      const WebSpeechRecognitionHandle&,
-      const WebVector<WebSpeechRecognitionResult>& new_final_results,
-      const WebVector<WebSpeechRecognitionResult>& current_interim_results);
-  void DidReceiveNoMatch(const WebSpeechRecognitionHandle&,
-                         const WebSpeechRecognitionResult&);
-  void DidReceiveError(const WebSpeechRecognitionHandle&,
-                       const WebString& message,
-                       WebSpeechRecognizerClient::ErrorCode);
-  void DidStart(const WebSpeechRecognitionHandle&);
-  void DidEnd(const WebSpeechRecognitionHandle&);
-
-  // Required by garbage collection
-  void Trace(blink::Visitor* visitor) override;
-
- private:
-  explicit SpeechRecognitionClientProxy(WebSpeechRecognizer*);
-
-  WebSpeechRecognizer* recognizer_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_CLIENT_PROXY_H_
diff --git a/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc b/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc
index bd7656e..6bef1f0 100644
--- a/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc
+++ b/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc
@@ -27,28 +27,65 @@
 
 #include <memory>
 
+#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/renderer/modules/speech/speech_grammar_list.h"
+#include "third_party/blink/renderer/modules/speech/speech_recognition.h"
+
 namespace blink {
 
 const char SpeechRecognitionController::kSupplementName[] =
     "SpeechRecognitionController";
 
-SpeechRecognitionController::SpeechRecognitionController(
-    SpeechRecognitionClient* client)
-    : client_(client) {}
+SpeechRecognitionController::SpeechRecognitionController(LocalFrame& frame)
+    : Supplement<LocalFrame>(frame) {}
 
 SpeechRecognitionController::~SpeechRecognitionController() {
   // FIXME: Call m_client->pageDestroyed(); once we have implemented a client.
 }
 
 SpeechRecognitionController* SpeechRecognitionController::Create(
-    SpeechRecognitionClient* client) {
-  return new SpeechRecognitionController(client);
+    LocalFrame& frame) {
+  return new SpeechRecognitionController(frame);
 }
 
-void ProvideSpeechRecognitionTo(LocalFrame& frame,
-                                SpeechRecognitionClient* client) {
+void SpeechRecognitionController::Start(
+    mojom::blink::SpeechRecognitionSessionRequest session_request,
+    mojom::blink::SpeechRecognitionSessionClientPtrInfo session_client,
+    const SpeechGrammarList* grammars,
+    const String& lang,
+    bool continuous,
+    bool interim_results,
+    unsigned long max_alternatives) {
+  mojom::blink::StartSpeechRecognitionRequestParamsPtr msg_params =
+      mojom::blink::StartSpeechRecognitionRequestParams::New();
+  for (unsigned i = 0; i < grammars->length(); i++) {
+    SpeechGrammar* grammar = grammars->item(i);
+    msg_params->grammars.push_back(mojom::blink::SpeechRecognitionGrammar::New(
+        grammar->src(), grammar->weight()));
+  }
+  msg_params->language = lang.IsNull() ? g_empty_string : lang;
+  msg_params->max_hypotheses = max_alternatives;
+  msg_params->continuous = continuous;
+  msg_params->interim_results = interim_results;
+  msg_params->origin = GetSupplementable()->GetDocument()->GetSecurityOrigin();
+  msg_params->client = std::move(session_client);
+  msg_params->session_request = std::move(session_request);
+
+  GetSpeechRecognizer().Start(std::move(msg_params));
+}
+
+void ProvideSpeechRecognitionTo(LocalFrame& frame) {
   SpeechRecognitionController::ProvideTo(
-      frame, SpeechRecognitionController::Create(client));
+      frame, SpeechRecognitionController::Create(frame));
+}
+
+mojom::blink::SpeechRecognizer&
+SpeechRecognitionController::GetSpeechRecognizer() {
+  if (!speech_recognizer_) {
+    GetSupplementable()->GetInterfaceProvider().GetInterface(
+        mojo::MakeRequest(&speech_recognizer_));
+  }
+  return *speech_recognizer_;
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/speech/speech_recognition_controller.h b/third_party/blink/renderer/modules/speech/speech_recognition_controller.h
index 19a3db2..e6a2fb40 100644
--- a/third_party/blink/renderer/modules/speech/speech_recognition_controller.h
+++ b/third_party/blink/renderer/modules/speech/speech_recognition_controller.h
@@ -28,11 +28,14 @@
 
 #include <memory>
 
+#include "third_party/blink/public/mojom/speech/speech_recognizer.mojom-blink.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/modules/speech/speech_recognition_client.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
 
 namespace blink {
 
+class SpeechGrammarList;
+
 class SpeechRecognitionController final
     : public GarbageCollectedFinalized<SpeechRecognitionController>,
       public Supplement<LocalFrame> {
@@ -43,35 +46,29 @@
 
   virtual ~SpeechRecognitionController();
 
-  void Start(SpeechRecognition* recognition,
+  void Start(mojom::blink::SpeechRecognitionSessionRequest session_request,
+             mojom::blink::SpeechRecognitionSessionClientPtrInfo session_client,
              const SpeechGrammarList* grammars,
              const String& lang,
              bool continuous,
              bool interim_results,
-             unsigned long max_alternatives) {
-    client_->Start(recognition, grammars, lang, continuous, interim_results,
-                   max_alternatives);
-  }
+             unsigned long max_alternatives);
 
-  void Stop(SpeechRecognition* recognition) { client_->Stop(recognition); }
-  void Abort(SpeechRecognition* recognition) { client_->Abort(recognition); }
-
-  static SpeechRecognitionController* Create(SpeechRecognitionClient*);
+  static SpeechRecognitionController* Create(LocalFrame& frame);
   static SpeechRecognitionController* From(LocalFrame* frame) {
     return Supplement<LocalFrame>::From<SpeechRecognitionController>(frame);
   }
 
-  void Trace(blink::Visitor* visitor) override {
-    Supplement<LocalFrame>::Trace(visitor);
-    visitor->Trace(client_);
-  }
-
  private:
-  explicit SpeechRecognitionController(SpeechRecognitionClient*);
+  explicit SpeechRecognitionController(LocalFrame& frame);
 
-  Member<SpeechRecognitionClient> client_;
+  mojom::blink::SpeechRecognizer& GetSpeechRecognizer();
+
+  mojom::blink::SpeechRecognizerPtr speech_recognizer_;
 };
 
+MODULES_EXPORT void ProvideSpeechRecognitionTo(LocalFrame& frame);
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_CONTROLLER_H_
diff --git a/third_party/blink/renderer/modules/speech/speech_recognition_error.cc b/third_party/blink/renderer/modules/speech/speech_recognition_error.cc
index 7a6a56f3..b1f4126 100644
--- a/third_party/blink/renderer/modules/speech/speech_recognition_error.cc
+++ b/third_party/blink/renderer/modules/speech/speech_recognition_error.cc
@@ -23,7 +23,6 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "third_party/blink/public/web/web_speech_recognizer_client.h"
 #include "third_party/blink/renderer/modules/speech/speech_recognition_error.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
 
@@ -86,23 +85,4 @@
   return EventNames::SpeechRecognitionError;
 }
 
-STATIC_ASSERT_ENUM(WebSpeechRecognizerClient::kOtherError,
-                   SpeechRecognitionError::kErrorCodeOther);
-STATIC_ASSERT_ENUM(WebSpeechRecognizerClient::kNoSpeechError,
-                   SpeechRecognitionError::kErrorCodeNoSpeech);
-STATIC_ASSERT_ENUM(WebSpeechRecognizerClient::kAbortedError,
-                   SpeechRecognitionError::kErrorCodeAborted);
-STATIC_ASSERT_ENUM(WebSpeechRecognizerClient::kAudioCaptureError,
-                   SpeechRecognitionError::kErrorCodeAudioCapture);
-STATIC_ASSERT_ENUM(WebSpeechRecognizerClient::kNetworkError,
-                   SpeechRecognitionError::kErrorCodeNetwork);
-STATIC_ASSERT_ENUM(WebSpeechRecognizerClient::kNotAllowedError,
-                   SpeechRecognitionError::kErrorCodeNotAllowed);
-STATIC_ASSERT_ENUM(WebSpeechRecognizerClient::kServiceNotAllowedError,
-                   SpeechRecognitionError::kErrorCodeServiceNotAllowed);
-STATIC_ASSERT_ENUM(WebSpeechRecognizerClient::kBadGrammarError,
-                   SpeechRecognitionError::kErrorCodeBadGrammar);
-STATIC_ASSERT_ENUM(WebSpeechRecognizerClient::kLanguageNotSupportedError,
-                   SpeechRecognitionError::kErrorCodeLanguageNotSupported);
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
index bfd415d7..f388c9a 100644
--- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h"
 
 #include <memory>
+#include "base/numerics/checked_math.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
 #include "third_party/blink/renderer/bindings/modules/v8/webgl_any.h"
@@ -26,7 +27,6 @@
 #include "third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_uniform_location.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 using WTF::String;
@@ -59,7 +59,7 @@
     // type size is at most 8, so no overflow.
     byte_offset = sub_offset * type_size;
   }
-  CheckedNumeric<long long> total = byte_offset;
+  base::CheckedNumeric<long long> total = byte_offset;
   total += byte_length;
   if (!total.IsValid() || total.ValueOrDie() > view->byteLength()) {
     return false;
@@ -3521,7 +3521,7 @@
                                                      GLenum buffer,
                                                      GLsizei size,
                                                      GLuint src_offset) {
-  CheckedNumeric<GLsizei> checked_size(size);
+  base::CheckedNumeric<GLsizei> checked_size(size);
   checked_size -= src_offset;
   if (!checked_size.IsValid()) {
     SynthesizeGLError(GL_INVALID_VALUE, function_name,
@@ -5877,7 +5877,7 @@
     WebGLBuffer* source_buffer,
     GLintptr source_byte_offset,
     long long destination_byte_length) {
-  CheckedNumeric<long long> src_end = source_byte_offset;
+  base::CheckedNumeric<long long> src_end = source_byte_offset;
   src_end += destination_byte_length;
   if (!src_end.IsValid() || src_end.ValueOrDie() > source_buffer->GetSize()) {
     SynthesizeGLError(GL_INVALID_VALUE, function_name,
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc
index 98588bdd..5a8e295 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc
@@ -26,6 +26,7 @@
 #include "third_party/blink/renderer/modules/webgl/webgl_rendering_context.h"
 
 #include <memory>
+#include "base/numerics/checked_math.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
@@ -64,7 +65,6 @@
 #include "third_party/blink/renderer/modules/webgl/webgl_draw_buffers.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_lose_context.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index b3cabdeb..1b96d662b 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -27,6 +27,7 @@
 
 #include <memory>
 
+#include "base/numerics/checked_math.h"
 #include "build/build_config.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "gpu/config/gpu_feature_info.h"
@@ -101,7 +102,6 @@
 #include "third_party/blink/renderer/platform/graphics/graphics_context.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/waitable_event.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
@@ -4213,7 +4213,7 @@
                       "no destination ArrayBufferView");
     return;
   }
-  CheckedNumeric<GLuint> offset_in_bytes = offset;
+  base::CheckedNumeric<GLuint> offset_in_bytes = offset;
   offset_in_bytes *= pixels->TypeSize();
   if (!offset_in_bytes.IsValid() ||
       offset_in_bytes.ValueOrDie() > pixels->byteLength()) {
@@ -4228,7 +4228,8 @@
     SynthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
     return;
   }
-  CheckedNumeric<GLuint> buffer_size = pixels->byteLength() - offset_in_bytes;
+  base::CheckedNumeric<GLuint> buffer_size =
+      pixels->byteLength() - offset_in_bytes;
   if (!buffer_size.IsValid()) {
     SynthesizeGLError(GL_INVALID_VALUE, "readPixels",
                       "destination offset out of range");
@@ -7200,7 +7201,7 @@
     SynthesizeGLError(error, function_name, "invalid texture dimensions");
     return false;
   }
-  CheckedNumeric<uint32_t> total = src_offset;
+  base::CheckedNumeric<uint32_t> total = src_offset;
   total *= pixels->TypeSize();
   total += total_bytes_required;
   total += skip_bytes;
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
index 8f2aaca..b3ac9b6 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -29,6 +29,7 @@
 #include <memory>
 #include <set>
 
+#include "base/numerics/checked_math.h"
 #include "base/optional.h"
 #include "base/single_thread_task_runner.h"
 #include "third_party/blink/public/platform/platform.h"
@@ -53,7 +54,6 @@
 #include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h"
 #include "third_party/blink/renderer/platform/timer.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "third_party/khronos/GLES2/gl2.h"
 
@@ -1098,7 +1098,7 @@
 
       // According to the WebGL 2.0 spec, specifying depth > 1 means
       // to select multiple rectangles stacked vertically.
-      WTF::CheckedNumeric<GLint> max_y_accessed;
+      base::CheckedNumeric<GLint> max_y_accessed;
       if (unpack_image_height) {
         max_y_accessed = unpack_image_height;
       } else {
diff --git a/third_party/blink/renderer/platform/exported/web_url_request.cc b/third_party/blink/renderer/platform/exported/web_url_request.cc
index f736e3d..0a8f117 100644
--- a/third_party/blink/renderer/platform/exported/web_url_request.cc
+++ b/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -416,6 +416,14 @@
   return resource_request_->GetDevToolsToken();
 }
 
+void WebURLRequest::SetOriginPolicy(const WebString& policy) {
+  resource_request_->SetOriginPolicy(policy);
+}
+
+const WebString WebURLRequest::GetOriginPolicy() const {
+  return resource_request_->GetOriginPolicy();
+}
+
 const ResourceRequest& WebURLRequest::ToResourceRequest() const {
   DCHECK(resource_request_);
   return *resource_request_;
diff --git a/third_party/blink/renderer/platform/geometry/int_rect.cc b/third_party/blink/renderer/platform/geometry/int_rect.cc
index cf792014..55406ad 100644
--- a/third_party/blink/renderer/platform/geometry/int_rect.cc
+++ b/third_party/blink/renderer/platform/geometry/int_rect.cc
@@ -25,9 +25,9 @@
 
 #include "third_party/blink/renderer/platform/geometry/int_rect.h"
 
+#include "base/numerics/checked_math.h"
 #include "third_party/blink/renderer/platform/geometry/float_rect.h"
 #include "third_party/blink/renderer/platform/geometry/layout_rect.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/text/text_stream.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -199,7 +199,7 @@
 }
 
 bool IntRect::IsValid() const {
-  CheckedNumeric<int> max = location_.X();
+  base::CheckedNumeric<int> max = location_.X();
   max += size_.Width();
   if (!max.IsValid())
     return false;
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
index 1864cf1..7642b803 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
@@ -655,14 +655,14 @@
   if (is_deferral_enabled_) {
     have_recorded_draw_commands_ = true;
     IntRect pixel_bounds = EnclosingIntRect(rect);
-    CheckedNumeric<int> pixel_bounds_size = pixel_bounds.Width();
+    base::CheckedNumeric<int> pixel_bounds_size = pixel_bounds.Width();
     pixel_bounds_size *= pixel_bounds.Height();
     recording_pixel_count_ += pixel_bounds_size;
     if (!recording_pixel_count_.IsValid()) {
       DisableDeferral(kDisableDeferralReasonExpensiveOverdrawHeuristic);
       return;
     }
-    CheckedNumeric<int> threshold_size = size_.Width();
+    base::CheckedNumeric<int> threshold_size = size_.Width();
     threshold_size *= size_.Height();
     threshold_size *= CanvasHeuristicParameters::kExpensiveOverdrawThreshold;
     if (!threshold_size.IsValid()) {
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h
index 6ab0eba..3a06f9f 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h
+++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h
@@ -31,6 +31,7 @@
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/numerics/checked_math.h"
 #include "build/build_config.h"
 #include "cc/layers/texture_layer_client.h"
 #include "third_party/blink/renderer/platform/geometry/float_rect.h"
@@ -41,7 +42,6 @@
 #include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
 #include "third_party/blink/renderer/platform/wtf/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/deque.h"
 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
 #include "third_party/khronos/GLES2/gl2.h"
@@ -203,7 +203,7 @@
   AccelerationMode acceleration_mode_;
   CanvasColorParams color_params_;
   IntSize size_;
-  CheckedNumeric<int> recording_pixel_count_;
+  base::CheckedNumeric<int> recording_pixel_count_;
 
   enum SnapshotState {
     kInitialSnapshotState,
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.cc b/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.cc
index c09fd84..8b69f689 100644
--- a/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.cc
+++ b/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.cc
@@ -26,8 +26,8 @@
 
 #include <memory>
 #include "SkMatrixConvolutionImageFilter.h"
+#include "base/numerics/checked_math.h"
 #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/text/text_stream.h"
 
 namespace blink {
@@ -123,7 +123,7 @@
   if (kernel_size_.IsEmpty())
     return false;
   uint64_t kernel_area = kernel_size_.Area();
-  if (!CheckedNumeric<int>(kernel_area).IsValid())
+  if (!base::CheckedNumeric<int>(kernel_area).IsValid())
     return false;
   if (SafeCast<size_t>(kernel_area) != kernel_matrix_.size())
     return false;
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
index e9df5c7..6787fae0 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -34,6 +34,7 @@
 #include <memory>
 #include <utility>
 
+#include "base/numerics/checked_math.h"
 #include "build/build_config.h"
 #include "cc/layers/texture_layer.h"
 #include "components/viz/common/resources/bitmap_allocation.h"
@@ -54,7 +55,6 @@
 #include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h"
 #include "third_party/skia/include/core/SkColorSpaceXform.h"
 #include "third_party/skia/include/core/SkSurface.h"
@@ -91,7 +91,7 @@
     return nullptr;
   }
 
-  CheckedNumeric<int> data_size = color_params.BytesPerPixel();
+  base::CheckedNumeric<int> data_size = color_params.BytesPerPixel();
   data_size *= size.Width();
   data_size *= size.Height();
   if (!data_size.IsValid() ||
@@ -1257,7 +1257,7 @@
   int width = Size().Width();
   int height = Size().Height();
 
-  CheckedNumeric<int> data_size = 4;
+  base::CheckedNumeric<int> data_size = 4;
   data_size *= width;
   data_size *= height;
   if (RuntimeEnabledFeatures::CanvasColorManagementEnabled() &&
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc b/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
index bdaa943..8eb90e5 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h"
 
 #include <memory>
+#include "base/numerics/checked_math.h"
 #include "build/build_config.h"
 #include "third_party/blink/renderer/platform/graphics/cpu/arm/webgl_image_conversion_neon.h"
 #include "third_party/blink/renderer/platform/graphics/cpu/mips/webgl_image_conversion_msa.h"
@@ -12,7 +13,6 @@
 #include "third_party/blink/renderer/platform/graphics/image_observer.h"
 #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
 #include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/skia/include/core/SkImage.h"
 
 namespace blink {
@@ -2703,14 +2703,15 @@
                                       &components_per_pixel))
     return GL_INVALID_ENUM;
   unsigned bytes_per_group = bytes_per_component * components_per_pixel;
-  CheckedNumeric<uint32_t> checked_value = static_cast<uint32_t>(row_length);
+  base::CheckedNumeric<uint32_t> checked_value =
+      static_cast<uint32_t>(row_length);
   checked_value *= bytes_per_group;
   if (!checked_value.IsValid())
     return GL_INVALID_VALUE;
 
   unsigned last_row_size;
   if (params.row_length > 0 && params.row_length != width) {
-    CheckedNumeric<uint32_t> tmp = width;
+    base::CheckedNumeric<uint32_t> tmp = width;
     tmp *= bytes_per_group;
     if (!tmp.IsValid())
       return GL_INVALID_VALUE;
@@ -2720,7 +2721,8 @@
   }
 
   unsigned padding = 0;
-  CheckedNumeric<uint32_t> checked_residual = checked_value % params.alignment;
+  base::CheckedNumeric<uint32_t> checked_residual =
+      checked_value % params.alignment;
   if (!checked_residual.IsValid()) {
     return GL_INVALID_VALUE;
   }
@@ -2733,7 +2735,7 @@
     return GL_INVALID_VALUE;
   unsigned padded_row_size = checked_value.ValueOrDie();
 
-  CheckedNumeric<uint32_t> rows = image_height;
+  base::CheckedNumeric<uint32_t> rows = image_height;
   rows *= (depth - 1);
   // Last image is not affected by IMAGE_HEIGHT parameter.
   rows += height;
@@ -2748,9 +2750,9 @@
   if (padding_in_bytes)
     *padding_in_bytes = padding;
 
-  CheckedNumeric<uint32_t> skip_size = 0;
+  base::CheckedNumeric<uint32_t> skip_size = 0;
   if (params.skip_images > 0) {
-    CheckedNumeric<uint32_t> tmp = padded_row_size;
+    base::CheckedNumeric<uint32_t> tmp = padded_row_size;
     tmp *= image_height;
     tmp *= params.skip_images;
     if (!tmp.IsValid())
@@ -2758,14 +2760,14 @@
     skip_size += tmp.ValueOrDie();
   }
   if (params.skip_rows > 0) {
-    CheckedNumeric<uint32_t> tmp = padded_row_size;
+    base::CheckedNumeric<uint32_t> tmp = padded_row_size;
     tmp *= params.skip_rows;
     if (!tmp.IsValid())
       return GL_INVALID_VALUE;
     skip_size += tmp.ValueOrDie();
   }
   if (params.skip_pixels > 0) {
-    CheckedNumeric<uint32_t> tmp = bytes_per_group;
+    base::CheckedNumeric<uint32_t> tmp = bytes_per_group;
     tmp *= params.skip_pixels;
     if (!tmp.IsValid())
       return GL_INVALID_VALUE;
diff --git a/third_party/blink/renderer/platform/graphics/image.cc b/third_party/blink/renderer/platform/graphics/image.cc
index f803141e..19bfa52 100644
--- a/third_party/blink/renderer/platform/graphics/image.cc
+++ b/third_party/blink/renderer/platform/graphics/image.cc
@@ -26,6 +26,7 @@
 
 #include "third_party/blink/renderer/platform/graphics/image.h"
 
+#include "base/numerics/checked_math.h"
 #include "build/build_config.h"
 #include "cc/tiles/software_image_decode_cache.h"
 #include "third_party/blink/public/platform/platform.h"
@@ -46,7 +47,6 @@
 #include "third_party/blink/renderer/platform/length.h"
 #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
 #include "third_party/blink/renderer/platform/shared_buffer.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "third_party/skia/include/core/SkImage.h"
diff --git a/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
index 8f87d6b..e4f1508 100644
--- a/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
+++ b/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
@@ -4,13 +4,13 @@
 
 #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
 
+#include "base/numerics/checked_math.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
 #include "third_party/blink/renderer/platform/graphics/graphics_context.h"
 #include "third_party/blink/renderer/platform/graphics/image_observer.h"
 #include "third_party/blink/renderer/platform/graphics/paint/paint_image.h"
 #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkImage.h"
@@ -115,7 +115,7 @@
     const CanvasColorParams& color_params,
     bool is_accelerated) {
   uint8_t bytes_per_pixel = color_params.BytesPerPixel();
-  CheckedNumeric<int> data_size = bytes_per_pixel;
+  base::CheckedNumeric<int> data_size = bytes_per_pixel;
   data_size *= rect.Size().Area();
   if (!data_size.IsValid() ||
       data_size.ValueOrDie() > v8::TypedArray::kMaxLength)
diff --git a/third_party/blink/renderer/platform/heap/heap_page.cc b/third_party/blink/renderer/platform/heap/heap_page.cc
index ce7888f..67a04a03 100644
--- a/third_party/blink/renderer/platform/heap/heap_page.cc
+++ b/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -1160,11 +1160,10 @@
 #if DCHECK_IS_ON() || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) || \
     defined(MEMORY_SANITIZER)
 NO_SANITIZE_MEMORY
-void NEVER_INLINE
-FreeList::GetAllowedAndForbiddenCounts(Address address,
-                                       size_t size,
-                                       size_t& allowed_count,
-                                       size_t& forbidden_count) {
+void NOINLINE FreeList::GetAllowedAndForbiddenCounts(Address address,
+                                                     size_t size,
+                                                     size_t& allowed_count,
+                                                     size_t& forbidden_count) {
   for (size_t i = sizeof(FreeListEntry); i < size; i++) {
     if (address[i] == kReuseAllowedZapValue)
       allowed_count++;
@@ -1177,7 +1176,7 @@
 
 NO_SANITIZE_ADDRESS
 NO_SANITIZE_MEMORY
-void NEVER_INLINE FreeList::ZapFreedMemory(Address address, size_t size) {
+void NOINLINE FreeList::ZapFreedMemory(Address address, size_t size) {
   for (size_t i = 0; i < size; i++) {
     // See the comment in addToFreeList().
     if (address[i] != kReuseAllowedZapValue)
@@ -1185,8 +1184,7 @@
   }
 }
 
-void NEVER_INLINE FreeList::CheckFreedMemoryIsZapped(Address address,
-                                                     size_t size) {
+void NOINLINE FreeList::CheckFreedMemoryIsZapped(Address address, size_t size) {
   for (size_t i = 0; i < size; i++) {
     DCHECK(address[i] == kReuseAllowedZapValue ||
            address[i] == kReuseForbiddenZapValue);
diff --git a/third_party/blink/renderer/platform/heap/heap_test.cc b/third_party/blink/renderer/platform/heap/heap_test.cc
index c802902..ac91ccf 100644
--- a/third_party/blink/renderer/platform/heap/heap_test.cc
+++ b/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -6317,7 +6317,7 @@
   kGrowsTowardsLower,
 };
 
-NEVER_INLINE NO_SANITIZE_ADDRESS GrowthDirection StackGrowthDirection() {
+NOINLINE NO_SANITIZE_ADDRESS GrowthDirection StackGrowthDirection() {
   // Disable ASan, otherwise its stack checking (use-after-return) will
   // confuse the direction check.
   static char* previous = nullptr;
diff --git a/third_party/blink/renderer/platform/heap/page_memory.cc b/third_party/blink/renderer/platform/heap/page_memory.cc
index 59bf902..5e7b33f 100644
--- a/third_party/blink/renderer/platform/heap/page_memory.cc
+++ b/third_party/blink/renderer/platform/heap/page_memory.cc
@@ -55,7 +55,7 @@
 // TODO(haraken): Like partitionOutOfMemoryWithLotsOfUncommitedPages(),
 // we should probably have a way to distinguish physical memory OOM from
 // virtual address space OOM.
-static NEVER_INLINE void BlinkGCOutOfMemory() {
+static NOINLINE void BlinkGCOutOfMemory() {
   OOM_CRASH();
 }
 
diff --git a/third_party/blink/renderer/platform/heap/stack_frame_depth.cc b/third_party/blink/renderer/platform/heap/stack_frame_depth.cc
index e6237ed..93ba8e2 100644
--- a/third_party/blink/renderer/platform/heap/stack_frame_depth.cc
+++ b/third_party/blink/renderer/platform/heap/stack_frame_depth.cc
@@ -19,9 +19,9 @@
 
 static const char* g_avoid_optimization = nullptr;
 
-// NEVER_INLINE ensures that |dummy| array on configureLimit() is not optimized
+// NOINLINE ensures that |dummy| array on configureLimit() is not optimized
 // away, and the stack frame base register is adjusted |kSafeStackFrameSize|.
-NEVER_INLINE static uintptr_t CurrentStackFrameBaseOnCallee(const char* dummy) {
+NOINLINE static uintptr_t CurrentStackFrameBaseOnCallee(const char* dummy) {
   g_avoid_optimization = dummy;
   return StackFrameDepth::CurrentStackFrame();
 }
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
index 9d5aaf8..6e5acfba 100644
--- a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
@@ -399,61 +399,61 @@
 
 RawResourceClientStateChecker::~RawResourceClientStateChecker() = default;
 
-NEVER_INLINE void RawResourceClientStateChecker::WillAddClient() {
+NOINLINE void RawResourceClientStateChecker::WillAddClient() {
   SECURITY_CHECK(state_ == kNotAddedAsClient);
   state_ = kStarted;
 }
 
-NEVER_INLINE void RawResourceClientStateChecker::WillRemoveClient() {
+NOINLINE void RawResourceClientStateChecker::WillRemoveClient() {
   SECURITY_CHECK(state_ != kNotAddedAsClient);
   state_ = kNotAddedAsClient;
 }
 
-NEVER_INLINE void RawResourceClientStateChecker::RedirectReceived() {
+NOINLINE void RawResourceClientStateChecker::RedirectReceived() {
   SECURITY_CHECK(state_ == kStarted);
 }
 
-NEVER_INLINE void RawResourceClientStateChecker::RedirectBlocked() {
+NOINLINE void RawResourceClientStateChecker::RedirectBlocked() {
   SECURITY_CHECK(state_ == kStarted);
   state_ = kRedirectBlocked;
 }
 
-NEVER_INLINE void RawResourceClientStateChecker::DataSent() {
+NOINLINE void RawResourceClientStateChecker::DataSent() {
   SECURITY_CHECK(state_ == kStarted);
 }
 
-NEVER_INLINE void RawResourceClientStateChecker::ResponseReceived() {
+NOINLINE void RawResourceClientStateChecker::ResponseReceived() {
   SECURITY_CHECK(state_ == kStarted);
   state_ = kResponseReceived;
 }
 
-NEVER_INLINE void RawResourceClientStateChecker::SetSerializedCachedMetadata() {
+NOINLINE void RawResourceClientStateChecker::SetSerializedCachedMetadata() {
   SECURITY_CHECK(state_ == kResponseReceived);
   state_ = kSetSerializedCachedMetadata;
 }
 
-NEVER_INLINE void RawResourceClientStateChecker::DataReceived() {
+NOINLINE void RawResourceClientStateChecker::DataReceived() {
   SECURITY_CHECK(state_ == kResponseReceived ||
                  state_ == kSetSerializedCachedMetadata ||
                  state_ == kDataReceived);
   state_ = kDataReceived;
 }
 
-NEVER_INLINE void RawResourceClientStateChecker::DataDownloaded() {
+NOINLINE void RawResourceClientStateChecker::DataDownloaded() {
   SECURITY_CHECK(state_ == kResponseReceived ||
                  state_ == kSetSerializedCachedMetadata ||
                  state_ == kDataDownloaded);
   state_ = kDataDownloaded;
 }
 
-NEVER_INLINE void RawResourceClientStateChecker::DidDownloadToBlob() {
+NOINLINE void RawResourceClientStateChecker::DidDownloadToBlob() {
   SECURITY_CHECK(state_ == kResponseReceived ||
                  state_ == kSetSerializedCachedMetadata ||
                  state_ == kDataDownloaded);
   state_ = kDidDownloadToBlob;
 }
 
-NEVER_INLINE void RawResourceClientStateChecker::NotifyFinished(
+NOINLINE void RawResourceClientStateChecker::NotifyFinished(
     Resource* resource) {
   SECURITY_CHECK(state_ != kNotAddedAsClient);
   SECURITY_CHECK(state_ != kNotifyFinished);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
index cebfb98..c10d3a4 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -369,6 +369,9 @@
     devtools_token_ = devtools_token;
   }
 
+  void SetOriginPolicy(const String& policy) { origin_policy_ = policy; }
+  const String& GetOriginPolicy() const { return origin_policy_; }
+
  private:
   using SharableExtraData =
       base::RefCountedData<std::unique_ptr<WebURLRequest::ExtraData>>;
@@ -438,6 +441,7 @@
   bool upgrade_if_insecure_ = false;
 
   base::Optional<base::UnguessableToken> devtools_token_;
+  String origin_policy_;
 };
 
 // This class is needed to copy a ResourceRequest across threads, because it
diff --git a/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h b/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h
index 3210160..ba5e0f30 100644
--- a/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h
+++ b/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h
@@ -56,7 +56,7 @@
   // message pipe already bound to this pointer.
   RevocableInterfacePtr& operator=(RevocableInterfacePtr&& other) {
     reset();
-    interface_ptr_ = std::move(other.interface_ptr);
+    interface_ptr_ = std::move(other.interface_ptr_);
     SetInvalidator(other.invalidator_.get());
     // Reset the other interface ptr to remove it as an observer of the
     // invalidator.
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index ae5db59..f7579da5 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -371,7 +371,7 @@
     },
     {
       name: "DeprecationReporting",
-      status: "experimental",
+      status: "stable",
     },
     {
       name: "DesktopCaptureDisableLocalEchoControl",
@@ -614,6 +614,10 @@
       settable_from_internals: true,
     },
     {
+      name: "InterventionReporting",
+      status: "experimental",
+    },
+    {
       // Tracks "jank" from layout objects changing their visual location
       // between animation frames (see crbug.com/581518).
       name: "JankTracking",
@@ -1041,7 +1045,8 @@
     },
     {
       name: "ReportingObserver",
-      status: "experimental",
+      implied_by: ["DeprecationReporting", "InterventionReporting"],
+      status: "stable",
     },
     {
       name: "RequestIsHistoryNavigation",
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
index 299444e..88575a0 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -715,19 +715,23 @@
   bool background_page_with_no_audio = !IsPageVisible() && !IsAudioPlaying();
 
   if (background_page_with_no_audio) {
-    if (base::FeatureList::IsEnabled(kLowPriorityForBackgroundPages))
+    if (main_thread_scheduler_->scheduling_settings()
+            .low_priority_background_page)
       return TaskQueue::QueuePriority::kLowPriority;
 
-    if (base::FeatureList::IsEnabled(kBestEffortPriorityForBackgroundPages))
+    if (main_thread_scheduler_->scheduling_settings()
+            .best_effort_background_page)
       return TaskQueue::QueuePriority::kBestEffortPriority;
   }
 
   // If main thread is in the loading use case or if the priority experiments
   // should take place at all times.
   if (main_thread_scheduler_->IsLoading() ||
-      !base::FeatureList::IsEnabled(kExperimentOnlyWhenLoading)) {
+      !main_thread_scheduler_->scheduling_settings()
+           .experiment_only_when_loading) {
     // Low priority feature enabled for hidden frame.
-    if (base::FeatureList::IsEnabled(kLowPriorityForHiddenFrame) &&
+    if (main_thread_scheduler_->scheduling_settings()
+            .low_priority_hidden_frame &&
         !IsFrameVisible())
       return TaskQueue::QueuePriority::kLowPriority;
 
@@ -737,16 +741,19 @@
         MainThreadTaskQueue::QueueType::kFrameThrottleable;
 
     // Low priority feature enabled for sub-frame.
-    if (base::FeatureList::IsEnabled(kLowPriorityForSubFrame) && is_subframe)
+    if (main_thread_scheduler_->scheduling_settings().low_priority_subframe &&
+        is_subframe)
       return TaskQueue::QueuePriority::kLowPriority;
 
     // Low priority feature enabled for sub-frame throttleable task queues.
-    if (base::FeatureList::IsEnabled(kLowPriorityForSubFrameThrottleableTask) &&
+    if (main_thread_scheduler_->scheduling_settings()
+            .low_priority_subframe_throttleable &&
         is_throttleable_task_queue)
       return TaskQueue::QueuePriority::kLowPriority;
 
     // Low priority feature enabled for throttleable task queues.
-    if (base::FeatureList::IsEnabled(kLowPriorityForThrottleableTask) &&
+    if (main_thread_scheduler_->scheduling_settings()
+            .low_priority_throttleable &&
         is_throttleable_task_queue)
       return TaskQueue::QueuePriority::kLowPriority;
   }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
index e5075cc..97a900f 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -39,6 +39,12 @@
     task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(5));
   }
 
+  FrameSchedulerImplTest(std::vector<base::Feature> features_to_enable,
+                         std::vector<base::Feature> features_to_disable)
+      : FrameSchedulerImplTest() {
+    feature_list_.InitWithFeatures(features_to_enable, features_to_disable);
+  }
+
   ~FrameSchedulerImplTest() override = default;
 
   void SetUp() override {
@@ -105,6 +111,7 @@
     return frame_scheduler_->CalculateLifecycleState(type);
   }
 
+  base::test::ScopedFeatureList feature_list_;
   base::test::ScopedTaskEnvironment task_environment_;
   std::unique_ptr<MainThreadSchedulerImpl> scheduler_;
   std::unique_ptr<PageSchedulerImpl> page_scheduler_;
@@ -635,10 +642,13 @@
 // TODO(farahcharab) Move priority testing to MainThreadTaskQueueTest after
 // landing the change that moves priority computation to MainThreadTaskQueue.
 
-TEST_F(FrameSchedulerImplTest, LowPriorityBackgroundPagesWhenFeatureEnabled) {
-  base::test::ScopedFeatureList feature_list_;
-  feature_list_.InitAndEnableFeature(kLowPriorityForBackgroundPages);
+class LowPriorityBackgroundPageExperimentTest : public FrameSchedulerImplTest {
+ public:
+  LowPriorityBackgroundPageExperimentTest()
+      : FrameSchedulerImplTest({kLowPriorityForBackgroundPages}, {}) {}
+};
 
+TEST_F(LowPriorityBackgroundPageExperimentTest, FrameQueuesPriorities) {
   page_scheduler_->SetPageVisible(false);
   EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
             TaskQueue::QueuePriority::kLowPriority);
@@ -683,11 +693,14 @@
             TaskQueue::QueuePriority::kNormalPriority);
 }
 
-TEST_F(FrameSchedulerImplTest,
-       BestEffortPriorityBackgroundPagesWhenFeatureEnabled) {
-  base::test::ScopedFeatureList feature_list_;
-  feature_list_.InitAndEnableFeature(kBestEffortPriorityForBackgroundPages);
+class BestEffortPriorityBackgroundPageExperimentTest
+    : public FrameSchedulerImplTest {
+ public:
+  BestEffortPriorityBackgroundPageExperimentTest()
+      : FrameSchedulerImplTest({kBestEffortPriorityForBackgroundPages}, {}) {}
+};
 
+TEST_F(BestEffortPriorityBackgroundPageExperimentTest, FrameQueuesPriorities) {
   page_scheduler_->SetPageVisible(false);
   EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
             TaskQueue::QueuePriority::kBestEffortPriority);
@@ -732,10 +745,14 @@
             TaskQueue::QueuePriority::kNormalPriority);
 }
 
-TEST_F(FrameSchedulerImplTest, LowPriorityForHiddenFrameFeatureEnabled) {
-  base::test::ScopedFeatureList feature_list_;
-  feature_list_.InitAndEnableFeature(kLowPriorityForHiddenFrame);
+class LowPriorityHiddenFrameExperimentTest : public FrameSchedulerImplTest {
+ public:
+  LowPriorityHiddenFrameExperimentTest()
+      : FrameSchedulerImplTest({kLowPriorityForHiddenFrame},
+                               {kExperimentOnlyWhenLoading}) {}
+};
 
+TEST_F(LowPriorityHiddenFrameExperimentTest, FrameQueuesPriorities) {
   // Hidden Frame Task Queues.
   frame_scheduler_->SetFrameVisible(false);
   EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
@@ -767,12 +784,17 @@
             TaskQueue::QueuePriority::kNormalPriority);
 }
 
-TEST_F(FrameSchedulerImplTest,
-       LowPriorityForHiddenFrameDuringLoadingFeatureEnabled) {
-  base::test::ScopedFeatureList feature_list_;
-  feature_list_.InitWithFeatures(
-      {kLowPriorityForHiddenFrame, kExperimentOnlyWhenLoading}, {});
+class LowPriorityHiddenFrameDuringLoadingExperimentTest
+    : public FrameSchedulerImplTest {
+ public:
+  LowPriorityHiddenFrameDuringLoadingExperimentTest()
+      : FrameSchedulerImplTest(
+            {kLowPriorityForHiddenFrame, kExperimentOnlyWhenLoading},
+            {}) {}
+};
 
+TEST_F(LowPriorityHiddenFrameDuringLoadingExperimentTest,
+       FrameQueuesPriorities) {
   // Main thread scheduler is in the loading use case.
   scheduler_->DidStartProvisionalLoad(true);
   EXPECT_TRUE(scheduler_->IsLoading());
@@ -810,10 +832,14 @@
             TaskQueue::QueuePriority::kNormalPriority);
 }
 
-TEST_F(FrameSchedulerImplTest, LowPriorityForSubFrameFeatureEnabled) {
-  base::test::ScopedFeatureList feature_list_;
-  feature_list_.InitAndEnableFeature(kLowPriorityForSubFrame);
+class LowPrioritySubFrameExperimentTest : public FrameSchedulerImplTest {
+ public:
+  LowPrioritySubFrameExperimentTest()
+      : FrameSchedulerImplTest({kLowPriorityForSubFrame},
+                               {kExperimentOnlyWhenLoading}) {}
+};
 
+TEST_F(LowPrioritySubFrameExperimentTest, FrameQueuesPriorities) {
   // Sub-Frame Task Queues.
   EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
             TaskQueue::QueuePriority::kLowPriority);
@@ -829,12 +855,16 @@
             TaskQueue::QueuePriority::kLowPriority);
 }
 
-TEST_F(FrameSchedulerImplTest,
-       LowPriorityForSubFrameDuringLoadingFeatureEnabled) {
-  base::test::ScopedFeatureList feature_list_;
-  feature_list_.InitWithFeatures(
-      {kLowPriorityForSubFrame, kExperimentOnlyWhenLoading}, {});
+class LowPrioritySubFrameDuringLoadingExperimentTest
+    : public FrameSchedulerImplTest {
+ public:
+  LowPrioritySubFrameDuringLoadingExperimentTest()
+      : FrameSchedulerImplTest(
+            {kLowPriorityForSubFrame, kExperimentOnlyWhenLoading},
+            {}) {}
+};
 
+TEST_F(LowPrioritySubFrameDuringLoadingExperimentTest, FrameQueuesPriorities) {
   // Main thread scheduler is in the loading use case.
   scheduler_->DidStartProvisionalLoad(true);
   EXPECT_TRUE(scheduler_->IsLoading());
@@ -872,11 +902,16 @@
             TaskQueue::QueuePriority::kNormalPriority);
 }
 
-TEST_F(FrameSchedulerImplTest,
-       kLowPriorityForSubFrameThrottleableTaskFeatureEnabled) {
-  base::test::ScopedFeatureList feature_list_;
-  feature_list_.InitAndEnableFeature(kLowPriorityForSubFrameThrottleableTask);
+class LowPrioritySubFrameThrottleableTaskExperimentTest
+    : public FrameSchedulerImplTest {
+ public:
+  LowPrioritySubFrameThrottleableTaskExperimentTest()
+      : FrameSchedulerImplTest({kLowPriorityForSubFrameThrottleableTask},
+                               {kExperimentOnlyWhenLoading}) {}
+};
 
+TEST_F(LowPrioritySubFrameThrottleableTaskExperimentTest,
+       FrameQueuesPriorities) {
   // Sub-Frame Task Queues.
   EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
             TaskQueue::QueuePriority::kNormalPriority);
@@ -892,13 +927,17 @@
             TaskQueue::QueuePriority::kNormalPriority);
 }
 
-TEST_F(FrameSchedulerImplTest,
-       kLowPriorityForSubFrameThrottleableTaskDuringLoadingFeatureEnabled) {
-  base::test::ScopedFeatureList feature_list_;
-  feature_list_.InitWithFeatures(
-      {kLowPriorityForSubFrameThrottleableTask, kExperimentOnlyWhenLoading},
-      {});
+class LowPrioritySubFrameThrottleableTaskDuringLoadingExperimentTest
+    : public FrameSchedulerImplTest {
+ public:
+  LowPrioritySubFrameThrottleableTaskDuringLoadingExperimentTest()
+      : FrameSchedulerImplTest({kLowPriorityForSubFrameThrottleableTask,
+                                kExperimentOnlyWhenLoading},
+                               {}) {}
+};
 
+TEST_F(LowPrioritySubFrameThrottleableTaskDuringLoadingExperimentTest,
+       FrameQueuesPriorities) {
   // Main thread scheduler is in the loading use case.
   scheduler_->DidStartProvisionalLoad(true);
   EXPECT_TRUE(scheduler_->IsLoading());
@@ -936,10 +975,15 @@
             TaskQueue::QueuePriority::kNormalPriority);
 }
 
-TEST_F(FrameSchedulerImplTest, kLowPriorityForThrottleableTaskFeatureEnabled) {
-  base::test::ScopedFeatureList feature_list_;
-  feature_list_.InitAndEnableFeature(kLowPriorityForThrottleableTask);
+class LowPriorityThrottleableTaskExperimentTest
+    : public FrameSchedulerImplTest {
+ public:
+  LowPriorityThrottleableTaskExperimentTest()
+      : FrameSchedulerImplTest({kLowPriorityForThrottleableTask},
+                               {kExperimentOnlyWhenLoading}) {}
+};
 
+TEST_F(LowPriorityThrottleableTaskExperimentTest, FrameQueuesPriorities) {
   // Sub-Frame Task Queues.
   EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
             TaskQueue::QueuePriority::kNormalPriority);
@@ -972,12 +1016,17 @@
             TaskQueue::QueuePriority::kNormalPriority);
 }
 
-TEST_F(FrameSchedulerImplTest,
-       kLowPriorityForThrottleableTaskDuringLoadingFeatureEnabled_SubFrame) {
-  base::test::ScopedFeatureList feature_list_;
-  feature_list_.InitWithFeatures(
-      {kLowPriorityForThrottleableTask, kExperimentOnlyWhenLoading}, {});
+class LowPriorityThrottleableTaskDuringLoadingExperimentTest
+    : public FrameSchedulerImplTest {
+ public:
+  LowPriorityThrottleableTaskDuringLoadingExperimentTest()
+      : FrameSchedulerImplTest(
+            {kLowPriorityForThrottleableTask, kExperimentOnlyWhenLoading},
+            {}) {}
+};
 
+TEST_F(LowPriorityThrottleableTaskDuringLoadingExperimentTest,
+       SubFrameQueuesPriorities) {
   // Main thread is in the loading use case.
   scheduler_->DidStartProvisionalLoad(true);
   EXPECT_TRUE(scheduler_->IsLoading());
@@ -1013,12 +1062,8 @@
             TaskQueue::QueuePriority::kNormalPriority);
 }
 
-TEST_F(FrameSchedulerImplTest,
-       kLowPriorityForThrottleableTaskDuringLoadingFeatureEnabled_MainFrame) {
-  base::test::ScopedFeatureList feature_list_;
-  feature_list_.InitWithFeatures(
-      {kLowPriorityForThrottleableTask, kExperimentOnlyWhenLoading}, {});
-
+TEST_F(LowPriorityThrottleableTaskDuringLoadingExperimentTest,
+       MainFrameQueuesPriorities) {
   frame_scheduler_ = FrameSchedulerImpl::Create(
       page_scheduler_.get(), nullptr, FrameScheduler::FrameType::kMainFrame);
 
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
index 605d487..a12f931 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -235,10 +235,6 @@
   return TaskQueue::PriorityToString(priority.value());
 }
 
-bool IsUnconditionalHighPriorityInputEnabled() {
-  return base::FeatureList::IsEnabled(kHighPriorityInput);
-}
-
 bool IsBlockingEvent(const blink::WebInputEvent& web_input_event) {
   blink::WebInputEvent::Type type = web_input_event.GetType();
   DCHECK(type == blink::WebInputEvent::kTouchStart ||
@@ -283,7 +279,7 @@
               MainThreadTaskQueue::QueueType::kInput)
               .SetShouldMonitorQuiescence(true)
               .SetFixedPriority(
-                  IsUnconditionalHighPriorityInputEnabled()
+                  scheduling_settings_.high_priority_input
                       ? base::make_optional(
                             TaskQueue::QueuePriority::kHighestPriority)
                       : base::nullopt))),
@@ -625,6 +621,26 @@
           &main_thread_scheduler_impl->tracing_controller_,
           YesNoStateToString) {}
 
+MainThreadSchedulerImpl::SchedulingSettings::SchedulingSettings() {
+  high_priority_input = base::FeatureList::IsEnabled(kHighPriorityInput);
+
+  low_priority_background_page =
+      base::FeatureList::IsEnabled(kLowPriorityForBackgroundPages);
+  best_effort_background_page =
+      base::FeatureList::IsEnabled(kBestEffortPriorityForBackgroundPages);
+
+  low_priority_hidden_frame =
+      base::FeatureList::IsEnabled(kLowPriorityForHiddenFrame);
+  low_priority_subframe = base::FeatureList::IsEnabled(kLowPriorityForSubFrame);
+  low_priority_throttleable =
+      base::FeatureList::IsEnabled(kLowPriorityForThrottleableTask);
+  low_priority_subframe_throttleable =
+      base::FeatureList::IsEnabled(kLowPriorityForSubFrameThrottleableTask);
+
+  experiment_only_when_loading =
+      base::FeatureList::IsEnabled(kExperimentOnlyWhenLoading);
+}
+
 MainThreadSchedulerImpl::AnyThread::~AnyThread() = default;
 
 MainThreadSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly()
@@ -2753,6 +2769,11 @@
   return main_thread_only().current_use_case == UseCase::kLoading;
 }
 
+const MainThreadSchedulerImpl::SchedulingSettings&
+MainThreadSchedulerImpl::scheduling_settings() const {
+  return scheduling_settings_;
+}
+
 // static
 const char* MainThreadSchedulerImpl::UseCaseToString(UseCase use_case) {
   switch (use_case) {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
index a01aba5..c766bf0d 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
@@ -83,6 +83,26 @@
     }
   };
 
+  struct SchedulingSettings {
+    SchedulingSettings();
+
+    // High priority input experiment.
+    bool high_priority_input;
+
+    // Background page priority experiment.
+    bool low_priority_background_page;
+    bool best_effort_background_page;
+
+    // Task and subframe priority experiment.
+    bool low_priority_subframe;
+    bool low_priority_throttleable;
+    bool low_priority_subframe_throttleable;
+    bool low_priority_hidden_frame;
+
+    // Turn on relevant experiments during the loading phase.
+    bool experiment_only_when_loading;
+  };
+
   static const char* UseCaseToString(UseCase use_case);
   static const char* RAILModeToString(v8::RAILMode rail_mode);
   static const char* VirtualTimePolicyToString(
@@ -325,6 +345,8 @@
   // Returns true if main thread is in loading use case.
   bool IsLoading() const;
 
+  const SchedulingSettings& scheduling_settings() const;
+
   base::WeakPtr<MainThreadSchedulerImpl> GetWeakPtr();
 
  protected:
@@ -353,6 +375,7 @@
   friend class main_thread_scheduler_impl_unittest::
       MainThreadSchedulerImplForTest;
   friend class main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest;
+
   FRIEND_TEST_ALL_PREFIXES(
       main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest,
       ShouldIgnoreTaskForUkm);
@@ -691,6 +714,14 @@
   // because they require one to initialize themselves.
   TraceableVariableController tracing_controller_;
 
+  // Used for experiments on finch. On main thread instantiation, we cache
+  // the values of base::Feature flags using this struct, since calling
+  // base::Feature::IsEnabled is a relatively expensive operation.
+  //
+  // Note that it is important to keep this as the first member to ensure it is
+  // initialized first and can be used everywhere.
+  const SchedulingSettings scheduling_settings_;
+
   MainThreadSchedulerHelper helper_;
   IdleHelper idle_helper_;
   IdleCanceledDelayedTaskSweeper idle_canceled_delayed_task_sweeper_;
diff --git a/third_party/blink/renderer/platform/text/icu_error.cc b/third_party/blink/renderer/platform/text/icu_error.cc
index d2e9cce..1aad852 100644
--- a/third_party/blink/renderer/platform/text/icu_error.cc
+++ b/third_party/blink/renderer/platform/text/icu_error.cc
@@ -10,7 +10,7 @@
 
 // Distinguish memory allocation failures from other errors.
 // https://groups.google.com/a/chromium.org/d/msg/platform-architecture-dev/MP0k9WGnCjA/zIBiJtilBwAJ
-static NEVER_INLINE void ICUOutOfMemory() {
+static NOINLINE void ICUOutOfMemory() {
   OOM_CRASH();
 }
 
diff --git a/third_party/blink/renderer/platform/wtf/BUILD.gn b/third_party/blink/renderer/platform/wtf/BUILD.gn
index 1207483..47f3d26e 100644
--- a/third_party/blink/renderer/platform/wtf/BUILD.gn
+++ b/third_party/blink/renderer/platform/wtf/BUILD.gn
@@ -59,7 +59,6 @@
     "bit_vector.cc",
     "bit_vector.h",
     "bloom_filter.h",
-    "checked_numeric.h",
     "compiler.h",
     "conditional_destructor.h",
     "container_annotations.h",
diff --git a/third_party/blink/renderer/platform/wtf/allocator/partitions.cc b/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
index 1d7bbd3..bd158e0 100644
--- a/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
+++ b/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
@@ -164,55 +164,55 @@
   return dumper.TotalActiveBytes();
 }
 
-static NEVER_INLINE void PartitionsOutOfMemoryUsing2G() {
+static NOINLINE void PartitionsOutOfMemoryUsing2G() {
   size_t signature = 2UL * 1024 * 1024 * 1024;
   base::debug::Alias(&signature);
   OOM_CRASH();
 }
 
-static NEVER_INLINE void PartitionsOutOfMemoryUsing1G() {
+static NOINLINE void PartitionsOutOfMemoryUsing1G() {
   size_t signature = 1UL * 1024 * 1024 * 1024;
   base::debug::Alias(&signature);
   OOM_CRASH();
 }
 
-static NEVER_INLINE void PartitionsOutOfMemoryUsing512M() {
+static NOINLINE void PartitionsOutOfMemoryUsing512M() {
   size_t signature = 512 * 1024 * 1024;
   base::debug::Alias(&signature);
   OOM_CRASH();
 }
 
-static NEVER_INLINE void PartitionsOutOfMemoryUsing256M() {
+static NOINLINE void PartitionsOutOfMemoryUsing256M() {
   size_t signature = 256 * 1024 * 1024;
   base::debug::Alias(&signature);
   OOM_CRASH();
 }
 
-static NEVER_INLINE void PartitionsOutOfMemoryUsing128M() {
+static NOINLINE void PartitionsOutOfMemoryUsing128M() {
   size_t signature = 128 * 1024 * 1024;
   base::debug::Alias(&signature);
   OOM_CRASH();
 }
 
-static NEVER_INLINE void PartitionsOutOfMemoryUsing64M() {
+static NOINLINE void PartitionsOutOfMemoryUsing64M() {
   size_t signature = 64 * 1024 * 1024;
   base::debug::Alias(&signature);
   OOM_CRASH();
 }
 
-static NEVER_INLINE void PartitionsOutOfMemoryUsing32M() {
+static NOINLINE void PartitionsOutOfMemoryUsing32M() {
   size_t signature = 32 * 1024 * 1024;
   base::debug::Alias(&signature);
   OOM_CRASH();
 }
 
-static NEVER_INLINE void PartitionsOutOfMemoryUsing16M() {
+static NOINLINE void PartitionsOutOfMemoryUsing16M() {
   size_t signature = 16 * 1024 * 1024;
   base::debug::Alias(&signature);
   OOM_CRASH();
 }
 
-static NEVER_INLINE void PartitionsOutOfMemoryUsingLessThan16M() {
+static NOINLINE void PartitionsOutOfMemoryUsingLessThan16M() {
   size_t signature = 16 * 1024 * 1024 - 1;
   base::debug::Alias(&signature);
   DLOG(FATAL) << "ParitionAlloc: out of memory with < 16M usage (error:"
diff --git a/third_party/blink/renderer/platform/wtf/checked_numeric.h b/third_party/blink/renderer/platform/wtf/checked_numeric.h
deleted file mode 100644
index 5a705f9..0000000
--- a/third_party/blink/renderer/platform/wtf/checked_numeric.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_CHECKED_NUMERIC_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_CHECKED_NUMERIC_H_
-
-/* See base/numerics/safe_math.h for usage.
- */
-#include "base/numerics/safe_math.h"
-
-namespace WTF {
-using base::CheckedNumeric;
-using base::IsValidForType;
-using base::ValueOrDieForType;
-using base::ValueOrDefaultForType;
-using base::MakeCheckedNum;
-using base::CheckMax;
-using base::CheckMin;
-using base::CheckAdd;
-using base::CheckSub;
-using base::CheckMul;
-using base::CheckDiv;
-using base::CheckMod;
-using base::CheckLsh;
-using base::CheckRsh;
-using base::CheckAnd;
-using base::CheckOr;
-using base::CheckXor;
-}  // namespace WTF
-
-using WTF::CheckedNumeric;
-
-#endif
diff --git a/third_party/blink/renderer/platform/wtf/compiler.h b/third_party/blink/renderer/platform/wtf/compiler.h
index 3cab18d..51595af 100644
--- a/third_party/blink/renderer/platform/wtf/compiler.h
+++ b/third_party/blink/renderer/platform/wtf/compiler.h
@@ -31,12 +31,6 @@
 
 /* ==== Compiler features ==== */
 
-/* NEVER_INLINE */
-
-// TODO(palmer): Remove this and update callers to use NOINLINE from Chromium
-// base. https://bugs.chromium.org/p/chromium/issues/detail?id=632441
-#define NEVER_INLINE NOINLINE
-
 /* OBJC_CLASS */
 
 #ifndef OBJC_CLASS
diff --git a/third_party/blink/renderer/platform/wtf/text/cstring.cc b/third_party/blink/renderer/platform/wtf/text/cstring.cc
index 4ab73cdc..33ac70a 100644
--- a/third_party/blink/renderer/platform/wtf/text/cstring.cc
+++ b/third_party/blink/renderer/platform/wtf/text/cstring.cc
@@ -27,9 +27,9 @@
 #include "third_party/blink/renderer/platform/wtf/text/cstring.h"
 
 #include <string.h>
+#include "base/numerics/checked_math.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
 #include "third_party/blink/renderer/platform/wtf/ascii_ctype.h"
-#include "third_party/blink/renderer/platform/wtf/checked_numeric.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 
 namespace WTF {
@@ -37,7 +37,7 @@
 scoped_refptr<CStringImpl> CStringImpl::CreateUninitialized(size_t length,
                                                             char*& data) {
   unsigned length_in_unsigned = SafeCast<unsigned>(length);
-  CheckedNumeric<size_t> size = length;
+  base::CheckedNumeric<size_t> size = length;
   // The +1 is for the terminating NUL character.
   size += sizeof(CStringImpl) + 1;
   CStringImpl* buffer = static_cast<CStringImpl*>(Partitions::BufferMalloc(
diff --git a/third_party/blink/renderer/platform/wtf/text/integer_to_string_conversion.h b/third_party/blink/renderer/platform/wtf/text/integer_to_string_conversion.h
index 48ece3d..4933c9b8 100644
--- a/third_party/blink/renderer/platform/wtf/text/integer_to_string_conversion.h
+++ b/third_party/blink/renderer/platform/wtf/text/integer_to_string_conversion.h
@@ -32,7 +32,7 @@
 
 // TODO(esprehn): See if we can generalize IntToStringT in
 // base/strings/string_number_conversions.cc, and use unsigned type expansion
-// optimization here instead of CheckedNumeric::UnsignedAbs().
+// optimization here instead of base::CheckedNumeric::UnsignedAbs().
 template <typename IntegerType>
 class IntegerToStringConverter {
  public:
diff --git a/third_party/blink/renderer/platform/wtf/text/string_impl.h b/third_party/blink/renderer/platform/wtf/text/string_impl.h
index 158d81c..0e7c40b 100644
--- a/third_party/blink/renderer/platform/wtf/text/string_impl.h
+++ b/third_party/blink/renderer/platform/wtf/text/string_impl.h
@@ -456,7 +456,7 @@
   template <typename CharType, class UCharPredicate>
   scoped_refptr<StringImpl> SimplifyMatchedCharactersToSpace(UCharPredicate,
                                                              StripBehavior);
-  NEVER_INLINE unsigned HashSlowCase() const;
+  NOINLINE unsigned HashSlowCase() const;
 
   void DestroyIfNotStatic() const;
   void UpdateContainsOnlyASCII() const;
diff --git a/third_party/blink/renderer/platform/wtf/text/string_statics.cc b/third_party/blink/renderer/platform/wtf/text/string_statics.cc
index d0013cde..9c0e508f 100644
--- a/third_party/blink/renderer/platform/wtf/text/string_statics.cc
+++ b/third_party/blink/renderer/platform/wtf/text/string_statics.cc
@@ -49,7 +49,7 @@
 WTF_EXPORT DEFINE_GLOBAL(String, g_empty_string);
 WTF_EXPORT DEFINE_GLOBAL(String, g_empty_string16_bit);
 
-NEVER_INLINE unsigned StringImpl::HashSlowCase() const {
+NOINLINE unsigned StringImpl::HashSlowCase() const {
   if (Is8Bit())
     SetHash(StringHasher::ComputeHashAndMaskTop8Bits(Characters8(), length_));
   else
diff --git a/third_party/blink/renderer/platform/wtf/vector.h b/third_party/blink/renderer/platform/wtf/vector.h
index 6a34147..88d30ba 100644
--- a/third_party/blink/renderer/platform/wtf/vector.h
+++ b/third_party/blink/renderer/platform/wtf/vector.h
@@ -598,7 +598,7 @@
     buffer_ = nullptr;
   }
 
-  NEVER_INLINE void ReallyDeallocateBuffer(T* buffer_to_deallocate) {
+  NOINLINE void ReallyDeallocateBuffer(T* buffer_to_deallocate) {
     Allocator::FreeInlineVectorBacking(buffer_to_deallocate);
   }
 
@@ -1766,8 +1766,7 @@
 
 template <typename T, size_t inlineCapacity, typename Allocator>
 template <typename U>
-NEVER_INLINE void Vector<T, inlineCapacity, Allocator>::AppendSlowCase(
-    U&& val) {
+NOINLINE void Vector<T, inlineCapacity, Allocator>::AppendSlowCase(U&& val) {
   DCHECK_EQ(size(), capacity());
 
   typename std::remove_reference<U>::type* ptr = &val;
diff --git a/third_party/blink/tools/audit_non_blink_usage.py b/third_party/blink/tools/audit_non_blink_usage.py
index 7afa3eb..53f8097 100755
--- a/third_party/blink/tools/audit_non_blink_usage.py
+++ b/third_party/blink/tools/audit_non_blink_usage.py
@@ -77,6 +77,25 @@
             # //base/synchronization/waitable_event.h.
             'base::WaitableEvent',
 
+            # //base/numerics/checked_math.h.
+            'base::CheckedNumeric',
+            'base::IsValidForType',
+            'base::ValueOrDieForType',
+            'base::ValueOrDefaultForType',
+            'base::MakeCheckedNum',
+            'base::CheckMax',
+            'base::CheckMin',
+            'base::CheckAdd',
+            'base::CheckSub',
+            'base::CheckMul',
+            'base::CheckDiv',
+            'base::CheckMod',
+            'base::CheckLsh',
+            'base::CheckRsh',
+            'base::CheckAnd',
+            'base::CheckOr',
+            'base::CheckXor',
+
             # Debugging helpers from //base/debug are allowed everywhere.
             'base::debug::.+',
 
diff --git a/tools/clang/blink_gc_plugin/RecordInfo.cpp b/tools/clang/blink_gc_plugin/RecordInfo.cpp
index dc4349f..8374a4f 100644
--- a/tools/clang/blink_gc_plugin/RecordInfo.cpp
+++ b/tools/clang/blink_gc_plugin/RecordInfo.cpp
@@ -85,9 +85,8 @@
   // delayed until FinalizeGarbageCollectedObject() gets called), unless there
   // is an inline buffer. Vector, Deque, and ListHashSet can have an inline
   // buffer.
-  if (name_ != "Vector" && name_ != "Deque" && name_ != "ListHashSet" &&
-      name_ != "HeapVector" && name_ != "HeapDeque" &&
-      name_ != "HeapListHashSet")
+  if (name_ != "Vector" && name_ != "Deque" && name_ != "HeapVector" &&
+      name_ != "HeapDeque")
     return true;
   ClassTemplateSpecializationDecl* tmpl =
       dyn_cast<ClassTemplateSpecializationDecl>(record_);
diff --git a/tools/clang/blink_gc_plugin/tests/class_requires_finalization_field.txt b/tools/clang/blink_gc_plugin/tests/class_requires_finalization_field.txt
index 8fc15a1..9c466f4a 100644
--- a/tools/clang/blink_gc_plugin/tests/class_requires_finalization_field.txt
+++ b/tools/clang/blink_gc_plugin/tests/class_requires_finalization_field.txt
@@ -5,4 +5,10 @@
 ./class_requires_finalization_field.h:39:5: note: [blink-gc] Field 'm_as' requiring finalization declared here:
     Vector<Member<A> > m_as;
     ^
-1 warning generated.
+./class_requires_finalization_field.h:44:1: warning: [blink-gc] Class 'AlsoNeedsFinalizer' requires finalization.
+class AlsoNeedsFinalizer : public A {
+^
+./class_requires_finalization_field.h:48:5: note: [blink-gc] Field 'm_bs' requiring finalization declared here:
+    HeapVector<B, 10> m_bs;
+    ^
+2 warnings generated.
diff --git a/tools/clang/blink_gc_plugin/tests/heap/stubs.h b/tools/clang/blink_gc_plugin/tests/heap/stubs.h
index c77369d..b5a1e4a 100644
--- a/tools/clang/blink_gc_plugin/tests/heap/stubs.h
+++ b/tools/clang/blink_gc_plugin/tests/heap/stubs.h
@@ -37,19 +37,10 @@
     static const bool isGarbageCollected = false;
 };
 
-template <bool noDestructor>
-class ConditionalDestructor {
- public:
-  ~ConditionalDestructor() {}
-};
-
-template <>
-class ConditionalDestructor<true> {};
-
 template <typename T,
           size_t inlineCapacity = 0,
           typename Allocator = DefaultAllocator>
-class Vector : public ConditionalDestructor<Allocator::isGarbageCollected> {
+class Vector {
  public:
   using iterator = T*;
   using const_iterator = const T*;
@@ -58,63 +49,73 @@
 
   size_t size();
   T& operator[](size_t);
+
+  ~Vector() {}
 };
 
 template <typename T,
           size_t inlineCapacity = 0,
           typename Allocator = DefaultAllocator>
-class Deque : public ConditionalDestructor<Allocator::isGarbageCollected> {
+class Deque {
  public:
   using iterator = T*;
   using const_iterator = const T*;
   using reverse_iterator = T*;
   using const_reverse_iterator = const T*;
+
+  ~Deque() {}
 };
 
 template <typename ValueArg,
           typename HashArg = void,
           typename TraitsArg = void,
           typename Allocator = DefaultAllocator>
-class HashSet : public ConditionalDestructor<Allocator::isGarbageCollected> {
+class HashSet {
  public:
   typedef ValueArg* iterator;
   typedef const ValueArg* const_iterator;
   typedef ValueArg* reverse_iterator;
   typedef const ValueArg* const_reverse_iterator;
+
+  ~HashSet() {}
 };
 
 template <typename ValueArg,
           typename HashArg = void,
           typename TraitsArg = void,
           typename Allocator = DefaultAllocator>
-class ListHashSet
-    : public ConditionalDestructor<Allocator::isGarbageCollected> {
+class ListHashSet {
  public:
   typedef ValueArg* iterator;
   typedef const ValueArg* const_iterator;
   typedef ValueArg* reverse_iterator;
   typedef const ValueArg* const_reverse_iterator;
+
+  ~ListHashSet() {}
 };
 
 template <typename ValueArg,
           typename HashArg = void,
           typename TraitsArg = void,
           typename Allocator = DefaultAllocator>
-class LinkedHashSet
-    : public ConditionalDestructor<Allocator::isGarbageCollected> {
+class LinkedHashSet {
  public:
   typedef ValueArg* iterator;
   typedef const ValueArg* const_iterator;
   typedef ValueArg* reverse_iterator;
   typedef const ValueArg* const_reverse_iterator;
+
+  ~LinkedHashSet() {}
 };
 
 template <typename ValueArg,
           typename HashArg = void,
           typename TraitsArg = void,
           typename Allocator = DefaultAllocator>
-class HashCountedSet
-    : public ConditionalDestructor<Allocator::isGarbageCollected> {};
+class HashCountedSet {
+ public:
+  ~HashCountedSet() {}
+};
 
 template <typename KeyArg,
           typename MappedArg,
@@ -122,12 +123,14 @@
           typename KeyTraitsArg = void,
           typename MappedTraitsArg = void,
           typename Allocator = DefaultAllocator>
-class HashMap : public ConditionalDestructor<Allocator::isGarbageCollected> {
+class HashMap {
  public:
   typedef MappedArg* iterator;
   typedef const MappedArg* const_iterator;
   typedef MappedArg* reverse_iterator;
   typedef const MappedArg* const_reverse_iterator;
+
+  ~HashMap() {}
 };
 }
 
diff --git a/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.txt b/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.txt
index dd5bc74..29286ff 100644
--- a/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.txt
+++ b/tools/clang/blink_gc_plugin/tests/persistent_field_in_gc_managed_class.txt
@@ -29,4 +29,10 @@
 ./persistent_field_in_gc_managed_class.h:27:5: note: [blink-gc] Field 'm_weakPersistent' defining a GC root declared here:
     WeakPersistent<HeapObject> m_weakPersistent;
     ^
-4 warnings generated.
+./persistent_field_in_gc_managed_class.h:20:1: warning: [blink-gc] Class 'HeapObject' requires finalization.
+class HeapObject : public GarbageCollected<HeapObject> {
+^
+./persistent_field_in_gc_managed_class.h:27:5: note: [blink-gc] Field 'm_weakPersistent' requiring finalization declared here:
+    WeakPersistent<HeapObject> m_weakPersistent;
+    ^
+5 warnings generated.
diff --git a/tools/clang/blink_gc_plugin/tests/stack_allocated.txt b/tools/clang/blink_gc_plugin/tests/stack_allocated.txt
index be40b444..17604fc 100644
--- a/tools/clang/blink_gc_plugin/tests/stack_allocated.txt
+++ b/tools/clang/blink_gc_plugin/tests/stack_allocated.txt
@@ -23,7 +23,7 @@
 ./stack_allocated.h:43:3: warning: [blink-gc] Garbage collected class 'DerivedHeapObject2' is not permitted to override its new operator.
   STACK_ALLOCATED();
   ^
-./heap/stubs.h:179:5: note: expanded from macro 'STACK_ALLOCATED'
+./heap/stubs.h:182:5: note: expanded from macro 'STACK_ALLOCATED'
     __attribute__((annotate("blink_stack_allocated")))      \
     ^
 stack_allocated.cpp:12:1: warning: [blink-gc] Class 'AnonStackObject' contains invalid fields.
diff --git a/tools/clang/blink_gc_plugin/tests/trace_collections.txt b/tools/clang/blink_gc_plugin/tests/trace_collections.txt
index 1faecb2..2fd9863a 100644
--- a/tools/clang/blink_gc_plugin/tests/trace_collections.txt
+++ b/tools/clang/blink_gc_plugin/tests/trace_collections.txt
@@ -1,3 +1,13 @@
+In file included from trace_collections.cpp:5:
+./trace_collections.h:12:1: warning: [blink-gc] Class 'HeapObject' requires finalization.
+class HeapObject : public GarbageCollected<HeapObject> {
+^
+./trace_collections.h:17:5: note: [blink-gc] Field 'm_wtfVector' requiring finalization declared here:
+    Vector<Member<HeapObject>, 0, HeapAllocator> m_wtfVector;
+    ^
+./trace_collections.h:20:5: note: [blink-gc] Field 'm_wtfDeque' requiring finalization declared here:
+    Deque<Member<HeapObject>, 0, HeapAllocator> m_wtfDeque;
+    ^
 trace_collections.cpp:9:1: warning: [blink-gc] Class 'HeapObject' has untraced fields that require tracing.
 void HeapObject::Trace(Visitor* visitor)
 ^
@@ -49,4 +59,4 @@
 ./trace_collections.h:38:5: note: [blink-gc] Untraced field 'm_wtfMapVal' declared here:
     HashMap<Member<HeapObject>, int, void, void, void, HeapAllocator>
     ^
-1 warning generated.
+2 warnings generated.
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 39417326..d1c9a4f 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -1070,7 +1070,7 @@
     ],
 
     'chromeos_with_codecs_release_trybot': [
-      'chromeos_with_codecs', 'release_trybot', 'use_vaapi',
+      'chromeos_with_codecs', 'release_trybot', 'use_vaapi', 'no_symbols',
     ],
 
     'clang_release_bot_minimal_symbols_x86': [
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index ca6e4472d..7bf0669 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -26909,6 +26909,7 @@
   <int value="-2020024440" label="scroll-end-effect"/>
   <int value="-2017953534" label="enable-hosted-app-shim-creation"/>
   <int value="-2013551096" label="ViewsSimplifiedFullscreenUI:disabled"/>
+  <int value="-2013124655" label="EnableEphemeralFlashPermission:disabled"/>
   <int value="-2012990889" label="SpannableInlineAutocomplete:enabled"/>
   <int value="-2009622663" label="WebRtcHWH264Encoding:enabled"/>
   <int value="-2008272679" label="disable-webrtc-hw-encoding"/>
@@ -27557,7 +27558,6 @@
   <int value="-699767107" label="enable-sync-app-list"/>
   <int value="-699198009" label="KeyboardShortcutViewer:enabled"/>
   <int value="-697751423" label="disable-quickoffice-component-app"/>
-  <int value="-694372915" label="enable-ephemeral-flash-permission"/>
   <int value="-684900739" label="disable-merge-key-char-events"/>
   <int value="-684223908" label="enable-android-wallpapers-app"/>
   <int value="-680787130" label="ExperimentalVRFeatures:disabled"/>
@@ -28561,6 +28561,7 @@
   <int value="1529979182" label="EnablePasswordSelection:enabled"/>
   <int value="1530113113" label="disable-pushstate-throttle"/>
   <int value="1530177325" label="LanguagesPreference:disabled"/>
+  <int value="1534222388" label="EnableEphemeralFlashPermission:enabled"/>
   <int value="1536921097" label="NavigationMojoResponse:disabled"/>
   <int value="1538690515" label="OneGoogleBarOnLocalNtp:enabled"/>
   <int value="1541723759" label="ServiceWorkerNavigationPreload:disabled"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index b1ee206..662659a 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -122203,8 +122203,14 @@
     </obsolete>
   </suffix>
   <suffix name="ServiceWorkerControlledMainFrameDidFinishLoad"
-      label="Recorded when DidFinishLoad is called for the main frame which
-             is controlled by a service worker."/>
+      label="Recorded when DidFinishLoad is called for the main frame which is
+             controlled by a service worker.">
+    <obsolete>
+      Deprecated as of June 2018. No longer recorded. This was also being
+      recorded when the page had a controller with no fetch event, which usually
+      means the service worker was not running.
+    </obsolete>
+  </suffix>
   <affected-histogram name="Memory.Experimental.Renderer.BlinkGC"/>
   <affected-histogram name="Memory.Experimental.Renderer.Discardable"/>
   <affected-histogram name="Memory.Experimental.Renderer.Malloc"/>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 6a58716..2f197116 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -374,11 +374,21 @@
     Recorded when user edits a text field. The text field may have been
     autofilled.
   </summary>
+  <metric name="FieldSignature">
+    <summary>
+      The signature of the field
+    </summary>
+  </metric>
   <metric name="FieldTypeGroup">
     <summary>
       Field's |FieldTypeGroup|. See |AutofillType.group()|.
     </summary>
   </metric>
+  <metric name="FormSignature">
+    <summary>
+      The signature of the form.
+    </summary>
+  </metric>
   <metric name="HeuristicType">
     <summary>
       Field's |ServerFieldType| based on heuristics. See
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 0751550c..d6c48594 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -162,6 +162,7 @@
  <item id="omnibox_zerosuggest_experimental" hash_code="3813491" type="0" content_hash_code="22929259" os_list="linux,windows" file_path="components/omnibox/browser/contextual_suggestions_service.cc"/>
  <item id="one_google_bar_service" hash_code="78917933" type="0" content_hash_code="46527252" os_list="linux,windows" file_path="chrome/browser/search/one_google_bar/one_google_bar_loader_impl.cc"/>
  <item id="open_search" hash_code="107267424" type="0" content_hash_code="25715812" os_list="linux,windows" file_path="components/search_engines/template_url_fetcher.cc"/>
+ <item id="origin_policy_loader" hash_code="6483617" type="0" content_hash_code="20680909" os_list="linux,windows" file_path="content/browser/frame_host/origin_policy_throttle.cc"/>
  <item id="p2p_invalidator" hash_code="84201371" type="0" content_hash_code="117416248" os_list="linux,windows" file_path="components/invalidation/impl/p2p_invalidator.cc"/>
  <item id="parallel_download_job" hash_code="135118587" type="0" content_hash_code="105330419" os_list="linux,windows" file_path="components/download/internal/common/parallel_download_job.cc"/>
  <item id="password_protection_request" hash_code="66322287" type="0" content_hash_code="25596947" os_list="linux,windows" file_path="components/safe_browsing/password_protection/password_protection_request.cc"/>
diff --git a/ui/events/x/events_x_unittest.cc b/ui/events/x/events_x_unittest.cc
index 4ca7049..897c5c5 100644
--- a/ui/events/x/events_x_unittest.cc
+++ b/ui/events/x/events_x_unittest.cc
@@ -21,6 +21,7 @@
 #include "ui/events/event_utils.h"
 #include "ui/events/test/events_test_utils.h"
 #include "ui/events/test/events_test_utils_x11.h"
+#include "ui/events/test/scoped_event_test_tick_clock.h"
 #include "ui/events/x/events_x_utils.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/x/x11.h"
@@ -554,9 +555,8 @@
   XEvent event;
   InitButtonEvent(&event, true, gfx::Point(5, 10), 1, 0);
 
-  base::SimpleTestTickClock clock;
+  test::ScopedEventTestTickClock clock;
   clock.SetNowTicks(TimeTicksFromMillis(0x100000001));
-  SetEventTickClockForTesting(&clock);
   ResetTimestampRolloverCountersForTesting();
 
   event.xbutton.time = 0xFFFFFFFF;
@@ -574,9 +574,8 @@
   XEvent event;
   InitButtonEvent(&event, true, gfx::Point(5, 10), 1, 0);
 
-  base::SimpleTestTickClock clock;
+  test::ScopedEventTestTickClock clock;
   clock.SetNowTicks(TimeTicksFromMillis(10));
-  SetEventTickClockForTesting(&clock);
   ResetTimestampRolloverCountersForTesting();
 
   event.xbutton.time = 6;
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html
index 97828a5e..3163e41 100644
--- a/ui/file_manager/file_manager/main.html
+++ b/ui/file_manager/file_manager/main.html
@@ -142,9 +142,8 @@
       <command id="toggle-hidden-files"
                i18n-values="label:TOGGLE_HIDDEN_FILES_COMMAND_LABEL"
                shortcut=".|Ctrl" hide-shortcut-text>
-      <!-- TODO(fukino): Internationalize this label. crbug.com/851844. -->
       <command id="toggle-hidden-android-folders"
-               label="Show hidden Play folders"></command>
+               i18n-values="label:SHOW_ALL_ANDROID_FOLDERS_OPTION">
 
       <command id="default-task">
       <command id="open-with" i18n-values="label:OPEN_WITH_BUTTON_LABEL">
diff --git a/ui/file_manager/gallery/css/gallery.css b/ui/file_manager/gallery/css/gallery.css
index 9a60e40..3f69a14 100644
--- a/ui/file_manager/gallery/css/gallery.css
+++ b/ui/file_manager/gallery/css/gallery.css
@@ -110,7 +110,9 @@
    * center within the container. Note that this makes transitions janky, but
    * transitions with video controls look silly, so they're disabled.
    */
+  align-items: center;
   display: flex;
+  justify-content: center;
 }
 
 .gallery[tools] .image-container[cursor='default'] {
@@ -169,11 +171,18 @@
 }
 
 .gallery .video-container > .video {
-  margin: auto auto;
   max-height: 100%;
   max-width: 100%;
-  object-fit: contain;
-  object-position: 50% 50%;
+}
+
+/*
+ * Move the video element away from the top and bottom edges when the ribbon is
+ * visible so that it doesn't overlap the scrubber when a video is sufficiently
+ * tall.
+ */
+.gallery[tools] .video-container > .video {
+  box-sizing: border-box;
+  padding: 48px 0;
 }
 
 @media print {
diff --git a/ui/ozone/platform/drm/gpu/crtc_controller.h b/ui/ozone/platform/drm/gpu/crtc_controller.h
index f9a089a..3320b4d 100644
--- a/ui/ozone/platform/drm/gpu/crtc_controller.h
+++ b/ui/ozone/platform/drm/gpu/crtc_controller.h
@@ -100,7 +100,7 @@
   // TODO(dnicoara) Add support for hardware mirroring (multiple connectors).
   uint32_t connector_;
 
-  drmModeModeInfo mode_;
+  drmModeModeInfo mode_ = {};
 
   // Keeps track of the CRTC state. If a surface has been bound, then the value
   // is set to false. Otherwise it is true.
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
index 7566b94..27b340a 100644
--- a/ui/views/BUILD.gn
+++ b/ui/views/BUILD.gn
@@ -95,6 +95,7 @@
     "cocoa/views_nswindow_delegate.h",
     "cocoa/views_scrollbar_bridge.h",
     "cocoa/widget_owner_nswindow_adapter.h",
+    "cocoa/window_touch_bar_delegate.h",
     "color_chooser/color_chooser_listener.h",
     "color_chooser/color_chooser_view.h",
     "context_menu_controller.h",
diff --git a/ui/views/cocoa/cocoa_mouse_capture.mm b/ui/views/cocoa/cocoa_mouse_capture.mm
index ea5bbc7..b1f3cb21 100644
--- a/ui/views/cocoa/cocoa_mouse_capture.mm
+++ b/ui/views/cocoa/cocoa_mouse_capture.mm
@@ -71,12 +71,14 @@
 }
 
 void CocoaMouseCapture::ActiveEventTap::Init() {
+  // Consume most things, but not NSMouseEntered/Exited: The Widget doing
+  // capture will still see its own Entered/Exit events, but not those for other
+  // NSViews, since consuming those would break their tracking area logic.
   NSEventMask event_mask =
       NSLeftMouseDownMask | NSLeftMouseUpMask | NSRightMouseDownMask |
       NSRightMouseUpMask | NSMouseMovedMask | NSLeftMouseDraggedMask |
-      NSRightMouseDraggedMask | NSMouseEnteredMask | NSMouseExitedMask |
-      NSScrollWheelMask | NSOtherMouseDownMask | NSOtherMouseUpMask |
-      NSOtherMouseDraggedMask;
+      NSRightMouseDraggedMask | NSScrollWheelMask | NSOtherMouseDownMask |
+      NSOtherMouseUpMask | NSOtherMouseDraggedMask;
 
   // Capture a WeakPtr via NSObject. This allows the block to detect another
   // event monitor for the same event deleting |owner_|.
diff --git a/ui/views/cocoa/native_widget_mac_nswindow.h b/ui/views/cocoa/native_widget_mac_nswindow.h
index a6d5d58..0de886a 100644
--- a/ui/views/cocoa/native_widget_mac_nswindow.h
+++ b/ui/views/cocoa/native_widget_mac_nswindow.h
@@ -10,6 +10,8 @@
 #import "ui/base/cocoa/command_dispatcher.h"
 #include "ui/views/views_export.h"
 
+@protocol WindowTouchBarDelegate;
+
 // The NSWindow used by BridgedNativeWidget. Provides hooks into AppKit that
 // can only be accomplished by overriding methods.
 VIEWS_EXPORT
@@ -23,6 +25,11 @@
          returnCode:(NSInteger)returnCode
         contextInfo:(void*)contextInfo;
 
+// Set a WindowTouchBarDelegate to allow creation of a custom TouchBar when
+// AppKit follows the responder chain and reaches the NSWindow when trying to
+// create one.
+- (void)setWindowTouchBarDelegate:(id<WindowTouchBarDelegate>)delegate;
+
 @end
 
 #endif  // UI_VIEWS_COCOA_NATIVE_WIDGET_MAC_NSWINDOW_H_
diff --git a/ui/views/cocoa/native_widget_mac_nswindow.mm b/ui/views/cocoa/native_widget_mac_nswindow.mm
index bb6c5f25..145bbbe0 100644
--- a/ui/views/cocoa/native_widget_mac_nswindow.mm
+++ b/ui/views/cocoa/native_widget_mac_nswindow.mm
@@ -6,9 +6,10 @@
 
 #include "base/mac/foundation_util.h"
 #import "base/mac/sdk_forward_declarations.h"
-#import "ui/views/cocoa/bridged_native_widget.h"
 #import "ui/base/cocoa/user_interface_item_command_handler.h"
+#import "ui/views/cocoa/bridged_native_widget.h"
 #import "ui/views/cocoa/views_nswindow_delegate.h"
+#import "ui/views/cocoa/window_touch_bar_delegate.h"
 #include "ui/views/controls/menu/menu_controller.h"
 #include "ui/views/widget/native_widget_mac.h"
 #include "ui/views/widget/widget_delegate.h"
@@ -32,6 +33,7 @@
  @private
   base::scoped_nsobject<CommandDispatcher> commandDispatcher_;
   base::scoped_nsprotocol<id<UserInterfaceItemCommandHandler>> commandHandler_;
+  id<WindowTouchBarDelegate> touchBarDelegate_;  // Weak.
 }
 
 - (instancetype)initWithContentRect:(NSRect)contentRect
@@ -70,6 +72,10 @@
                                 contextInfo:contextInfo];
 }
 
+- (void)setWindowTouchBarDelegate:(id<WindowTouchBarDelegate>)delegate {
+  touchBarDelegate_ = delegate;
+}
+
 // Private methods.
 
 - (ViewsNSWindowDelegate*)viewsNSWindowDelegate {
@@ -183,6 +189,10 @@
     [super cursorUpdate:theEvent];
 }
 
+- (NSTouchBar*)makeTouchBar API_AVAILABLE(macos(10.12.2)) {
+  return touchBarDelegate_ ? [touchBarDelegate_ makeTouchBar] : nil;
+}
+
 // CommandDispatchingWindow implementation.
 
 - (void)setCommandHandler:(id<UserInterfaceItemCommandHandler>)commandHandler {
diff --git a/ui/views/cocoa/window_touch_bar_delegate.h b/ui/views/cocoa/window_touch_bar_delegate.h
new file mode 100644
index 0000000..daef546
--- /dev/null
+++ b/ui/views/cocoa/window_touch_bar_delegate.h
@@ -0,0 +1,21 @@
+// 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 UI_VIEWS_COCOA_WINDOW_TOUCH_BAR_DELEGATE_H_
+#define UI_VIEWS_COCOA_WINDOW_TOUCH_BAR_DELEGATE_H_
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/mac/availability.h"
+
+// Bridge delegate class for NativeWidgetMacNSWindow and
+// BrowserWindowTouchBarMac.
+@protocol WindowTouchBarDelegate<NSObject>
+
+// Creates and returns a touch bar for the browser window.
+- (NSTouchBar*)makeTouchBar API_AVAILABLE(macos(10.12.2));
+
+@end
+
+#endif  // UI_VIEWS_COCOA_WINDOW_TOUCH_BAR_DELEGATE_H_
\ No newline at end of file
diff --git a/ui/views/mus/desktop_window_tree_host_mus.h b/ui/views/mus/desktop_window_tree_host_mus.h
index def3640..81d5d7b 100644
--- a/ui/views/mus/desktop_window_tree_host_mus.h
+++ b/ui/views/mus/desktop_window_tree_host_mus.h
@@ -114,6 +114,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
+  void SetAspectRatio(const gfx::Size& aspect_ratio) override {}
   void SetWindowIcons(const gfx::ImageSkia& window_icon,
                       const gfx::ImageSkia& app_icon) override;
   void InitModalType(ui::ModalType modal_type) override;
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index b8873eba..2958c9b 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -870,6 +870,11 @@
     desktop_window_tree_host_->SetOpacity(opacity);
 }
 
+void DesktopNativeWidgetAura::SetAspectRatio(const gfx::Size& aspect_ratio) {
+  if (content_window_)
+    desktop_window_tree_host_->SetAspectRatio(aspect_ratio);
+}
+
 void DesktopNativeWidgetAura::FlashFrame(bool flash_frame) {
   if (content_window_)
     desktop_window_tree_host_->FlashFrame(flash_frame);
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
index be8fd03..c86f287b 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -164,6 +164,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
+  void SetAspectRatio(const gfx::Size& aspect_ratio) override;
   void FlashFrame(bool flash_frame) override;
   void RunShellDrag(View* view,
                     const ui::OSExchangeData& data,
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host.h b/ui/views/widget/desktop_aura/desktop_window_tree_host.h
index 437a0294..1dc3fcef 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host.h
@@ -141,6 +141,8 @@
 
   virtual void SetOpacity(float opacity) = 0;
 
+  virtual void SetAspectRatio(const gfx::Size& aspect_ratio) = 0;
+
   virtual void SetWindowIcons(const gfx::ImageSkia& window_icon,
                               const gfx::ImageSkia& app_icon) = 0;
 
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
index 551bcb59..085f24c3 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
@@ -77,6 +77,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
+  void SetAspectRatio(const gfx::Size& aspect_ratio) override {}
   void SetWindowIcons(const gfx::ImageSkia& window_icon,
                       const gfx::ImageSkia& app_icon) override;
   void InitModalType(ui::ModalType modal_type) override;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index 7e422e8..429e340 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -447,6 +447,10 @@
   content_window()->layer()->SetOpacity(opacity);
 }
 
+void DesktopWindowTreeHostWin::SetAspectRatio(const gfx::Size& aspect_ratio) {
+  // TODO(apacible): Implement for Windows. https://crbug.com/853276.
+}
+
 void DesktopWindowTreeHostWin::SetWindowIcons(
     const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) {
   message_handler_->SetWindowIcons(window_icon, app_icon);
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
index 327e4fb..1eb03f1 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -110,6 +110,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
+  void SetAspectRatio(const gfx::Size& aspect_ratio) override;
   void SetWindowIcons(const gfx::ImageSkia& window_icon,
                       const gfx::ImageSkia& app_icon) override;
   void InitModalType(ui::ModalType modal_type) override;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index cbfbfcbd..347384b 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -1075,6 +1075,18 @@
   }
 }
 
+void DesktopWindowTreeHostX11::SetAspectRatio(const gfx::Size& aspect_ratio) {
+  XSizeHints size_hints;
+  size_hints.flags = 0;
+  long supplied_return;
+
+  XGetWMNormalHints(xdisplay_, xwindow_, &size_hints, &supplied_return);
+  size_hints.flags |= PAspect;
+  size_hints.min_aspect.x = size_hints.max_aspect.x = aspect_ratio.width();
+  size_hints.min_aspect.y = size_hints.max_aspect.y = aspect_ratio.height();
+  XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
+}
+
 void DesktopWindowTreeHostX11::SetWindowIcons(
     const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) {
   // TODO(erg): The way we handle icons across different versions of chrome
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
index f424728..5b115b64 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -146,6 +146,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
+  void SetAspectRatio(const gfx::Size& aspect_ratio) override;
   void SetWindowIcons(const gfx::ImageSkia& window_icon,
                       const gfx::ImageSkia& app_icon) override;
   void InitModalType(ui::ModalType modal_type) override;
diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h
index 74bd738..9472bea 100644
--- a/ui/views/widget/native_widget_aura.h
+++ b/ui/views/widget/native_widget_aura.h
@@ -123,6 +123,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
+  void SetAspectRatio(const gfx::Size& aspect_ratio) override {}
   void FlashFrame(bool flash_frame) override;
   void RunShellDrag(View* view,
                     const ui::OSExchangeData& data,
diff --git a/ui/views/widget/native_widget_mac.h b/ui/views/widget/native_widget_mac.h
index c1d97e3..b952e9c 100644
--- a/ui/views/widget/native_widget_mac.h
+++ b/ui/views/widget/native_widget_mac.h
@@ -113,6 +113,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
+  void SetAspectRatio(const gfx::Size& aspect_ratio) override {}
   void FlashFrame(bool flash_frame) override;
   void RunShellDrag(View* view,
                     const ui::OSExchangeData& data,
diff --git a/ui/views/widget/native_widget_private.h b/ui/views/widget/native_widget_private.h
index 226dcba15..c12e7de 100644
--- a/ui/views/widget/native_widget_private.h
+++ b/ui/views/widget/native_widget_private.h
@@ -206,6 +206,7 @@
   virtual void SetFullscreen(bool fullscreen) = 0;
   virtual bool IsFullscreen() const = 0;
   virtual void SetOpacity(float opacity) = 0;
+  virtual void SetAspectRatio(const gfx::Size& aspect_ratio) = 0;
   virtual void FlashFrame(bool flash) = 0;
   virtual void RunShellDrag(View* view,
                             const ui::OSExchangeData& data,
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index a3b72c4..adb90b9d 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -718,6 +718,10 @@
   native_widget_->SetOpacity(opacity);
 }
 
+void Widget::SetAspectRatio(const gfx::Size& aspect_ratio) {
+  native_widget_->SetAspectRatio(aspect_ratio);
+}
+
 void Widget::FlashFrame(bool flash) {
   native_widget_->FlashFrame(flash);
 }
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h
index bc3b94f..461097a 100644
--- a/ui/views/widget/widget.h
+++ b/ui/views/widget/widget.h
@@ -552,6 +552,10 @@
   // underlying windowing system.
   void SetOpacity(float opacity);
 
+  // Sets the aspect ratio of the widget, which will be maintained during
+  // resizing.
+  void SetAspectRatio(const gfx::Size& aspect_ratio);
+
   // Flashes the frame of the window to draw attention to it. Currently only
   // implemented on Windows for non-Aura.
   void FlashFrame(bool flash);