diff --git a/DEPS b/DEPS
index 771048f..7469ceb 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,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': '3a3bc42b7d5b9d996debab1d2a05d2137c875bd7',
+  'skia_revision': 'da16434928b4c721b462d780d5140f9fc68d1413',
   # 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': 'bde4f053b5814d123e43d32d4a83650adbcd90e1',
+  'v8_revision': '38fc673a85f75931b590cf0f1dc93b9d0a49c8b3',
   # 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.
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index ec32769a..3f57da9 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -288,7 +288,6 @@
     "shelf/shelf_constants.h",
     "shelf/shelf_controller.cc",
     "shelf/shelf_controller.h",
-    "shelf/shelf_delegate.h",
     "shelf/shelf_layout_manager.cc",
     "shelf/shelf_layout_manager.h",
     "shelf/shelf_layout_manager_observer.h",
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd
index 572a8dd..7ade540 100644
--- a/ash/ash_strings.grd
+++ b/ash/ash_strings.grd
@@ -268,6 +268,10 @@
         Restart to update
       </message>
 
+      <message name="IDS_ASH_STATUS_TRAY_UPDATE_FLASH" desc="The label used in the tray popup to notify that the user should restart to update Adobe Flash Player.">
+        Restart to update Adobe Flash Player
+      </message>
+
       <message name="IDS_ASH_STATUS_TRAY_RESTART_AND_POWERWASH_TO_UPDATE" desc="The label used in the tray popup to notify that the user should restart and powerwash the device to get system updates.">
         Restart and powerwash to update
       </message>
diff --git a/ash/display/display_error_observer_chromeos.cc b/ash/display/display_error_observer_chromeos.cc
index 32aaf84b..cc55d1e 100644
--- a/ash/display/display_error_observer_chromeos.cc
+++ b/ash/display/display_error_observer_chromeos.cc
@@ -9,6 +9,7 @@
 #include "ash/system/devicetype_utils.h"
 #include "base/strings/string_number_conversions.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/display/types/display_snapshot.h"
 
 namespace ash {
 
diff --git a/ash/metrics/user_metrics_recorder.cc b/ash/metrics/user_metrics_recorder.cc
index f06b8c6..a6ff35ea 100644
--- a/ash/metrics/user_metrics_recorder.cc
+++ b/ash/metrics/user_metrics_recorder.cc
@@ -8,13 +8,13 @@
 #include "ash/metrics/pointer_metrics_recorder.h"
 #include "ash/public/cpp/shelf_item.h"
 #include "ash/public/cpp/shell_window_ids.h"
+#include "ash/session/session_controller.h"
 #include "ash/session/session_state_delegate.h"
 #include "ash/shelf/shelf_model.h"
 #include "ash/shelf/shelf_view.h"
 #include "ash/shelf/wm_shelf.h"
 #include "ash/shell.h"
 #include "ash/shell_port.h"
-#include "ash/system/tray/system_tray_delegate.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_state_aura.h"
 #include "ash/wm_window.h"
@@ -79,34 +79,21 @@
 
 // Returns true if kiosk mode is active.
 bool IsKioskModeActive() {
-  return Shell::Get()->system_tray_delegate()->GetUserLoginStatus() ==
+  return Shell::Get()->session_controller()->login_status() ==
          LoginStatus::KIOSK_APP;
 }
 
 // Returns true if ARC kiosk mode is active.
 bool IsArcKioskModeActive() {
-  return Shell::Get()->system_tray_delegate()->GetUserLoginStatus() ==
+  return Shell::Get()->session_controller()->login_status() ==
          LoginStatus::ARC_KIOSK_APP;
 }
 
 // Returns true if there is an active user and their session isn't currently
 // locked.
 bool IsUserActive() {
-  switch (Shell::Get()->system_tray_delegate()->GetUserLoginStatus()) {
-    case LoginStatus::NOT_LOGGED_IN:
-    case LoginStatus::LOCKED:
-      return false;
-    case LoginStatus::USER:
-    case LoginStatus::OWNER:
-    case LoginStatus::GUEST:
-    case LoginStatus::PUBLIC:
-    case LoginStatus::SUPERVISED:
-    case LoginStatus::KIOSK_APP:
-    case LoginStatus::ARC_KIOSK_APP:
-      return true;
-  }
-  NOTREACHED();
-  return false;
+  SessionController* session = Shell::Get()->session_controller();
+  return session->IsActiveUserSessionStarted() && !session->IsScreenLocked();
 }
 
 // Array of window container ids that contain visible windows to be counted for
diff --git a/ash/metrics/user_metrics_recorder_unittest.cc b/ash/metrics/user_metrics_recorder_unittest.cc
index e9f323c..4effbd16 100644
--- a/ash/metrics/user_metrics_recorder_unittest.cc
+++ b/ash/metrics/user_metrics_recorder_unittest.cc
@@ -8,15 +8,18 @@
 
 #include "ash/login_status.h"
 #include "ash/public/cpp/config.h"
+#include "ash/session/session_controller.h"
 #include "ash/shelf/shelf_model.h"
 #include "ash/shell.h"
 #include "ash/shell_port.h"
 #include "ash/test/ash_test_base.h"
-#include "ash/test/test_system_tray_delegate.h"
+#include "ash/test/test_session_controller_client.h"
 #include "ash/test/user_metrics_recorder_test_api.h"
 #include "ash/wm_window.h"
 #include "base/test/histogram_tester.h"
 
+using session_manager::SessionState;
+
 namespace ash {
 namespace {
 
@@ -35,117 +38,68 @@
 
 }  // namespace
 
-// Test fixture for the UserMetricsRecorder class.
-class UserMetricsRecorderTest : public test::AshTestBase {
+// Test fixture for the UserMetricsRecorder class. The tests manage their own
+// session state.
+class UserMetricsRecorderTest : public test::NoSessionAshTestBase {
  public:
-  UserMetricsRecorderTest();
-  ~UserMetricsRecorderTest() override;
+  UserMetricsRecorderTest() = default;
+  ~UserMetricsRecorderTest() override = default;
 
-  // test::AshTestBase:
-  void SetUp() override;
-  void TearDown() override;
-
-  // Sets the user login status.
-  void SetLoginStatus(LoginStatus login_status);
-
-  // Sets the current user session to be active or inactive in a desktop
-  // environment.
-  void SetUserInActiveDesktopEnvironment(bool is_active);
-
-  test::UserMetricsRecorderTestAPI* user_metrics_recorder_test_api() {
-    return user_metrics_recorder_test_api_.get();
-  }
+  test::UserMetricsRecorderTestAPI& test_api() { return test_api_; }
 
   base::HistogramTester& histograms() { return histograms_; }
 
  private:
   // Test API to access private members of the test target.
-  std::unique_ptr<test::UserMetricsRecorderTestAPI>
-      user_metrics_recorder_test_api_;
+  test::UserMetricsRecorderTestAPI test_api_;
 
   // Histogram value verifier.
   base::HistogramTester histograms_;
 
-  // The active SystemTrayDelegate. Not owned.
-  test::TestSystemTrayDelegate* test_system_tray_delegate_;
-
   DISALLOW_COPY_AND_ASSIGN(UserMetricsRecorderTest);
 };
 
-UserMetricsRecorderTest::UserMetricsRecorderTest() {}
-
-UserMetricsRecorderTest::~UserMetricsRecorderTest() {}
-
-void UserMetricsRecorderTest::SetUp() {
-  test::AshTestBase::SetUp();
-  user_metrics_recorder_test_api_.reset(new test::UserMetricsRecorderTestAPI());
-  test_system_tray_delegate_ = GetSystemTrayDelegate();
-}
-
-void UserMetricsRecorderTest::TearDown() {
-  test_system_tray_delegate_ = nullptr;
-  test::AshTestBase::TearDown();
-}
-
-void UserMetricsRecorderTest::SetLoginStatus(LoginStatus login_status) {
-  test_system_tray_delegate_->SetLoginStatus(login_status);
-}
-
-void UserMetricsRecorderTest::SetUserInActiveDesktopEnvironment(
-    bool is_active) {
-  if (is_active) {
-    SetLoginStatus(LoginStatus::USER);
-    ASSERT_TRUE(
-        user_metrics_recorder_test_api()->IsUserInActiveDesktopEnvironment());
-  } else {
-    SetLoginStatus(LoginStatus::LOCKED);
-    ASSERT_FALSE(
-        user_metrics_recorder_test_api()->IsUserInActiveDesktopEnvironment());
-  }
-}
-
 // Verifies the return value of IsUserInActiveDesktopEnvironment() for the
 // different login status values.
 TEST_F(UserMetricsRecorderTest, VerifyIsUserInActiveDesktopEnvironmentValues) {
-  SetLoginStatus(LoginStatus::NOT_LOGGED_IN);
-  EXPECT_FALSE(
-      user_metrics_recorder_test_api()->IsUserInActiveDesktopEnvironment());
+  SessionController* session = Shell::Get()->session_controller();
 
-  SetLoginStatus(LoginStatus::LOCKED);
-  EXPECT_FALSE(
-      user_metrics_recorder_test_api()->IsUserInActiveDesktopEnvironment());
+  // Environment is not active before login.
+  ASSERT_FALSE(session->IsActiveUserSessionStarted());
+  EXPECT_FALSE(test_api().IsUserInActiveDesktopEnvironment());
 
-  SetLoginStatus(LoginStatus::USER);
-  EXPECT_TRUE(
-      user_metrics_recorder_test_api()->IsUserInActiveDesktopEnvironment());
+  // Environment is active after login.
+  SetSessionStarted(true);
+  ASSERT_TRUE(session->IsActiveUserSessionStarted());
+  EXPECT_TRUE(test_api().IsUserInActiveDesktopEnvironment());
 
-  SetLoginStatus(LoginStatus::OWNER);
-  EXPECT_TRUE(
-      user_metrics_recorder_test_api()->IsUserInActiveDesktopEnvironment());
+  // Environment is not active when screen is locked.
+  test::TestSessionControllerClient* client = GetSessionControllerClient();
+  client->SetSessionState(SessionState::LOCKED);
+  ASSERT_TRUE(session->IsScreenLocked());
+  EXPECT_FALSE(test_api().IsUserInActiveDesktopEnvironment());
 
-  SetLoginStatus(LoginStatus::GUEST);
-  EXPECT_TRUE(
-      user_metrics_recorder_test_api()->IsUserInActiveDesktopEnvironment());
+  // Kiosk logins are not considered active.
+  client->Reset();
+  client->AddUserSession("app@kiosk-apps.device-local.localhost",
+                         user_manager::USER_TYPE_KIOSK_APP);
+  client->SetSessionState(session_manager::SessionState::ACTIVE);
+  EXPECT_FALSE(test_api().IsUserInActiveDesktopEnvironment());
 
-  SetLoginStatus(LoginStatus::PUBLIC);
-  EXPECT_TRUE(
-      user_metrics_recorder_test_api()->IsUserInActiveDesktopEnvironment());
-
-  SetLoginStatus(LoginStatus::SUPERVISED);
-  EXPECT_TRUE(
-      user_metrics_recorder_test_api()->IsUserInActiveDesktopEnvironment());
-
-  SetLoginStatus(LoginStatus::KIOSK_APP);
-  EXPECT_FALSE(
-      user_metrics_recorder_test_api()->IsUserInActiveDesktopEnvironment());
+  // Arc kiosk logins are not considered active.
+  client->Reset();
+  client->AddUserSession("app@arc-kiosk-apps.device-local.localhost",
+                         user_manager::USER_TYPE_ARC_KIOSK_APP);
+  client->SetSessionState(session_manager::SessionState::ACTIVE);
+  EXPECT_FALSE(test_api().IsUserInActiveDesktopEnvironment());
 }
 
 // Verifies that the IsUserInActiveDesktopEnvironment() dependent stats are not
 // recorded when a user is not active in a desktop environment.
 TEST_F(UserMetricsRecorderTest,
        VerifyStatsRecordedWhenUserNotInActiveDesktopEnvironment) {
-  SetUserInActiveDesktopEnvironment(false);
-  user_metrics_recorder_test_api()->RecordPeriodicMetrics();
+  ASSERT_FALSE(test_api().IsUserInActiveDesktopEnvironment());
+  test_api().RecordPeriodicMetrics();
 
   histograms().ExpectTotalCount(kAsh_NumberOfVisibleWindowsInPrimaryDisplay, 0);
   histograms().ExpectTotalCount(kAsh_Shelf_NumberOfItems, 0);
@@ -157,8 +111,9 @@
 // recorded when a user is active in a desktop environment.
 TEST_F(UserMetricsRecorderTest,
        VerifyStatsRecordedWhenUserInActiveDesktopEnvironment) {
-  SetUserInActiveDesktopEnvironment(true);
-  user_metrics_recorder_test_api()->RecordPeriodicMetrics();
+  SetSessionStarted(true);
+  ASSERT_TRUE(test_api().IsUserInActiveDesktopEnvironment());
+  test_api().RecordPeriodicMetrics();
 
   histograms().ExpectTotalCount(kAsh_NumberOfVisibleWindowsInPrimaryDisplay, 1);
   histograms().ExpectTotalCount(kAsh_Shelf_NumberOfItems, 1);
@@ -169,8 +124,8 @@
 // Verifies recording of stats which are always recorded by
 // RecordPeriodicMetrics.
 TEST_F(UserMetricsRecorderTest, VerifyStatsRecordedByRecordPeriodicMetrics) {
-  SetUserInActiveDesktopEnvironment(true);
-  user_metrics_recorder_test_api()->RecordPeriodicMetrics();
+  SetSessionStarted(true);
+  test_api().RecordPeriodicMetrics();
 
   histograms().ExpectTotalCount(kAsh_ActiveWindowShowTypeOverTime, 1);
 }
@@ -182,7 +137,7 @@
   if (Shell::GetAshConfig() == Config::MASH)
     return;
 
-  SetUserInActiveDesktopEnvironment(true);
+  SetSessionStarted(true);
 
   // Make sure the shelf contains the app list launcher button.
   ShelfModel* shelf_model = Shell::Get()->shelf_model();
@@ -204,7 +159,7 @@
   shelf_item.app_launch_id = AppLaunchId("app_id_5");
   shelf_model->Add(shelf_item);
 
-  user_metrics_recorder_test_api()->RecordPeriodicMetrics();
+  test_api().RecordPeriodicMetrics();
   histograms().ExpectBucketCount(kAsh_Shelf_NumberOfItems, 5, 1);
   histograms().ExpectBucketCount(kAsh_Shelf_NumberOfPinnedItems, 2, 1);
   histograms().ExpectBucketCount(kAsh_Shelf_NumberOfUnpinnedItems, 3, 1);
diff --git a/ash/mus/BUILD.gn b/ash/mus/BUILD.gn
index cd65be3..93e7fc9b 100644
--- a/ash/mus/BUILD.gn
+++ b/ash/mus/BUILD.gn
@@ -46,8 +46,6 @@
     "property_util.h",
     "screen_mus.cc",
     "screen_mus.h",
-    "shelf_delegate_mus.cc",
-    "shelf_delegate_mus.h",
     "shell_delegate_mus.cc",
     "shell_delegate_mus.h",
     "system_tray_delegate_mus.cc",
diff --git a/ash/mus/shelf_delegate_mus.cc b/ash/mus/shelf_delegate_mus.cc
deleted file mode 100644
index 265b89c..0000000
--- a/ash/mus/shelf_delegate_mus.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/mus/shelf_delegate_mus.h"
-
-#include "ash/shelf/shelf_controller.h"
-#include "ash/shell.h"
-#include "base/strings/string_util.h"
-
-namespace ash {
-
-ShelfDelegateMus::ShelfDelegateMus() {}
-
-ShelfDelegateMus::~ShelfDelegateMus() {}
-
-///////////////////////////////////////////////////////////////////////////////
-// ShelfDelegate:
-
-ShelfID ShelfDelegateMus::GetShelfIDForAppID(const std::string& app_id) {
-  if (Shell::Get()->shelf_controller()->app_id_to_shelf_id().count(app_id))
-    return Shell::Get()->shelf_controller()->app_id_to_shelf_id().at(app_id);
-  return 0;
-}
-
-ShelfID ShelfDelegateMus::GetShelfIDForAppIDAndLaunchID(
-    const std::string& app_id,
-    const std::string& launch_id) {
-  return ShelfDelegateMus::GetShelfIDForAppID(app_id);
-}
-
-const std::string& ShelfDelegateMus::GetAppIDForShelfID(ShelfID id) {
-  if (Shell::Get()->shelf_controller()->shelf_id_to_app_id().count(id))
-    return Shell::Get()->shelf_controller()->shelf_id_to_app_id().at(id);
-  return base::EmptyString();
-}
-
-void ShelfDelegateMus::PinAppWithID(const std::string& app_id) {
-  NOTIMPLEMENTED();
-}
-
-bool ShelfDelegateMus::IsAppPinned(const std::string& app_id) {
-  NOTIMPLEMENTED();
-  return false;
-}
-
-void ShelfDelegateMus::UnpinAppWithID(const std::string& app_id) {
-  NOTIMPLEMENTED();
-}
-
-}  // namespace ash
diff --git a/ash/mus/shelf_delegate_mus.h b/ash/mus/shelf_delegate_mus.h
deleted file mode 100644
index 520ccb35..0000000
--- a/ash/mus/shelf_delegate_mus.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_MUS_SHELF_DELEGATE_MUS_H_
-#define ASH_MUS_SHELF_DELEGATE_MUS_H_
-
-#include <string>
-
-#include "ash/public/cpp/shelf_types.h"
-#include "ash/shelf/shelf_delegate.h"
-#include "base/macros.h"
-
-namespace ash {
-
-// Manages communication between the mash shelf and the browser.
-class ShelfDelegateMus : public ShelfDelegate {
- public:
-  ShelfDelegateMus();
-  ~ShelfDelegateMus() override;
-
- private:
-  // ShelfDelegate:
-  ShelfID GetShelfIDForAppID(const std::string& app_id) override;
-  ShelfID GetShelfIDForAppIDAndLaunchID(const std::string& app_id,
-                                        const std::string& launch_id) override;
-  const std::string& GetAppIDForShelfID(ShelfID id) override;
-  void PinAppWithID(const std::string& app_id) override;
-  bool IsAppPinned(const std::string& app_id) override;
-  void UnpinAppWithID(const std::string& app_id) override;
-
-  DISALLOW_COPY_AND_ASSIGN(ShelfDelegateMus);
-};
-
-}  // namespace ash
-
-#endif  // ASH_MUS_SHELF_DELEGATE_MUS_H_
diff --git a/ash/mus/shell_delegate_mus.cc b/ash/mus/shell_delegate_mus.cc
index 63137bb..f0932ce 100644
--- a/ash/mus/shell_delegate_mus.cc
+++ b/ash/mus/shell_delegate_mus.cc
@@ -9,7 +9,6 @@
 #include "ash/gpu_support_stub.h"
 #include "ash/mus/accessibility_delegate_mus.h"
 #include "ash/mus/context_menu_mus.h"
-#include "ash/mus/shelf_delegate_mus.h"
 #include "ash/mus/system_tray_delegate_mus.h"
 #include "ash/mus/wallpaper_delegate_mus.h"
 #include "ash/palette_delegate.h"
@@ -103,8 +102,12 @@
   NOTIMPLEMENTED();
 }
 
-ShelfDelegate* ShellDelegateMus::CreateShelfDelegate(ShelfModel* model) {
-  return new ShelfDelegateMus();
+void ShellDelegateMus::ShelfInit() {
+  NOTIMPLEMENTED();
+}
+
+void ShellDelegateMus::ShelfShutdown() {
+  NOTIMPLEMENTED();
 }
 
 SystemTrayDelegate* ShellDelegateMus::CreateSystemTrayDelegate() {
diff --git a/ash/mus/shell_delegate_mus.h b/ash/mus/shell_delegate_mus.h
index c66ac31..f96f23e 100644
--- a/ash/mus/shell_delegate_mus.h
+++ b/ash/mus/shell_delegate_mus.h
@@ -33,7 +33,8 @@
   void Exit() override;
   keyboard::KeyboardUI* CreateKeyboardUI() override;
   void OpenUrlFromArc(const GURL& url) override;
-  ShelfDelegate* CreateShelfDelegate(ShelfModel* model) override;
+  void ShelfInit() override;
+  void ShelfShutdown() override;
   SystemTrayDelegate* CreateSystemTrayDelegate() override;
   std::unique_ptr<WallpaperDelegate> CreateWallpaperDelegate() override;
   SessionStateDelegate* CreateSessionStateDelegate() override;
diff --git a/ash/public/interfaces/system_tray.mojom b/ash/public/interfaces/system_tray.mojom
index 6504605..fc980e8 100644
--- a/ash/public/interfaces/system_tray.mojom
+++ b/ash/public/interfaces/system_tray.mojom
@@ -26,7 +26,9 @@
   // Shows an icon in the system tray indicating that a software update is
   // available. Once shown the icon persists until reboot. |severity| and
   // |factory_reset_required| are used to set the icon, color, and tooltip.
-  ShowUpdateIcon(UpdateSeverity severity, bool factory_reset_required);
+  ShowUpdateIcon(UpdateSeverity severity,
+                 bool factory_reset_required,
+                 UpdateType update_type);
 };
 
 // Allows ash system tray to control a client (e.g. Chrome browser). Requests
diff --git a/ash/public/interfaces/update.mojom b/ash/public/interfaces/update.mojom
index dd52e50..894d19a 100644
--- a/ash/public/interfaces/update.mojom
+++ b/ash/public/interfaces/update.mojom
@@ -15,3 +15,9 @@
   SEVERE,
   CRITICAL,
 };
+
+// The type of update being applied. Sets the string in the system tray.
+enum UpdateType {
+  FLASH,
+  SYSTEM,
+};
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 84c9912..d10013e 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -22,7 +22,6 @@
 #include "ash/root_window_settings.h"
 #include "ash/screen_util.h"
 #include "ash/session/session_controller.h"
-#include "ash/shelf/shelf_delegate.h"
 #include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shelf/shelf_window_targeter.h"
diff --git a/ash/session/session_controller.cc b/ash/session/session_controller.cc
index b546c92b..873f5776 100644
--- a/ash/session/session_controller.cc
+++ b/ash/session/session_controller.cc
@@ -14,6 +14,7 @@
 #include "base/command_line.h"
 #include "chromeos/chromeos_switches.h"
 #include "components/signin/core/account_id/account_id.h"
+#include "components/user_manager/user_type.h"
 #include "services/service_manager/public/cpp/connector.h"
 
 using session_manager::SessionState;
@@ -126,6 +127,23 @@
   return user_sessions_[index].get();
 }
 
+bool SessionController::IsUserSupervised() const {
+  if (!IsActiveUserSessionStarted())
+    return false;
+
+  user_manager::UserType active_user_type = GetUserSession(0)->type;
+  return active_user_type == user_manager::USER_TYPE_SUPERVISED ||
+         active_user_type == user_manager::USER_TYPE_CHILD;
+}
+
+bool SessionController::IsUserChild() const {
+  if (!IsActiveUserSessionStarted())
+    return false;
+
+  user_manager::UserType active_user_type = GetUserSession(0)->type;
+  return active_user_type == user_manager::USER_TYPE_CHILD;
+}
+
 void SessionController::LockScreen() {
   if (client_)
     client_->RequestLockScreen();
diff --git a/ash/session/session_controller.h b/ash/session/session_controller.h
index 5500b41..fa594e1 100644
--- a/ash/session/session_controller.h
+++ b/ash/session/session_controller.h
@@ -85,6 +85,13 @@
   // nullptr if no user session is found for the index.
   const mojom::UserSession* GetUserSession(UserIndex index) const;
 
+  // Returns true if the current user is supervised: has legacy supervised
+  // account or kid account.
+  bool IsUserSupervised() const;
+
+  // Returns true if the current user is a child account.
+  bool IsUserChild() const;
+
   // Locks the screen. The locking happens asynchronously.
   void LockScreen();
 
diff --git a/ash/session/session_controller_unittest.cc b/ash/session/session_controller_unittest.cc
index b90ee19..b287cc2 100644
--- a/ash/session/session_controller_unittest.cc
+++ b/ash/session/session_controller_unittest.cc
@@ -348,5 +348,26 @@
   }
 }
 
+TEST_F(SessionControllerTest, IsUserSupervised) {
+  mojom::UserSessionPtr session = mojom::UserSession::New();
+  session->session_id = 1u;
+  session->type = user_manager::USER_TYPE_SUPERVISED;
+  controller()->UpdateUserSession(std::move(session));
+
+  EXPECT_TRUE(controller()->IsUserSupervised());
+}
+
+TEST_F(SessionControllerTest, IsUserChild) {
+  mojom::UserSessionPtr session = mojom::UserSession::New();
+  session->session_id = 1u;
+  session->type = user_manager::USER_TYPE_CHILD;
+  controller()->UpdateUserSession(std::move(session));
+
+  EXPECT_TRUE(controller()->IsUserChild());
+
+  // Child accounts are supervised.
+  EXPECT_TRUE(controller()->IsUserSupervised());
+}
+
 }  // namespace
 }  // namespace ash
diff --git a/ash/shelf/shelf_delegate.h b/ash/shelf/shelf_delegate.h
deleted file mode 100644
index 3462409..0000000
--- a/ash/shelf/shelf_delegate.h
+++ /dev/null
@@ -1,53 +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 ASH_SHELF_SHELF_DELEGATE_H_
-#define ASH_SHELF_SHELF_DELEGATE_H_
-
-#include <string>
-
-#include "ash/ash_export.h"
-#include "ash/public/cpp/shelf_types.h"
-
-namespace ash {
-
-// Delegate shared by all shelf instances.
-class ASH_EXPORT ShelfDelegate {
- public:
-  virtual ~ShelfDelegate() {}
-
-  // Get the shelf ID from an application ID. Returns kInvalidShelfID if the
-  // app id is unknown, or has no associated ShelfID.
-  virtual ShelfID GetShelfIDForAppID(const std::string& app_id) = 0;
-
-  // Get the shelf ID from an application ID and a launch ID.
-  // The launch ID can be passed to an app when launched in order to support
-  // multiple shelf items per app. This id is used together with the app_id to
-  // uniquely identify each shelf item that has the same app_id.
-  // For example, a single virtualization app might want to show different
-  // shelf icons for different remote apps. Returns kInvalidShelfID if the app
-  // id is unknown or has no associated ShelfID.
-  virtual ShelfID GetShelfIDForAppIDAndLaunchID(
-      const std::string& app_id,
-      const std::string& launch_id) = 0;
-
-  // Get the application ID for a given shelf ID. Returns an empty string for
-  // an unknown or invalid ShelfID.
-  virtual const std::string& GetAppIDForShelfID(ShelfID id) = 0;
-
-  // Pins an app with |app_id| to shelf. A running instance will get pinned.
-  // In case there is no running instance a new shelf item is created and
-  // pinned.
-  virtual void PinAppWithID(const std::string& app_id) = 0;
-
-  // Check if the app with |app_id_| is pinned to the shelf.
-  virtual bool IsAppPinned(const std::string& app_id) = 0;
-
-  // Unpins app item with |app_id|.
-  virtual void UnpinAppWithID(const std::string& app_id) = 0;
-};
-
-}  // namespace ash
-
-#endif  // ASH_SHELF_SHELF_DELEGATE_H_
diff --git a/ash/shelf/shelf_model.cc b/ash/shelf/shelf_model.cc
index bfc37d2..afd6e125 100644
--- a/ash/shelf/shelf_model.cc
+++ b/ash/shelf/shelf_model.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 
+#include "ash/public/cpp/app_launch_id.h"
 #include "ash/public/cpp/shelf_item_delegate.h"
 #include "ash/shelf/shelf_model_observer.h"
 
@@ -41,12 +42,117 @@
   return ShelfItemTypeToWeight(a.type) < ShelfItemTypeToWeight(b.type);
 }
 
+// Returns shelf app id. Play Store app is mapped to ARC platform host app.
+// TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
+std::string GetShelfAppIdFromArcAppId(const std::string& arc_app_id) {
+  static const char kPlayStoreAppId[] = "gpkmicpkkebkmabiaedjognfppcchdfa";
+  static const char kArcHostAppId[] = "cnbgggchhmkkdmeppjobngjoejnihlei";
+  return arc_app_id == kPlayStoreAppId ? kArcHostAppId : arc_app_id;
+}
+
 }  // namespace
 
 ShelfModel::ShelfModel() : next_id_(1) {}
 
 ShelfModel::~ShelfModel() {}
 
+ShelfID ShelfModel::GetShelfIDForAppID(const std::string& app_id) {
+  // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
+  const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id);
+
+  if (shelf_app_id.empty())
+    return ash::kInvalidShelfID;
+
+  for (const ShelfItem& item : items_) {
+    // ShelfWindowWatcher handles app panel windows separately.
+    if (item.type != TYPE_APP_PANEL &&
+        item.app_launch_id.app_id() == shelf_app_id) {
+      return item.id;
+    }
+  }
+  return kInvalidShelfID;
+}
+
+ShelfID ShelfModel::GetShelfIDForAppIDAndLaunchID(
+    const std::string& app_id,
+    const std::string& launch_id) {
+  // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
+  const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id);
+
+  if (shelf_app_id.empty())
+    return ash::kInvalidShelfID;
+
+  for (const ShelfItem& item : items_) {
+    // ShelfWindowWatcher handles app panel windows separately.
+    if (item.type != TYPE_APP_PANEL &&
+        item.app_launch_id.app_id() == shelf_app_id &&
+        item.app_launch_id.launch_id() == launch_id) {
+      return item.id;
+    }
+  }
+  return kInvalidShelfID;
+}
+
+const std::string& ShelfModel::GetAppIDForShelfID(ShelfID id) {
+  ShelfItems::const_iterator item = ItemByID(id);
+  return item != items().end() ? item->app_launch_id.app_id()
+                               : base::EmptyString();
+}
+
+void ShelfModel::PinAppWithID(const std::string& app_id) {
+  // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
+  const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id);
+
+  // If the app is already pinned, do nothing and return.
+  if (IsAppPinned(shelf_app_id))
+    return;
+
+  // Convert an existing item to be pinned, or create a new pinned item.
+  const int index = ItemIndexByID(GetShelfIDForAppID(shelf_app_id));
+  if (index >= 0) {
+    ShelfItem item = items_[index];
+    DCHECK_EQ(item.type, TYPE_APP);
+    DCHECK(!item.pinned_by_policy);
+    item.type = TYPE_PINNED_APP;
+    Set(index, item);
+  } else if (!shelf_app_id.empty()) {
+    ash::ShelfItem item;
+    item.type = ash::TYPE_PINNED_APP;
+    item.app_launch_id = AppLaunchId(shelf_app_id);
+    Add(item);
+  }
+}
+
+bool ShelfModel::IsAppPinned(const std::string& app_id) {
+  // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
+  const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id);
+
+  const int index = ItemIndexByID(GetShelfIDForAppID(shelf_app_id));
+  return index >= 0 && (items_[index].type == TYPE_PINNED_APP ||
+                        items_[index].type == TYPE_BROWSER_SHORTCUT);
+}
+
+void ShelfModel::UnpinAppWithID(const std::string& app_id) {
+  // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
+  const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id);
+
+  // If the app is already not pinned, do nothing and return.
+  if (!IsAppPinned(shelf_app_id))
+    return;
+
+  // Remove the item if it is closed, or mark it as unpinned.
+  const int index = ItemIndexByID(GetShelfIDForAppID(shelf_app_id));
+  ShelfItem item = items_[index];
+  DCHECK_EQ(item.type, TYPE_PINNED_APP);
+  DCHECK(!item.pinned_by_policy);
+  if (item.status == ash::STATUS_CLOSED) {
+    RemoveItemAt(index);
+  } else {
+    item.type = TYPE_APP;
+    Set(index, item);
+  }
+}
+
 void ShelfModel::DestroyItemDelegates() {
   // Some ShelfItemDelegates access this model in their destructors and hence
   // need early cleanup.
diff --git a/ash/shelf/shelf_model.h b/ash/shelf/shelf_model.h
index b3bb09e..4f38b3e8 100644
--- a/ash/shelf/shelf_model.h
+++ b/ash/shelf/shelf_model.h
@@ -9,6 +9,7 @@
 #include <memory>
 
 #include "ash/ash_export.h"
+#include "ash/public/cpp/app_launch_id.h"
 #include "ash/public/cpp/shelf_item.h"
 #include "ash/public/interfaces/shelf.mojom.h"
 #include "base/macros.h"
@@ -25,6 +26,35 @@
   ShelfModel();
   ~ShelfModel();
 
+  // Get the shelf ID from an application ID. Returns kInvalidShelfID if the
+  // app id is unknown, or has no associated ShelfID.
+  ShelfID GetShelfIDForAppID(const std::string& app_id);
+
+  // Get the shelf ID from an application ID and a launch ID.
+  // The launch ID can be passed to an app when launched in order to support
+  // multiple shelf items per app. This id is used together with the app_id to
+  // uniquely identify each shelf item that has the same app_id.
+  // For example, a single virtualization app might want to show different
+  // shelf icons for different remote apps. Returns kInvalidShelfID if the app
+  // id is unknown or has no associated ShelfID.
+  ShelfID GetShelfIDForAppIDAndLaunchID(const std::string& app_id,
+                                        const std::string& launch_id);
+
+  // Get the application ID for a given shelf ID. Returns an empty string for
+  // an unknown or invalid ShelfID.
+  const std::string& GetAppIDForShelfID(ShelfID id);
+
+  // Pins an app with |app_id| to shelf. A running instance will get pinned.
+  // In case there is no running instance a new shelf item is created and
+  // pinned.
+  void PinAppWithID(const std::string& app_id);
+
+  // Check if the app with |app_id_| is pinned to the shelf.
+  bool IsAppPinned(const std::string& app_id);
+
+  // Unpins app item with |app_id|.
+  void UnpinAppWithID(const std::string& app_id);
+
   // Cleans up the ShelfItemDelegates.
   void DestroyItemDelegates();
 
@@ -66,9 +96,6 @@
   // Returns the id assigned to the next item added.
   ShelfID next_id() const { return next_id_; }
 
-  // Returns a reserved id which will not be used by the |ShelfModel|.
-  ShelfID reserve_external_id() { return next_id_++; }
-
   // Returns an iterator into items() for the item with the specified id, or
   // items().end() if there is no item with the specified id.
   ShelfItems::const_iterator ItemByID(ShelfID id) const;
diff --git a/ash/shelf/shelf_model_unittest.cc b/ash/shelf/shelf_model_unittest.cc
index 7aa70fe..def513db 100644
--- a/ash/shelf/shelf_model_unittest.cc
+++ b/ash/shelf/shelf_model_unittest.cc
@@ -255,19 +255,11 @@
   // Calling this function multiple times does not change the returned ID.
   EXPECT_EQ(model_->next_id(), id);
 
-  // Check that when we reserve a value it will be the previously retrieved ID,
-  // but it will not change the item count and retrieving the next ID should
-  // produce something new.
-  EXPECT_EQ(model_->reserve_external_id(), id);
-  EXPECT_EQ(1, model_->item_count());
-  ShelfID id2 = model_->next_id();
-  EXPECT_NE(id2, id);
-
-  // Adding another item to the list should also produce a new ID.
+  // Adding another item to the list should produce a new ID.
   ShelfItem item;
   item.type = TYPE_APP;
   model_->Add(item);
-  EXPECT_NE(model_->next_id(), id2);
+  EXPECT_NE(model_->next_id(), id);
 }
 
 // This verifies that converting an existing item into a lower weight category
@@ -300,4 +292,147 @@
   EXPECT_EQ(TYPE_APP, model_->items()[4].type);
 }
 
+// Test conversion between ShelfID and application [launch] ids.
+TEST_F(ShelfModelTest, IdentifierConversion) {
+  const std::string app_id1("app_id1");
+  const std::string launch_id("launch_id");
+  const ShelfID unknown_shelf_id = 123;
+
+  // Expect kInvalidShelfID and empty app ids for input not found in the model.
+  EXPECT_EQ(kInvalidShelfID, model_->GetShelfIDForAppID(std::string()));
+  EXPECT_EQ(kInvalidShelfID, model_->GetShelfIDForAppID(app_id1));
+  EXPECT_EQ(kInvalidShelfID,
+            model_->GetShelfIDForAppIDAndLaunchID(app_id1, std::string()));
+  EXPECT_EQ(kInvalidShelfID,
+            model_->GetShelfIDForAppIDAndLaunchID(app_id1, launch_id));
+  EXPECT_TRUE(model_->GetAppIDForShelfID(kInvalidShelfID).empty());
+  EXPECT_TRUE(model_->GetAppIDForShelfID(unknown_shelf_id).empty());
+
+  // Add an example app with an app id and a launch id.
+  ShelfItem item;
+  item.type = TYPE_PINNED_APP;
+  item.app_launch_id = AppLaunchId(app_id1, launch_id);
+  const ShelfID assigned_shelf_id1 = model_->next_id();
+  const int index = model_->Add(item);
+
+  // Ensure the item ids can be found and converted as expected.
+  EXPECT_NE(kInvalidShelfID, assigned_shelf_id1);
+  EXPECT_EQ(assigned_shelf_id1, model_->GetShelfIDForAppID(app_id1));
+  EXPECT_EQ(assigned_shelf_id1,
+            model_->GetShelfIDForAppIDAndLaunchID(app_id1, launch_id));
+  EXPECT_EQ(app_id1, model_->GetAppIDForShelfID(assigned_shelf_id1));
+
+  // Removing the example app should again yield invalid ids.
+  model_->RemoveItemAt(index);
+  EXPECT_EQ(kInvalidShelfID, model_->GetShelfIDForAppID(app_id1));
+  EXPECT_EQ(kInvalidShelfID,
+            model_->GetShelfIDForAppIDAndLaunchID(app_id1, launch_id));
+  EXPECT_TRUE(model_->GetAppIDForShelfID(assigned_shelf_id1).empty());
+
+  // Add an example app with a different app id and no launch id.
+  const std::string app_id2("app_id2");
+  item.app_launch_id = AppLaunchId(app_id2);
+  const ShelfID assigned_shelf_id2 = model_->next_id();
+  model_->Add(item);
+
+  // Ensure the item ids can be found and converted as expected.
+  EXPECT_NE(kInvalidShelfID, assigned_shelf_id2);
+  EXPECT_NE(assigned_shelf_id1, assigned_shelf_id2);
+  EXPECT_EQ(assigned_shelf_id2, model_->GetShelfIDForAppID(app_id2));
+  EXPECT_EQ(assigned_shelf_id2,
+            model_->GetShelfIDForAppIDAndLaunchID(app_id2, std::string()));
+  EXPECT_EQ(kInvalidShelfID,
+            model_->GetShelfIDForAppIDAndLaunchID(app_id2, launch_id));
+  EXPECT_EQ(app_id2, model_->GetAppIDForShelfID(assigned_shelf_id2));
+}
+
+// Test pinning and unpinning a closed app, and checking if it is pinned.
+TEST_F(ShelfModelTest, ClosedAppPinning) {
+  const std::string app_id("app_id");
+
+  // Check the initial state.
+  EXPECT_FALSE(model_->IsAppPinned(app_id));
+  EXPECT_EQ(1, model_->item_count());
+
+  // Pinning a previously unknown app should add an item.
+  model_->PinAppWithID(app_id);
+  EXPECT_TRUE(model_->IsAppPinned(app_id));
+  EXPECT_EQ(2, model_->item_count());
+  EXPECT_EQ(TYPE_PINNED_APP, model_->items()[1].type);
+  EXPECT_EQ(app_id, model_->items()[1].app_launch_id.app_id());
+
+  // Pinning the same app id again should have no change.
+  model_->PinAppWithID(app_id);
+  EXPECT_TRUE(model_->IsAppPinned(app_id));
+  EXPECT_EQ(2, model_->item_count());
+  EXPECT_EQ(TYPE_PINNED_APP, model_->items()[1].type);
+  EXPECT_EQ(app_id, model_->items()[1].app_launch_id.app_id());
+
+  // Unpinning the app should remove the item.
+  model_->UnpinAppWithID(app_id);
+  EXPECT_FALSE(model_->IsAppPinned(app_id));
+  EXPECT_EQ(1, model_->item_count());
+
+  // Unpinning the same app id again should have no change.
+  model_->UnpinAppWithID(app_id);
+  EXPECT_FALSE(model_->IsAppPinned(app_id));
+  EXPECT_EQ(1, model_->item_count());
+}
+
+// Test pinning and unpinning a running app, and checking if it is pinned.
+TEST_F(ShelfModelTest, RunningAppPinning) {
+  const std::string app_id("app_id");
+
+  // Check the initial state.
+  EXPECT_FALSE(model_->IsAppPinned(app_id));
+  EXPECT_EQ(1, model_->item_count());
+
+  // Add an example running app.
+  ShelfItem item;
+  item.type = TYPE_APP;
+  item.status = STATUS_RUNNING;
+  item.app_launch_id = AppLaunchId(app_id);
+  const ShelfID assigned_shelf_id = model_->next_id();
+  const int index = model_->Add(item);
+
+  // The item should be added but not pinned.
+  EXPECT_FALSE(model_->IsAppPinned(app_id));
+  EXPECT_EQ(2, model_->item_count());
+  EXPECT_EQ(TYPE_APP, model_->items()[index].type);
+  EXPECT_EQ(app_id, model_->items()[index].app_launch_id.app_id());
+  EXPECT_EQ(assigned_shelf_id, model_->items()[index].id);
+
+  // Pinning the item should just change its type.
+  model_->PinAppWithID(app_id);
+  EXPECT_TRUE(model_->IsAppPinned(app_id));
+  EXPECT_EQ(2, model_->item_count());
+  EXPECT_EQ(TYPE_PINNED_APP, model_->items()[index].type);
+  EXPECT_EQ(app_id, model_->items()[index].app_launch_id.app_id());
+  EXPECT_EQ(assigned_shelf_id, model_->items()[index].id);
+
+  // Pinning the same app id again should have no change.
+  model_->PinAppWithID(app_id);
+  EXPECT_TRUE(model_->IsAppPinned(app_id));
+  EXPECT_EQ(2, model_->item_count());
+  EXPECT_EQ(TYPE_PINNED_APP, model_->items()[index].type);
+  EXPECT_EQ(app_id, model_->items()[index].app_launch_id.app_id());
+  EXPECT_EQ(assigned_shelf_id, model_->items()[index].id);
+
+  // Unpinning the app should leave the item unpinnned but running.
+  model_->UnpinAppWithID(app_id);
+  EXPECT_FALSE(model_->IsAppPinned(app_id));
+  EXPECT_EQ(2, model_->item_count());
+  EXPECT_EQ(TYPE_APP, model_->items()[index].type);
+  EXPECT_EQ(app_id, model_->items()[index].app_launch_id.app_id());
+  EXPECT_EQ(assigned_shelf_id, model_->items()[index].id);
+
+  // Unpinning the same app id again should have no change.
+  model_->UnpinAppWithID(app_id);
+  EXPECT_FALSE(model_->IsAppPinned(app_id));
+  EXPECT_EQ(2, model_->item_count());
+  EXPECT_EQ(TYPE_APP, model_->items()[index].type);
+  EXPECT_EQ(app_id, model_->items()[index].app_launch_id.app_id());
+  EXPECT_EQ(assigned_shelf_id, model_->items()[index].id);
+}
+
 }  // namespace ash
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc
index ed9850e7..9be5a085 100644
--- a/ash/shelf/shelf_view.cc
+++ b/ash/shelf/shelf_view.cc
@@ -18,7 +18,6 @@
 #include "ash/shelf/shelf_application_menu_model.h"
 #include "ash/shelf/shelf_button.h"
 #include "ash/shelf/shelf_constants.h"
-#include "ash/shelf/shelf_delegate.h"
 #include "ash/shelf/shelf_model.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shelf/wm_shelf.h"
@@ -239,11 +238,9 @@
 const int ShelfView::kMinimumDragDistance = 8;
 
 ShelfView::ShelfView(ShelfModel* model,
-                     ShelfDelegate* delegate,
                      WmShelf* wm_shelf,
                      ShelfWidget* shelf_widget)
     : model_(model),
-      delegate_(delegate),
       wm_shelf_(wm_shelf),
       shelf_widget_(shelf_widget),
       view_model_(new views::ViewModel),
@@ -271,7 +268,6 @@
       last_pressed_index_(-1),
       weak_factory_(this) {
   DCHECK(model_);
-  DCHECK(delegate_);
   DCHECK(wm_shelf_);
   DCHECK(shelf_widget_);
   bounds_animator_.reset(new views::BoundsAnimator(this));
@@ -560,18 +556,16 @@
   CancelDrag(-1);
   drag_and_drop_item_pinned_ = false;
   drag_and_drop_app_id_ = app_id;
-  drag_and_drop_shelf_id_ =
-      delegate_->GetShelfIDForAppID(drag_and_drop_app_id_);
+  drag_and_drop_shelf_id_ = model_->GetShelfIDForAppID(drag_and_drop_app_id_);
   // Check if the application is known and pinned - if not, we have to pin it so
   // that we can re-arrange the shelf order accordingly. Note that items have
   // to be pinned to give them the same (order) possibilities as a shortcut.
   // When an item is dragged from overflow to shelf, IsShowingOverflowBubble()
   // returns true. At this time, we don't need to pin the item.
   if (!IsShowingOverflowBubble() &&
-      (!drag_and_drop_shelf_id_ || !delegate_->IsAppPinned(app_id))) {
-    delegate_->PinAppWithID(app_id);
-    drag_and_drop_shelf_id_ =
-        delegate_->GetShelfIDForAppID(drag_and_drop_app_id_);
+      (!drag_and_drop_shelf_id_ || !model_->IsAppPinned(app_id))) {
+    model_->PinAppWithID(app_id);
+    drag_and_drop_shelf_id_ = model_->GetShelfIDForAppID(drag_and_drop_app_id_);
     if (!drag_and_drop_shelf_id_)
       return false;
     drag_and_drop_item_pinned_ = true;
@@ -629,7 +623,7 @@
 
   // Either destroy the temporarily created item - or - make the item visible.
   if (drag_and_drop_item_pinned_ && cancel) {
-    delegate_->UnpinAppWithID(drag_and_drop_app_id_);
+    model_->UnpinAppWithID(drag_and_drop_app_id_);
   } else if (drag_and_drop_view) {
     if (cancel) {
       // When a hosted drag gets canceled, the item can remain in the same slot
@@ -1063,7 +1057,7 @@
   int current_index = view_model_->GetIndexOfView(drag_view_);
   DCHECK_NE(-1, current_index);
   std::string dragged_app_id =
-      delegate_->GetAppIDForShelfID(model_->items()[current_index].id);
+      model_->GetAppIDForShelfID(model_->items()[current_index].id);
 
   gfx::Point screen_location =
       WmWindow::Get(GetWidget()->GetNativeWindow())
@@ -1186,8 +1180,8 @@
       // Make sure the item stays invisible upon removal.
       drag_view_->SetVisible(false);
       std::string app_id =
-          delegate_->GetAppIDForShelfID(model_->items()[current_index].id);
-      delegate_->UnpinAppWithID(app_id);
+          model_->GetAppIDForShelfID(model_->items()[current_index].id);
+      model_->UnpinAppWithID(app_id);
     }
   }
   if (cancel || snap_back) {
@@ -1229,10 +1223,9 @@
     return NOT_REMOVABLE;
 
   // Note: Only pinned app shortcuts can be removed!
-  std::string app_id = delegate_->GetAppIDForShelfID(model_->items()[index].id);
-  return (type == TYPE_PINNED_APP && delegate_->IsAppPinned(app_id))
-             ? REMOVABLE
-             : DRAGGABLE;
+  std::string app_id = model_->GetAppIDForShelfID(model_->items()[index].id);
+  return (type == TYPE_PINNED_APP && model_->IsAppPinned(app_id)) ? REMOVABLE
+                                                                  : DRAGGABLE;
 }
 
 bool ShelfView::SameDragType(ShelfItemType typea, ShelfItemType typeb) const {
@@ -1281,8 +1274,7 @@
   if (!overflow_bubble_)
     overflow_bubble_.reset(new OverflowBubble(wm_shelf_));
 
-  ShelfView* overflow_view =
-      new ShelfView(model_, delegate_, wm_shelf_, shelf_widget_);
+  ShelfView* overflow_view = new ShelfView(model_, wm_shelf_, shelf_widget_);
   overflow_view->overflow_mode_ = true;
   overflow_view->Init();
   overflow_view->set_owner_overflow_bubble(overflow_bubble_.get());
@@ -1538,6 +1530,13 @@
 
 void ShelfView::ShelfItemChanged(int model_index, const ShelfItem& old_item) {
   const ShelfItem& item(model_->items()[model_index]);
+
+  // Bail if the view and shelf sizes do not match. ShelfItemChanged may be
+  // called here before ShelfItemAdded, due to ChromeLauncherController's
+  // item initialization, which calls SetItem during ShelfItemAdded.
+  if (static_cast<int>(model_->items().size()) != view_model_->view_size())
+    return;
+
   if (old_item.type != item.type) {
     // Type changed, swap the views.
     model_index = CancelDrag(model_index);
diff --git a/ash/shelf/shelf_view.h b/ash/shelf/shelf_view.h
index e0692e1..1a5ec0f 100644
--- a/ash/shelf/shelf_view.h
+++ b/ash/shelf/shelf_view.h
@@ -44,7 +44,6 @@
 class OverflowButton;
 class ScopedRootWindowForNewWindows;
 class ShelfButton;
-class ShelfDelegate;
 class ShelfModel;
 struct ShelfItem;
 class ShelfWidget;
@@ -71,7 +70,6 @@
                              public app_list::ApplicationDragAndDropHost {
  public:
   ShelfView(ShelfModel* model,
-            ShelfDelegate* delegate,
             WmShelf* wm_shelf,
             ShelfWidget* shelf_widget);
   ~ShelfView() override;
@@ -352,9 +350,6 @@
   // The model; owned by Launcher.
   ShelfModel* model_;
 
-  // Delegate; owned by Launcher.
-  ShelfDelegate* delegate_;
-
   // The shelf controller; owned by RootWindowController.
   WmShelf* wm_shelf_;
 
diff --git a/ash/shelf/shelf_widget.cc b/ash/shelf/shelf_widget.cc
index abaf370..3d07828 100644
--- a/ash/shelf/shelf_widget.cc
+++ b/ash/shelf/shelf_widget.cc
@@ -11,7 +11,6 @@
 #include "ash/shelf/app_list_button.h"
 #include "ash/shelf/shelf_background_animator_observer.h"
 #include "ash/shelf/shelf_constants.h"
-#include "ash/shelf/shelf_delegate.h"
 #include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shelf/shelf_view.h"
 #include "ash/shelf/wm_shelf.h"
@@ -229,9 +228,7 @@
 
 ShelfView* ShelfWidget::CreateShelfView() {
   DCHECK(!shelf_view_);
-
-  shelf_view_ = new ShelfView(Shell::Get()->shelf_model(),
-                              Shell::Get()->shelf_delegate(), wm_shelf_, this);
+  shelf_view_ = new ShelfView(Shell::Get()->shelf_model(), wm_shelf_, this);
   shelf_view_->Init();
   GetContentsView()->AddChildView(shelf_view_);
   return shelf_view_;
diff --git a/ash/shelf/wm_shelf.cc b/ash/shelf/wm_shelf.cc
index 79ee471..bd0cbd6 100644
--- a/ash/shelf/wm_shelf.cc
+++ b/ash/shelf/wm_shelf.cc
@@ -8,6 +8,7 @@
 #include "ash/public/cpp/shelf_item_delegate.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/root_window_controller.h"
+#include "ash/session/session_controller.h"
 #include "ash/shelf/shelf_bezel_event_handler.h"
 #include "ash/shelf/shelf_controller.h"
 #include "ash/shelf/shelf_layout_manager.h"
@@ -75,7 +76,7 @@
 
 // static
 bool WmShelf::CanChangeShelfAlignment() {
-  if (Shell::Get()->system_tray_delegate()->IsUserSupervised())
+  if (Shell::Get()->session_controller()->IsUserSupervised())
     return false;
 
   LoginStatus login_status =
diff --git a/ash/shell.cc b/ash/shell.cc
index 111ffaf..9bc373d 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -55,7 +55,6 @@
 #include "ash/session/session_controller.h"
 #include "ash/session/session_state_delegate.h"
 #include "ash/shelf/shelf_controller.h"
-#include "ash/shelf/shelf_delegate.h"
 #include "ash/shelf/shelf_model.h"
 #include "ash/shelf/shelf_window_watcher.h"
 #include "ash/shelf/wm_shelf.h"
@@ -408,8 +407,13 @@
   // Must occur after SessionController creation and user login.
   DCHECK(session_controller());
   DCHECK_GT(session_controller()->NumberOfLoggedInUsers(), 0);
-  CreateShelfDelegate();
 
+  // Notify the ShellDelegate that the shelf is being initialized.
+  // TODO(msw): Refine ChromeLauncherControllerImpl lifetime management.
+  shell_delegate_->ShelfInit();
+
+  if (!shelf_window_watcher_)
+    shelf_window_watcher_ = base::MakeUnique<ShelfWindowWatcher>(shelf_model());
   for (WmWindow* root_window : shell_port_->GetAllRootWindows())
     root_window->GetRootWindowController()->CreateShelfView();
 }
@@ -724,8 +728,9 @@
   // shelf items in Chrome) so explicitly shutdown early.
   shelf_model()->DestroyItemDelegates();
 
-  // Must be destroyed before FocusController.
-  shelf_delegate_.reset();
+  // Notify the ShellDelegate that the shelf is shutting down.
+  // TODO(msw): Refine ChromeLauncherControllerImpl lifetime management.
+  shell_delegate_->ShelfShutdown();
 
   // Removes itself as an observer of |pref_service_|.
   shelf_controller_.reset();
@@ -1161,19 +1166,6 @@
   }
 }
 
-void Shell::CreateShelfDelegate() {
-  // May be called multiple times as shelves are created and destroyed.
-  if (shelf_delegate_)
-    return;
-  // Must occur after SessionController creation and user login because
-  // Chrome's implementation of ShelfDelegate assumes it can get information
-  // about multi-profile login state.
-  DCHECK(session_controller());
-  DCHECK_GT(session_controller()->NumberOfLoggedInUsers(), 0);
-  shelf_delegate_.reset(shell_delegate_->CreateShelfDelegate(shelf_model()));
-  shelf_window_watcher_ = base::MakeUnique<ShelfWindowWatcher>(shelf_model());
-}
-
 bool Shell::CanWindowReceiveEvents(aura::Window* window) {
   RootWindowControllerList controllers = GetAllRootWindowControllers();
   for (RootWindowController* controller : controllers) {
diff --git a/ash/shell.h b/ash/shell.h
index 71eaef5..27fdd012 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -140,7 +140,6 @@
 class SessionController;
 class SessionStateDelegate;
 class ShelfController;
-class ShelfDelegate;
 class ShelfModel;
 class ShelfWindowWatcher;
 class ShellDelegate;
@@ -328,7 +327,6 @@
   }
   SessionController* session_controller() { return session_controller_.get(); }
   ShelfController* shelf_controller() { return shelf_controller_.get(); }
-  ShelfDelegate* shelf_delegate() { return shelf_delegate_.get(); }
   ShelfModel* shelf_model();
   ShutdownController* shutdown_controller() {
     return shutdown_controller_.get();
@@ -609,8 +607,6 @@
   void SetSystemTrayDelegate(std::unique_ptr<SystemTrayDelegate> delegate);
   void DeleteSystemTrayDelegate();
 
-  void CreateShelfDelegate();
-
   // Destroys all child windows including widgets across all roots.
   void CloseAllRootWindowChildWindows();
 
@@ -677,7 +673,6 @@
   std::unique_ptr<ResizeShadowController> resize_shadow_controller_;
   std::unique_ptr<SessionController> session_controller_;
   std::unique_ptr<ShelfController> shelf_controller_;
-  std::unique_ptr<ShelfDelegate> shelf_delegate_;
   std::unique_ptr<ShelfWindowWatcher> shelf_window_watcher_;
   std::unique_ptr<ShellDelegate> shell_delegate_;
   std::unique_ptr<ShutdownController> shutdown_controller_;
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc
index 0532775..8aab1ae 100644
--- a/ash/shell/shell_delegate_impl.cc
+++ b/ash/shell/shell_delegate_impl.cc
@@ -16,7 +16,6 @@
 #include "ash/shell/example_factory.h"
 #include "ash/shell/toplevel_window.h"
 #include "ash/test/test_keyboard_ui.h"
-#include "ash/test/test_shelf_delegate.h"
 #include "ash/test/test_system_tray_delegate.h"
 #include "ash/wm/window_state.h"
 #include "base/memory/ptr_util.h"
@@ -122,9 +121,9 @@
 
 void ShellDelegateImpl::OpenUrlFromArc(const GURL& url) {}
 
-ShelfDelegate* ShellDelegateImpl::CreateShelfDelegate(ShelfModel* model) {
-  return new test::TestShelfDelegate();
-}
+void ShellDelegateImpl::ShelfInit() {}
+
+void ShellDelegateImpl::ShelfShutdown() {}
 
 SystemTrayDelegate* ShellDelegateImpl::CreateSystemTrayDelegate() {
   return new test::TestSystemTrayDelegate;
diff --git a/ash/shell/shell_delegate_impl.h b/ash/shell/shell_delegate_impl.h
index 3f953ba..77312047 100644
--- a/ash/shell/shell_delegate_impl.h
+++ b/ash/shell/shell_delegate_impl.h
@@ -35,7 +35,8 @@
   void Exit() override;
   keyboard::KeyboardUI* CreateKeyboardUI() override;
   void OpenUrlFromArc(const GURL& url) override;
-  ShelfDelegate* CreateShelfDelegate(ShelfModel* model) override;
+  void ShelfInit() override;
+  void ShelfShutdown() override;
   SystemTrayDelegate* CreateSystemTrayDelegate() override;
   std::unique_ptr<WallpaperDelegate> CreateWallpaperDelegate() override;
   SessionStateDelegate* CreateSessionStateDelegate() override;
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h
index ce83773..2ab7088 100644
--- a/ash/shell_delegate.h
+++ b/ash/shell_delegate.h
@@ -36,8 +36,6 @@
 class GPUSupport;
 class PaletteDelegate;
 class SessionStateDelegate;
-class ShelfDelegate;
-class ShelfModel;
 class SystemTrayDelegate;
 struct ShelfItem;
 class WallpaperDelegate;
@@ -89,8 +87,10 @@
   // Opens the |url| in a new browser tab.
   virtual void OpenUrlFromArc(const GURL& url) = 0;
 
-  // Creates a new ShelfDelegate. Shell takes ownership of the returned value.
-  virtual ShelfDelegate* CreateShelfDelegate(ShelfModel* model) = 0;
+  // Functions called when the shelf is initialized and shut down.
+  // TODO(msw): Refine ChromeLauncherControllerImpl lifetime management.
+  virtual void ShelfInit() = 0;
+  virtual void ShelfShutdown() = 0;
 
   // Creates a system-tray delegate. Shell takes ownership of the delegate.
   virtual SystemTrayDelegate* CreateSystemTrayDelegate() = 0;
diff --git a/ash/system/supervised/tray_supervised_user.cc b/ash/system/supervised/tray_supervised_user.cc
index 8db5f66..fe336b82 100644
--- a/ash/system/supervised/tray_supervised_user.cc
+++ b/ash/system/supervised/tray_supervised_user.cc
@@ -8,6 +8,7 @@
 
 #include "ash/login_status.h"
 #include "ash/resources/vector_icons/vector_icons.h"
+#include "ash/session/session_controller.h"
 #include "ash/shell.h"
 #include "ash/system/system_notifier.h"
 #include "ash/system/tray/label_tray_view.h"
@@ -55,8 +56,7 @@
 
 views::View* TraySupervisedUser::CreateDefaultView(LoginStatus status) {
   DCHECK(!tray_view_);
-  SystemTrayDelegate* delegate = Shell::Get()->system_tray_delegate();
-  if (!delegate->IsUserSupervised())
+  if (!Shell::Get()->session_controller()->IsUserSupervised())
     return nullptr;
 
   tray_view_ = new LabelTrayView(this, GetSupervisedUserIcon());
@@ -74,12 +74,13 @@
 
 void TraySupervisedUser::UpdateAfterLoginStatusChange(LoginStatus status) {
   SystemTrayDelegate* delegate = Shell::Get()->system_tray_delegate();
+  SessionController* session = Shell::Get()->session_controller();
 
-  bool is_user_supervised = delegate->IsUserSupervised();
+  const bool is_user_supervised = session->IsUserSupervised();
   if (status == status_ && is_user_supervised == is_user_supervised_)
     return;
 
-  if (is_user_supervised && !delegate->IsUserChild() &&
+  if (is_user_supervised && !session->IsUserChild() &&
       status_ != LoginStatus::LOCKED &&
       !delegate->GetSupervisedUserManager().empty()) {
     CreateOrUpdateSupervisedWarningNotification();
@@ -111,7 +112,7 @@
   SystemTrayDelegate* delegate = Shell::Get()->system_tray_delegate();
   std::string manager_name = delegate->GetSupervisedUserManager();
   if (!manager_name.empty()) {
-    if (!delegate->IsUserChild() &&
+    if (!Shell::Get()->session_controller()->IsUserChild() &&
         !message_center::MessageCenter::Get()->FindVisibleNotificationById(
             kNotificationId)) {
       CreateOrUpdateSupervisedWarningNotification();
@@ -121,12 +122,10 @@
 }
 
 const gfx::VectorIcon& TraySupervisedUser::GetSupervisedUserIcon() const {
-  SystemTrayDelegate* delegate = Shell::Get()->system_tray_delegate();
-
   // Not intended to be used for non-supervised users.
-  DCHECK(delegate->IsUserSupervised());
+  DCHECK(Shell::Get()->session_controller()->IsUserSupervised());
 
-  if (delegate->IsUserChild())
+  if (Shell::Get()->session_controller()->IsUserChild())
     return kSystemMenuChildUserIcon;
   return kSystemMenuSupervisedUserIcon;
 }
diff --git a/ash/system/supervised/tray_supervised_user_unittest.cc b/ash/system/supervised/tray_supervised_user_unittest.cc
index 61d3d48..37c96c96 100644
--- a/ash/system/supervised/tray_supervised_user_unittest.cc
+++ b/ash/system/supervised/tray_supervised_user_unittest.cc
@@ -5,7 +5,10 @@
 #include "ash/system/supervised/tray_supervised_user.h"
 
 #include "ash/login_status.h"
-#include "ash/test/ash_test.h"
+#include "ash/session/session_controller.h"
+#include "ash/shell.h"
+#include "ash/test/ash_test_base.h"
+#include "ash/test/test_session_controller_client.h"
 #include "ash/test/test_system_tray_delegate.h"
 #include "ui/message_center/message_center.h"
 #include "ui/message_center/notification.h"
@@ -16,7 +19,8 @@
 
 namespace ash {
 
-class TraySupervisedUserTest : public AshTest {
+// Tests handle creating their own sessions.
+class TraySupervisedUserTest : public test::NoSessionAshTestBase {
  public:
   TraySupervisedUserTest() {}
   ~TraySupervisedUserTest() override {}
@@ -40,33 +44,19 @@
   return NULL;
 }
 
-class TraySupervisedUserInitialTest : public TraySupervisedUserTest {
- public:
-  // Set the initial login status to supervised-user before AshTest::SetUp()
-  // constructs the system tray.
-  TraySupervisedUserInitialTest()
-      : scoped_initial_login_status_(LoginStatus::SUPERVISED) {}
-  ~TraySupervisedUserInitialTest() override {}
-
- private:
-  test::ScopedInitialLoginStatus scoped_initial_login_status_;
-
-  DISALLOW_COPY_AND_ASSIGN(TraySupervisedUserInitialTest);
-};
-
+// Verifies that when a supervised user logs in that a warning notification is
+// shown and ash does not crash.
 TEST_F(TraySupervisedUserTest, SupervisedUserHasNotification) {
-  test::TestSystemTrayDelegate* delegate = GetSystemTrayDelegate();
-  delegate->SetLoginStatus(LoginStatus::SUPERVISED);
+  SessionController* session = Shell::Get()->session_controller();
+  ASSERT_EQ(LoginStatus::NOT_LOGGED_IN, session->login_status());
+  ASSERT_FALSE(session->IsActiveUserSessionStarted());
 
-  message_center::Notification* notification = GetPopup();
-  ASSERT_NE(static_cast<message_center::Notification*>(NULL), notification);
-  EXPECT_EQ(static_cast<int>(message_center::SYSTEM_PRIORITY),
-            notification->rich_notification_data().priority);
-}
+  // Simulate a supervised user logging in.
+  test::TestSessionControllerClient* client = GetSessionControllerClient();
+  client->Reset();
+  client->AddUserSession("user1@test.com", user_manager::USER_TYPE_SUPERVISED);
+  client->SetSessionState(session_manager::SessionState::ACTIVE);
 
-TEST_F(TraySupervisedUserInitialTest, SupervisedUserNoCrash) {
-  // Initial login status is already SUPERVISED, which should create
-  // the notification and should not cause crashes.
   message_center::Notification* notification = GetPopup();
   ASSERT_NE(static_cast<message_center::Notification*>(NULL), notification);
   EXPECT_EQ(static_cast<int>(message_center::SYSTEM_PRIORITY),
diff --git a/ash/system/tiles/tray_tiles_unittest.cc b/ash/system/tiles/tray_tiles_unittest.cc
index afee1f0..30fa094 100644
--- a/ash/system/tiles/tray_tiles_unittest.cc
+++ b/ash/system/tiles/tray_tiles_unittest.cc
@@ -7,6 +7,7 @@
 #include "ash/system/tiles/tiles_default_view.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/test/test_session_controller_client.h"
+#include "components/user_manager/user_type.h"
 #include "ui/views/controls/button/custom_button.h"
 #include "ui/views/view.h"
 
@@ -99,10 +100,11 @@
 
 // Settings buttons are disabled when adding a supervised user.
 TEST_F(TrayTilesTest, ButtonStatesSupervisedUserFlow) {
-  // Simulate a supervised user session with disabled settings.
+  // Simulate the add supervised user flow, which is a regular user session but
+  // with web UI settings disabled.
   const bool enable_settings = false;
-  GetSessionControllerClient()->AddUserSession("foo@example.com",
-                                               enable_settings);
+  GetSessionControllerClient()->AddUserSession(
+      "foo@example.com", user_manager::USER_TYPE_REGULAR, enable_settings);
   std::unique_ptr<views::View> default_view(
       tray_tiles()->CreateDefaultViewForTesting());
   EXPECT_EQ(Button::STATE_DISABLED, GetSettingsButton()->state());
diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc
index d6a15e8..5139ec0 100644
--- a/ash/system/tray/system_tray.cc
+++ b/ash/system/tray/system_tray.cc
@@ -207,21 +207,7 @@
 
 // SystemTray
 
-SystemTray::SystemTray(WmShelf* wm_shelf)
-    : TrayBackgroundView(wm_shelf, true),
-      web_notification_tray_(nullptr),
-      detailed_item_(nullptr),
-      default_bubble_height_(0),
-      full_system_tray_menu_(false),
-      tray_accessibility_(nullptr),
-      tray_audio_(nullptr),
-      tray_cast_(nullptr),
-      tray_network_(nullptr),
-      tray_tiles_(nullptr),
-      tray_system_info_(nullptr),
-      tray_update_(nullptr),
-      screen_capture_tray_item_(nullptr),
-      screen_share_tray_item_(nullptr) {
+SystemTray::SystemTray(WmShelf* wm_shelf) : TrayBackgroundView(wm_shelf, true) {
   SetInkDropMode(InkDropMode::ON);
 
   // Since user avatar is on the right hand side of System tray of a
@@ -696,9 +682,11 @@
 }
 
 bool SystemTray::PerformAction(const ui::Event& event) {
-  // If we're already showing the menu, hide it; otherwise, show it (and hide
-  // any popup that's currently shown).
-  if (HasSystemBubble()) {
+  // If we're already showing the default view or detailed view in system menu,
+  // hide it; otherwise, show it (and hide any popup that's currently shown).
+  if (HasSystemBubbleType(SystemTrayBubble::BUBBLE_TYPE_DEFAULT) ||
+      (HasSystemBubbleType(SystemTrayBubble::BUBBLE_TYPE_DETAILED) &&
+       full_system_tray_menu_)) {
     system_bubble_->bubble()->Close();
   } else {
     ShowDefaultView(BUBBLE_CREATE_NEW);
diff --git a/ash/system/tray/system_tray.h b/ash/system/tray/system_tray.h
index b977622..e54d30d 100644
--- a/ash/system/tray/system_tray.h
+++ b/ash/system/tray/system_tray.h
@@ -202,13 +202,13 @@
   bool PerformAction(const ui::Event& event) override;
 
   // The web notification tray view that appears adjacent to this view.
-  WebNotificationTray* web_notification_tray_;
+  WebNotificationTray* web_notification_tray_ = nullptr;
 
   // Items.
   std::vector<std::unique_ptr<SystemTrayItem>> items_;
 
   // Pointers to members of |items_|.
-  SystemTrayItem* detailed_item_;
+  SystemTrayItem* detailed_item_ = nullptr;
 
   // Mappings of system tray item and it's view in the tray.
   std::map<SystemTrayItem*, views::View*> tray_item_map_;
@@ -218,25 +218,25 @@
 
   // Keep track of the default view height so that when we create detailed
   // views directly (e.g. from a notification) we know what height to use.
-  int default_bubble_height_;
+  int default_bubble_height_ = 0;
 
   // This is true when the displayed system tray menu is a full tray menu,
   // otherwise a single line item menu like the volume slider is shown.
   // Note that the value is only valid when |system_bubble_| is true.
-  bool full_system_tray_menu_;
+  bool full_system_tray_menu_ = false;
 
   // These objects are not owned by this class.
-  TrayAccessibility* tray_accessibility_;
-  TrayAudio* tray_audio_;  // May be null.
-  TrayCast* tray_cast_;
-  TrayNetwork* tray_network_;
-  TrayTiles* tray_tiles_;  // only used in material design.
-  TraySystemInfo* tray_system_info_;  // only used in material design.
-  TrayUpdate* tray_update_;
+  TrayAccessibility* tray_accessibility_ = nullptr;
+  TrayAudio* tray_audio_ = nullptr;  // May be null.
+  TrayCast* tray_cast_ = nullptr;
+  TrayNetwork* tray_network_ = nullptr;
+  TrayTiles* tray_tiles_ = nullptr;
+  TraySystemInfo* tray_system_info_ = nullptr;
+  TrayUpdate* tray_update_ = nullptr;
 
   // A reference to the Screen share and capture item.
-  ScreenTrayItem* screen_capture_tray_item_;  // not owned
-  ScreenTrayItem* screen_share_tray_item_;    // not owned
+  ScreenTrayItem* screen_capture_tray_item_ = nullptr;  // not owned
+  ScreenTrayItem* screen_share_tray_item_ = nullptr;    // not owned
 
   std::unique_ptr<KeyEventWatcher> key_event_watcher_;
 
diff --git a/ash/system/tray/system_tray_controller.cc b/ash/system/tray/system_tray_controller.cc
index 022f97a..8b40876 100644
--- a/ash/system/tray/system_tray_controller.cc
+++ b/ash/system/tray/system_tray_controller.cc
@@ -184,14 +184,16 @@
 }
 
 void SystemTrayController::ShowUpdateIcon(mojom::UpdateSeverity severity,
-                                          bool factory_reset_required) {
+                                          bool factory_reset_required,
+                                          mojom::UpdateType update_type) {
   // Show the icon on all displays.
   for (WmWindow* root : ShellPort::Get()->GetAllRootWindows()) {
     ash::SystemTray* tray = root->GetRootWindowController()->GetSystemTray();
     // External monitors might not have a tray yet.
     if (!tray)
       continue;
-    tray->tray_update()->ShowUpdateIcon(severity, factory_reset_required);
+    tray->tray_update()->ShowUpdateIcon(severity, factory_reset_required,
+                                        update_type);
   }
 }
 
diff --git a/ash/system/tray/system_tray_controller.h b/ash/system/tray/system_tray_controller.h
index a9a1cdf..ab29f20 100644
--- a/ash/system/tray/system_tray_controller.h
+++ b/ash/system/tray/system_tray_controller.h
@@ -67,7 +67,8 @@
   void SetPrimaryTrayVisible(bool visible) override;
   void SetUse24HourClock(bool use_24_hour) override;
   void ShowUpdateIcon(mojom::UpdateSeverity severity,
-                      bool factory_reset_required) override;
+                      bool factory_reset_required,
+                      mojom::UpdateType update_type) override;
 
  private:
   // Client interface in chrome browser. May be null in tests.
diff --git a/ash/system/tray/system_tray_delegate.cc b/ash/system/tray/system_tray_delegate.cc
index 10669a0a..7868d10 100644
--- a/ash/system/tray/system_tray_delegate.cc
+++ b/ash/system/tray/system_tray_delegate.cc
@@ -43,14 +43,6 @@
   return base::string16();
 }
 
-bool SystemTrayDelegate::IsUserSupervised() const {
-  return false;
-}
-
-bool SystemTrayDelegate::IsUserChild() const {
-  return false;
-}
-
 void SystemTrayDelegate::ShowEnterpriseInfo() {}
 
 void SystemTrayDelegate::ShowUserLogin() {}
diff --git a/ash/system/tray/system_tray_delegate.h b/ash/system/tray/system_tray_delegate.h
index 9980cbb..5056e57 100644
--- a/ash/system/tray/system_tray_delegate.h
+++ b/ash/system/tray/system_tray_delegate.h
@@ -69,23 +69,17 @@
 
   // Returns the display email of the user that manages the current supervised
   // user.
+  // TODO(jamescook): Migrate to SessionController. http://crbug.com/712799
   virtual std::string GetSupervisedUserManager() const;
 
   // Returns the name of the user that manages the current supervised user.
+  // TODO(jamescook): Migrate to SessionController. http://crbug.com/712799
   virtual base::string16 GetSupervisedUserManagerName() const;
 
   // Returns the notification for supervised users.
+  // TODO(jamescook): Migrate to SessionController. http://crbug.com/712799
   virtual base::string16 GetSupervisedUserMessage() const;
 
-  // Returns true if the current user is supervised: has legacy supervised
-  // account or kid account.
-  virtual bool IsUserSupervised() const;
-
-  // Returns true if the current user is child.
-  // TODO(merkulova): remove on FakeUserManager componentization.
-  // crbug.com/443119
-  virtual bool IsUserChild() const;
-
   // Shows information about enterprise enrolled devices.
   virtual void ShowEnterpriseInfo();
 
diff --git a/ash/system/update/tray_update.cc b/ash/system/update/tray_update.cc
index 55a82c5..a88ae9c 100644
--- a/ash/system/update/tray_update.cc
+++ b/ash/system/update/tray_update.cc
@@ -60,12 +60,14 @@
 mojom::UpdateSeverity TrayUpdate::severity_ = mojom::UpdateSeverity::NONE;
 // static
 bool TrayUpdate::factory_reset_required_ = false;
+mojom::UpdateType TrayUpdate::update_type_ = mojom::UpdateType::SYSTEM;
 
 // The "restart to update" item in the system tray menu.
 class TrayUpdate::UpdateView : public ActionableView {
  public:
   explicit UpdateView(TrayUpdate* owner)
-      : ActionableView(owner, TrayPopupInkDropStyle::FILL_BOUNDS) {
+      : ActionableView(owner, TrayPopupInkDropStyle::FILL_BOUNDS),
+        update_label_(nullptr) {
     SetLayoutManager(new views::FillLayout);
 
     ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
@@ -77,23 +79,31 @@
         IconColorForUpdateSeverity(owner->severity_, true)));
     tri_view->AddView(TriView::Container::START, image);
 
-    base::string16 label_text =
-        owner->factory_reset_required_
-            ? bundle.GetLocalizedString(
-                  IDS_ASH_STATUS_TRAY_RESTART_AND_POWERWASH_TO_UPDATE)
-            : bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_UPDATE);
+    base::string16 label_text;
+    if (owner->factory_reset_required_) {
+      label_text = bundle.GetLocalizedString(
+          IDS_ASH_STATUS_TRAY_RESTART_AND_POWERWASH_TO_UPDATE);
+    } else if (owner->update_type_ == mojom::UpdateType::FLASH) {
+      label_text = bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_UPDATE_FLASH);
+    } else {
+      label_text = bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_UPDATE);
+    }
+
     SetAccessibleName(label_text);
-    auto* label = TrayPopupUtils::CreateDefaultLabel();
-    label->SetText(label_text);
+    update_label_ = TrayPopupUtils::CreateDefaultLabel();
+    update_label_->SetText(label_text);
+
     TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::DEFAULT_VIEW_LABEL);
-    style.SetupLabel(label);
-    tri_view->AddView(TriView::Container::CENTER, label);
+    style.SetupLabel(update_label_);
+    tri_view->AddView(TriView::Container::CENTER, update_label_);
 
     SetInkDropMode(InkDropHostView::InkDropMode::ON);
   }
 
   ~UpdateView() override {}
 
+  views::Label* update_label_;
+
  private:
   // Overridden from ActionableView.
   bool PerformAction(const ui::Event& event) override {
@@ -119,19 +129,33 @@
 }
 
 views::View* TrayUpdate::CreateDefaultView(LoginStatus status) {
-  return update_required_ ? new UpdateView(this) : nullptr;
+  if (update_required_) {
+    update_view_ = new UpdateView(this);
+    return update_view_;
+  }
+  return nullptr;
+}
+
+void TrayUpdate::DestroyDefaultView() {
+  update_view_ = nullptr;
 }
 
 void TrayUpdate::ShowUpdateIcon(mojom::UpdateSeverity severity,
-                                bool factory_reset_required) {
+                                bool factory_reset_required,
+                                mojom::UpdateType update_type) {
   // Cache update info so we can create the default view when the menu opens.
   update_required_ = true;
   severity_ = severity;
   factory_reset_required_ = factory_reset_required;
+  update_type_ = update_type;
 
   // Show the icon in the tray.
   SetIconColor(IconColorForUpdateSeverity(severity_, false));
   tray_view()->SetVisible(true);
 }
 
+views::Label* TrayUpdate::GetLabelForTesting() {
+  return update_view_ ? update_view_->update_label_ : nullptr;
+}
+
 }  // namespace ash
diff --git a/ash/system/update/tray_update.h b/ash/system/update/tray_update.h
index 70c970e..6d3a9c0 100644
--- a/ash/system/update/tray_update.h
+++ b/ash/system/update/tray_update.h
@@ -7,9 +7,12 @@
 
 #include "ash/ash_export.h"
 #include "ash/system/tray/tray_image_item.h"
+#include "base/gtest_prod_util.h"
 #include "base/macros.h"
+#include "base/strings/string16.h"
 
 namespace views {
+class Label;
 class View;
 }
 
@@ -17,6 +20,7 @@
 
 namespace mojom {
 enum class UpdateSeverity;
+enum class UpdateType;
 }
 
 // The system update tray item. The tray icon stays visible once an update
@@ -31,14 +35,23 @@
   // available. Once shown the icon persists until reboot. |severity| and
   // |factory_reset_required| are used to set the icon, color, and tooltip.
   void ShowUpdateIcon(mojom::UpdateSeverity severity,
-                      bool factory_reset_required);
+                      bool factory_reset_required,
+                      mojom::UpdateType update_type);
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(TrayUpdateTest, VisibilityAfterUpdate);
+  FRIEND_TEST_ALL_PREFIXES(TrayUpdateTest, VisibilityAfterFlashUpdate);
+
   class UpdateView;
 
   // Overridden from TrayImageItem.
   bool GetInitialVisibility() override;
   views::View* CreateDefaultView(LoginStatus status) override;
+  void DestroyDefaultView() override;
+
+  // Expose label information for testing.
+  views::Label* GetLabelForTesting();
+  UpdateView* update_view_;
 
   // If an external monitor is connected then the system tray may be created
   // after the update data is sent from chrome, so share the update info between
@@ -46,6 +59,7 @@
   static bool update_required_;
   static mojom::UpdateSeverity severity_;
   static bool factory_reset_required_;
+  static mojom::UpdateType update_type_;
 
   DISALLOW_COPY_AND_ASSIGN(TrayUpdate);
 };
diff --git a/ash/system/update/tray_update_unittest.cc b/ash/system/update/tray_update_unittest.cc
index aa38649..a7c131c2 100644
--- a/ash/system/update/tray_update_unittest.cc
+++ b/ash/system/update/tray_update_unittest.cc
@@ -9,6 +9,9 @@
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/system_tray_controller.h"
 #include "ash/test/ash_test.h"
+#include "base/strings/utf_string_conversions.h"
+#include "ui/events/event.h"
+#include "ui/views/controls/label.h"
 
 namespace ash {
 
@@ -17,17 +20,38 @@
 // Tests that the update icon becomes visible when an update becomes
 // available.
 TEST_F(TrayUpdateTest, VisibilityAfterUpdate) {
-  TrayUpdate* tray_update = GetPrimarySystemTray()->tray_update();
+  SystemTray* tray = GetPrimarySystemTray();
+  TrayUpdate* tray_update = tray->tray_update();
 
   // The system starts with no update pending, so the icon isn't visible.
   EXPECT_FALSE(tray_update->tray_view()->visible());
 
   // Simulate an update.
   Shell::Get()->system_tray_controller()->ShowUpdateIcon(
-      mojom::UpdateSeverity::LOW, false);
+      mojom::UpdateSeverity::LOW, false, mojom::UpdateType::SYSTEM);
 
   // Tray item is now visible.
   EXPECT_TRUE(tray_update->tray_view()->visible());
+
+  tray->ShowDefaultView(BUBBLE_CREATE_NEW);
+  base::string16 label = tray_update->GetLabelForTesting()->text();
+  EXPECT_EQ("Restart to update", base::UTF16ToUTF8(label));
+}
+
+TEST_F(TrayUpdateTest, VisibilityAfterFlashUpdate) {
+  SystemTray* tray = GetPrimarySystemTray();
+  TrayUpdate* tray_update = tray->tray_update();
+
+  // Simulate an update.
+  Shell::Get()->system_tray_controller()->ShowUpdateIcon(
+      mojom::UpdateSeverity::LOW, false, mojom::UpdateType::FLASH);
+
+  // Tray item is now visible.
+  EXPECT_TRUE(tray_update->tray_view()->visible());
+
+  tray->ShowDefaultView(BUBBLE_CREATE_NEW);
+  base::string16 label = tray_update->GetLabelForTesting()->text();
+  EXPECT_EQ("Restart to update Adobe Flash Player", base::UTF16ToUTF8(label));
 }
 
 }  // namespace ash
diff --git a/ash/system/user/tray_user.cc b/ash/system/user/tray_user.cc
index 47c6e87..c37e57b5 100644
--- a/ash/system/user/tray_user.cc
+++ b/ash/system/user/tray_user.cc
@@ -10,7 +10,6 @@
 #include "ash/shell_port.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/system/tray/system_tray.h"
-#include "ash/system/tray/system_tray_delegate.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_item_view.h"
 #include "ash/system/tray/tray_utils.h"
@@ -112,8 +111,8 @@
     return;
   bool need_label = false;
   bool need_avatar = false;
-  SystemTrayDelegate* delegate = Shell::Get()->system_tray_delegate();
-  if (delegate->IsUserSupervised())
+  SessionController* session = Shell::Get()->session_controller();
+  if (session->IsUserSupervised())
     need_label = true;
   switch (status) {
     case LoginStatus::LOCKED:
@@ -157,7 +156,7 @@
     }
   }
 
-  if (delegate->IsUserSupervised()) {
+  if (session->IsUserSupervised()) {
     label_->SetText(
         l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SUPERVISED_LABEL));
   } else if (status == LoginStatus::GUEST) {
diff --git a/ash/system/user/user_card_view.cc b/ash/system/user/user_card_view.cc
index be3a9d12..ef1e219 100644
--- a/ash/system/user/user_card_view.cc
+++ b/ash/system/user/user_card_view.cc
@@ -414,7 +414,7 @@
   base::string16 user_email_string;
   if (login_status != LoginStatus::GUEST) {
     user_email_string =
-        Shell::Get()->system_tray_delegate()->IsUserSupervised()
+        Shell::Get()->session_controller()->IsUserSupervised()
             ? l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SUPERVISED_LABEL)
             : base::UTF8ToUTF16(
                   controller->GetUserSession(user_index_)->display_email);
diff --git a/ash/test/BUILD.gn b/ash/test/BUILD.gn
index 7527e34..e63b6c1 100644
--- a/ash/test/BUILD.gn
+++ b/ash/test/BUILD.gn
@@ -122,10 +122,6 @@
     "test_session_state_animator.h",
     "test_session_state_delegate.cc",
     "test_session_state_delegate.h",
-    "test_shelf_delegate.cc",
-    "test_shelf_delegate.h",
-    "test_shelf_item_delegate.cc",
-    "test_shelf_item_delegate.h",
     "test_shell_delegate.cc",
     "test_shell_delegate.h",
     "test_system_tray_delegate.cc",
diff --git a/ash/test/shelf_view_test_api.cc b/ash/test/shelf_view_test_api.cc
index 9bf2d8c7..2ddb9c4 100644
--- a/ash/test/shelf_view_test_api.cc
+++ b/ash/test/shelf_view_test_api.cc
@@ -150,10 +150,6 @@
   return shelf_view_->SameDragType(typea, typeb);
 }
 
-void ShelfViewTestAPI::SetShelfDelegate(ShelfDelegate* delegate) {
-  shelf_view_->delegate_ = delegate;
-}
-
 gfx::Rect ShelfViewTestAPI::GetBoundsForDragInsertInScreen() {
   return shelf_view_->GetBoundsForDragInsertInScreen();
 }
diff --git a/ash/test/shelf_view_test_api.h b/ash/test/shelf_view_test_api.h
index fbb35c2..3967e7cc 100644
--- a/ash/test/shelf_view_test_api.h
+++ b/ash/test/shelf_view_test_api.h
@@ -28,7 +28,6 @@
 class OverflowButton;
 class ShelfButton;
 class ShelfButtonPressedMetricTracker;
-class ShelfDelegate;
 class ShelfTooltipManager;
 class ShelfView;
 
@@ -107,9 +106,6 @@
   // Wrapper for ShelfView::SameDragType.
   bool SameDragType(ShelfItemType typea, ShelfItemType typeb) const;
 
-  // Sets ShelfDelegate.
-  void SetShelfDelegate(ShelfDelegate* delegate);
-
   // Returns re-insertable bounds in screen.
   gfx::Rect GetBoundsForDragInsertInScreen();
 
diff --git a/ash/test/shell_test_api.cc b/ash/test/shell_test_api.cc
index 3bc0b30f..a60db9e 100644
--- a/ash/test/shell_test_api.cc
+++ b/ash/test/shell_test_api.cc
@@ -7,7 +7,6 @@
 #include "ash/palette_delegate.h"
 #include "ash/root_window_controller.h"
 #include "ash/session/session_state_delegate.h"
-#include "ash/shelf/shelf_delegate.h"
 #include "ash/shell.h"
 
 namespace ash {
@@ -47,10 +46,5 @@
   shell_->session_state_delegate_.reset(session_state_delegate);
 }
 
-void ShellTestApi::SetShelfDelegate(
-    std::unique_ptr<ShelfDelegate> test_delegate) {
-  shell_->shelf_delegate_ = std::move(test_delegate);
-}
-
 }  // namespace test
 }  // namespace ash
diff --git a/ash/test/shell_test_api.h b/ash/test/shell_test_api.h
index 0d1364c..f1eb5d4 100644
--- a/ash/test/shell_test_api.h
+++ b/ash/test/shell_test_api.h
@@ -16,7 +16,6 @@
 class PaletteDelegate;
 class SessionStateDelegate;
 class ScreenPositionController;
-class ShelfDelegate;
 class Shell;
 class SystemGestureEventFilter;
 class WorkspaceController;
@@ -38,7 +37,6 @@
 
   void SetPaletteDelegate(std::unique_ptr<PaletteDelegate> palette_delegate);
   void SetSessionStateDelegate(SessionStateDelegate* session_state_delegate);
-  void SetShelfDelegate(std::unique_ptr<ShelfDelegate> test_delegate);
 
  private:
   Shell* shell_;  // not owned
diff --git a/ash/test/test_session_controller_client.cc b/ash/test/test_session_controller_client.cc
index 6492a7c..19f98b7 100644
--- a/ash/test/test_session_controller_client.cc
+++ b/ash/test/test_session_controller_client.cc
@@ -97,10 +97,11 @@
 
 void TestSessionControllerClient::AddUserSession(
     const std::string& display_email,
+    user_manager::UserType user_type,
     bool enable_settings) {
   mojom::UserSessionPtr session = mojom::UserSession::New();
   session->session_id = ++fake_session_id_;
-  session->type = user_manager::USER_TYPE_REGULAR;
+  session->type = user_type;
   session->account_id =
       AccountId::FromUserEmail(GetUserIdFromEmail(display_email));
   session->display_name = "Über tray Über tray Über tray Über tray";
diff --git a/ash/test/test_session_controller_client.h b/ash/test/test_session_controller_client.h
index 6524a9e..7516e6c 100644
--- a/ash/test/test_session_controller_client.h
+++ b/ash/test/test_session_controller_client.h
@@ -11,6 +11,7 @@
 
 #include "ash/public/interfaces/session_controller.mojom.h"
 #include "base/macros.h"
+#include "components/user_manager/user_type.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
 class AccountId;
@@ -52,8 +53,10 @@
   // Adds a user session from a given display email. The display email will be
   // canonicalized and used to construct an AccountId. |enable_settings| sets
   // whether web UI settings are allowed.
-  void AddUserSession(const std::string& display_email,
-                      bool enable_settings = true);
+  void AddUserSession(
+      const std::string& display_email,
+      user_manager::UserType user_type = user_manager::USER_TYPE_REGULAR,
+      bool enable_settings = true);
 
   // Simulates screen unlocking. It is virtual so that test cases can override
   // it. The default implementation sets the session state of SessionController
diff --git a/ash/test/test_shelf_delegate.cc b/ash/test/test_shelf_delegate.cc
deleted file mode 100644
index 0fef1c7..0000000
--- a/ash/test/test_shelf_delegate.cc
+++ /dev/null
@@ -1,99 +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 "ash/test/test_shelf_delegate.h"
-
-#include "ash/shelf/shelf_model.h"
-#include "ash/shell.h"
-#include "base/strings/string_util.h"
-
-namespace ash {
-namespace test {
-
-TestShelfDelegate* TestShelfDelegate::instance_ = nullptr;
-
-TestShelfDelegate::TestShelfDelegate() {
-  CHECK(!instance_);
-  instance_ = this;
-}
-
-TestShelfDelegate::~TestShelfDelegate() {
-  instance_ = nullptr;
-}
-
-ShelfID TestShelfDelegate::GetShelfIDForAppID(const std::string& app_id) {
-  // Get shelf id for |app_id| and an empty |launch_id|.
-  return GetShelfIDForAppIDAndLaunchID(app_id, std::string());
-}
-
-ShelfID TestShelfDelegate::GetShelfIDForAppIDAndLaunchID(
-    const std::string& app_id,
-    const std::string& launch_id) {
-  for (const ShelfItem& item : Shell::Get()->shelf_model()->items()) {
-    // Ash's ShelfWindowWatcher handles app panel windows separately.
-    if (item.type != TYPE_APP_PANEL && item.app_launch_id.app_id() == app_id &&
-        item.app_launch_id.launch_id() == launch_id) {
-      return item.id;
-    }
-  }
-  return kInvalidShelfID;
-}
-
-const std::string& TestShelfDelegate::GetAppIDForShelfID(ShelfID id) {
-  ShelfModel* model = Shell::Get()->shelf_model();
-  ShelfItems::const_iterator item = model->ItemByID(id);
-  return item != model->items().end() ? item->app_launch_id.app_id()
-                                      : base::EmptyString();
-}
-
-void TestShelfDelegate::PinAppWithID(const std::string& app_id) {
-  // If the app is already pinned, do nothing and return.
-  if (IsAppPinned(app_id))
-    return;
-
-  // Convert an existing item to be pinned, or create a new pinned item.
-  ShelfModel* model = Shell::Get()->shelf_model();
-  const int index = model->ItemIndexByID(GetShelfIDForAppID(app_id));
-  if (index >= 0) {
-    ShelfItem item = model->items()[index];
-    DCHECK_EQ(item.type, TYPE_APP);
-    DCHECK(!item.pinned_by_policy);
-    item.type = TYPE_PINNED_APP;
-    model->Set(index, item);
-  } else if (!app_id.empty()) {
-    ShelfItem item;
-    item.type = TYPE_PINNED_APP;
-    item.app_launch_id = AppLaunchId(app_id);
-    model->Add(item);
-  }
-}
-
-bool TestShelfDelegate::IsAppPinned(const std::string& app_id) {
-  ShelfID shelf_id = GetShelfIDForAppID(app_id);
-  ShelfModel* model = Shell::Get()->shelf_model();
-  ShelfItems::const_iterator item = model->ItemByID(shelf_id);
-  return item != model->items().end() && item->type == TYPE_PINNED_APP;
-}
-
-void TestShelfDelegate::UnpinAppWithID(const std::string& app_id) {
-  // If the app is already not pinned, do nothing and return.
-  if (!IsAppPinned(app_id))
-    return;
-
-  // Remove the item if it is closed, or mark it as unpinned.
-  ShelfModel* model = Shell::Get()->shelf_model();
-  const int index = model->ItemIndexByID(GetShelfIDForAppID(app_id));
-  ShelfItem item = model->items()[index];
-  DCHECK_EQ(item.type, TYPE_PINNED_APP);
-  DCHECK(!item.pinned_by_policy);
-  if (item.status == STATUS_CLOSED) {
-    model->RemoveItemAt(index);
-  } else {
-    item.type = TYPE_APP;
-    model->Set(index, item);
-  }
-}
-
-}  // namespace test
-}  // namespace ash
diff --git a/ash/test/test_shelf_delegate.h b/ash/test/test_shelf_delegate.h
deleted file mode 100644
index ddf1549..0000000
--- a/ash/test/test_shelf_delegate.h
+++ /dev/null
@@ -1,42 +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 ASH_TEST_TEST_SHELF_DELEGATE_H_
-#define ASH_TEST_TEST_SHELF_DELEGATE_H_
-
-#include <string>
-
-#include "ash/shelf/shelf_delegate.h"
-#include "base/macros.h"
-
-namespace ash {
-namespace test {
-
-// Test implementation of ShelfDelegate.
-class TestShelfDelegate : public ShelfDelegate {
- public:
-  TestShelfDelegate();
-  ~TestShelfDelegate() override;
-
-  static TestShelfDelegate* instance() { return instance_; }
-
-  // ShelfDelegate implementation.
-  ShelfID GetShelfIDForAppID(const std::string& app_id) override;
-  ShelfID GetShelfIDForAppIDAndLaunchID(const std::string& app_id,
-                                        const std::string& launch_id) override;
-  const std::string& GetAppIDForShelfID(ShelfID id) override;
-  void PinAppWithID(const std::string& app_id) override;
-  bool IsAppPinned(const std::string& app_id) override;
-  void UnpinAppWithID(const std::string& app_id) override;
-
- private:
-  static TestShelfDelegate* instance_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestShelfDelegate);
-};
-
-}  // namespace test
-}  // namespace ash
-
-#endif  // ASH_TEST_TEST_SHELF_DELEGATE_H_
diff --git a/ash/test/test_shelf_item_delegate.cc b/ash/test/test_shelf_item_delegate.cc
deleted file mode 100644
index ce22dc1..0000000
--- a/ash/test/test_shelf_item_delegate.cc
+++ /dev/null
@@ -1,42 +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 "ash/test/test_shelf_item_delegate.h"
-
-#include "ash/wm/window_util.h"
-#include "ash/wm_window.h"
-
-namespace ash {
-namespace test {
-
-TestShelfItemDelegate::TestShelfItemDelegate(WmWindow* window)
-    : ShelfItemDelegate(AppLaunchId()), window_(window) {}
-
-TestShelfItemDelegate::~TestShelfItemDelegate() {}
-
-void TestShelfItemDelegate::ItemSelected(std::unique_ptr<ui::Event> event,
-                                         int64_t display_id,
-                                         ShelfLaunchSource source,
-                                         const ItemSelectedCallback& callback) {
-  if (window_) {
-    if (window_->GetType() == ui::wm::WINDOW_TYPE_PANEL)
-      wm::MoveWindowToDisplay(window_->aura_window(), display_id);
-    window_->Show();
-    window_->Activate();
-    callback.Run(SHELF_ACTION_WINDOW_ACTIVATED, base::nullopt);
-    return;
-  }
-  callback.Run(SHELF_ACTION_NONE, base::nullopt);
-}
-
-void TestShelfItemDelegate::ExecuteCommand(uint32_t command_id,
-                                           int32_t event_flags) {
-  // This delegate does not support showing an application menu.
-  NOTIMPLEMENTED();
-}
-
-void TestShelfItemDelegate::Close() {}
-
-}  // namespace test
-}  // namespace ash
diff --git a/ash/test/test_shelf_item_delegate.h b/ash/test/test_shelf_item_delegate.h
deleted file mode 100644
index 5f8f1b37..0000000
--- a/ash/test/test_shelf_item_delegate.h
+++ /dev/null
@@ -1,40 +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 ASH_TEST_TEST_SHELF_ITEM_DELEGATE_H_
-#define ASH_TEST_TEST_SHELF_ITEM_DELEGATE_H_
-
-#include "ash/public/cpp/shelf_item_delegate.h"
-#include "base/macros.h"
-
-namespace ash {
-
-class WmWindow;
-
-namespace test {
-
-// Test implementation of ShelfItemDelegate.
-class TestShelfItemDelegate : public ShelfItemDelegate {
- public:
-  explicit TestShelfItemDelegate(WmWindow* window);
-  ~TestShelfItemDelegate() override;
-
-  // ShelfItemDelegate:
-  void ItemSelected(std::unique_ptr<ui::Event> event,
-                    int64_t display_id,
-                    ShelfLaunchSource source,
-                    const ItemSelectedCallback& callback) override;
-  void ExecuteCommand(uint32_t command_id, int32_t event_flags) override;
-  void Close() override;
-
- private:
-  WmWindow* window_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestShelfItemDelegate);
-};
-
-}  // namespace test
-}  // namespace ash
-
-#endif  // ASH_TEST_TEST_SHELF_ITEM_DELEGATE_H_
diff --git a/ash/test/test_shell_delegate.cc b/ash/test/test_shell_delegate.cc
index 27c12b0..5d75697 100644
--- a/ash/test/test_shell_delegate.cc
+++ b/ash/test/test_shell_delegate.cc
@@ -18,7 +18,6 @@
 #include "ash/system/tray/system_tray_notifier.h"
 #include "ash/test/test_keyboard_ui.h"
 #include "ash/test/test_session_state_delegate.h"
-#include "ash/test/test_shelf_delegate.h"
 #include "ash/test/test_system_tray_delegate.h"
 #include "ash/test/test_wallpaper_delegate.h"
 #include "ash/wm/window_state.h"
@@ -101,12 +100,14 @@
 
 void TestShellDelegate::OpenUrlFromArc(const GURL& url) {}
 
-ShelfDelegate* TestShellDelegate::CreateShelfDelegate(ShelfModel* model) {
+void TestShellDelegate::ShelfInit() {
   // Create a separate shelf initializer that mimics ChromeLauncherController.
-  shelf_initializer_ = base::MakeUnique<ShelfInitializer>();
-  return new TestShelfDelegate();
+  if (!shelf_initializer_)
+    shelf_initializer_ = base::MakeUnique<ShelfInitializer>();
 }
 
+void TestShellDelegate::ShelfShutdown() {}
+
 SystemTrayDelegate* TestShellDelegate::CreateSystemTrayDelegate() {
   return new TestSystemTrayDelegate;
 }
diff --git a/ash/test/test_shell_delegate.h b/ash/test/test_shell_delegate.h
index ab64ef4e9..9110cda8 100644
--- a/ash/test/test_shell_delegate.h
+++ b/ash/test/test_shell_delegate.h
@@ -41,8 +41,9 @@
   void PreShutdown() override;
   void Exit() override;
   keyboard::KeyboardUI* CreateKeyboardUI() override;
+  void ShelfInit() override;
+  void ShelfShutdown() override;
   void OpenUrlFromArc(const GURL& url) override;
-  ShelfDelegate* CreateShelfDelegate(ShelfModel* model) override;
   SystemTrayDelegate* CreateSystemTrayDelegate() override;
   std::unique_ptr<WallpaperDelegate> CreateWallpaperDelegate() override;
   TestSessionStateDelegate* CreateSessionStateDelegate() override;
diff --git a/ash/test/test_system_tray_delegate.cc b/ash/test/test_system_tray_delegate.cc
index dac714c..0f19c35c 100644
--- a/ash/test/test_system_tray_delegate.cc
+++ b/ash/test/test_system_tray_delegate.cc
@@ -14,21 +14,9 @@
 namespace ash {
 namespace test {
 
-namespace {
+TestSystemTrayDelegate::TestSystemTrayDelegate() = default;
 
-LoginStatus g_initial_status = LoginStatus::USER;
-
-}  // namespace
-
-TestSystemTrayDelegate::TestSystemTrayDelegate()
-    : login_status_(g_initial_status), session_length_limit_set_(false) {}
-
-TestSystemTrayDelegate::~TestSystemTrayDelegate() {}
-
-void TestSystemTrayDelegate::SetLoginStatus(LoginStatus login_status) {
-  login_status_ = login_status;
-  Shell::Get()->UpdateAfterLoginStatusChange(login_status);
-}
+TestSystemTrayDelegate::~TestSystemTrayDelegate() = default;
 
 void TestSystemTrayDelegate::SetSessionLengthLimitForTest(
     const base::TimeDelta& new_limit) {
@@ -49,33 +37,15 @@
 }
 
 LoginStatus TestSystemTrayDelegate::GetUserLoginStatus() const {
-  // Initial login status has been changed for testing.
-  if (g_initial_status != LoginStatus::USER &&
-      g_initial_status == login_status_) {
-    return login_status_;
-  }
-
-  // At new user image screen manager->IsUserLoggedIn() would return true
-  // but there's no browser session available yet so use SessionStarted().
-  SessionController* controller = Shell::Get()->session_controller();
-
-  if (!controller->IsActiveUserSessionStarted())
-    return LoginStatus::NOT_LOGGED_IN;
-  if (controller->IsScreenLocked())
-    return LoginStatus::LOCKED;
-  return login_status_;
+  return Shell::Get()->session_controller()->login_status();
 }
 
 std::string TestSystemTrayDelegate::GetSupervisedUserManager() const {
-  if (!IsUserSupervised())
+  if (!Shell::Get()->session_controller()->IsUserSupervised())
     return std::string();
   return "manager@chrome.com";
 }
 
-bool TestSystemTrayDelegate::IsUserSupervised() const {
-  return login_status_ == LoginStatus::SUPERVISED;
-}
-
 bool TestSystemTrayDelegate::GetSessionStartTime(
     base::TimeTicks* session_start_time) {
   // Just returns TimeTicks::Now(), so the remaining time is always the
@@ -100,16 +70,5 @@
   *list = ime_list_;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-
-ScopedInitialLoginStatus::ScopedInitialLoginStatus(LoginStatus new_status)
-    : old_status_(g_initial_status) {
-  g_initial_status = new_status;
-}
-
-ScopedInitialLoginStatus::~ScopedInitialLoginStatus() {
-  g_initial_status = old_status_;
-}
-
 }  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_system_tray_delegate.h b/ash/test/test_system_tray_delegate.h
index 5362012..1a4cf6aa 100644
--- a/ash/test/test_system_tray_delegate.h
+++ b/ash/test/test_system_tray_delegate.h
@@ -18,13 +18,6 @@
   TestSystemTrayDelegate();
   ~TestSystemTrayDelegate() override;
 
-  // Changes the current login status in the test. This also invokes
-  // UpdateAfterLoginStatusChange(). Usually this is called in the test code to
-  // set up a login status. This will fit to most of the test cases, but this
-  // cannot be set during the initialization. To test the initialization,
-  // consider using SetInitialLoginStatus() instead.
-  void SetLoginStatus(LoginStatus login_status);
-
   // Updates the session length limit so that the limit will come from now in
   // |new_limit|.
   void SetSessionLengthLimitForTest(const base::TimeDelta& new_limit);
@@ -41,36 +34,20 @@
   // SystemTrayDelegate:
   LoginStatus GetUserLoginStatus() const override;
   std::string GetSupervisedUserManager() const override;
-  bool IsUserSupervised() const override;
   bool GetSessionStartTime(base::TimeTicks* session_start_time) override;
   bool GetSessionLengthLimit(base::TimeDelta* session_length_limit) override;
   void GetCurrentIME(IMEInfo* info) override;
   void GetAvailableIMEList(IMEInfoList* list) override;
 
  private:
-  LoginStatus login_status_;
   base::TimeDelta session_length_limit_;
-  bool session_length_limit_set_;
+  bool session_length_limit_set_ = false;
   IMEInfo current_ime_;
   IMEInfoList ime_list_;
 
   DISALLOW_COPY_AND_ASSIGN(TestSystemTrayDelegate);
 };
 
-// Changes the initial login status before TestSystemTrayDelegate is created.
-// Allows testing the case when chrome is restarted right after login (such as
-// when a flag is set).
-class ScopedInitialLoginStatus {
- public:
-  explicit ScopedInitialLoginStatus(LoginStatus status);
-  ~ScopedInitialLoginStatus();
-
- private:
-  LoginStatus old_status_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedInitialLoginStatus);
-};
-
 }  // namespace test
 }  // namespace ash
 
diff --git a/build/android/play_services/preprocess.py b/build/android/play_services/preprocess.py
index b14ffad8..16fd3c467 100755
--- a/build/android/play_services/preprocess.py
+++ b/build/android/play_services/preprocess.py
@@ -35,6 +35,7 @@
 import stat
 import sys
 import tempfile
+import textwrap
 import zipfile
 
 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir))
@@ -55,11 +56,21 @@
                                    'location'),
                              required=True,
                              metavar='FILE')
+  required_args.add_argument('-d',
+                             '--root-dir',
+                             help='the directory which GN considers the root',
+                             required=True,
+                             metavar='FILE')
   required_args.add_argument('-o',
                              '--out-dir',
                              help='the output directory',
                              required=True,
                              metavar='FILE')
+  required_args.add_argument('-g',
+                             '--gni-out-file',
+                             help='the GN output file',
+                             required=True,
+                             metavar='FILE')
   required_args.add_argument('-c',
                              '--config-file',
                              help='the config file path',
@@ -73,11 +84,14 @@
   args = parser.parse_args()
 
   return ProcessGooglePlayServices(args.repository,
+                                   args.root_dir,
                                    args.out_dir,
+                                   args.gni_out_file,
                                    args.config_file)
 
 
-def ProcessGooglePlayServices(repo, out_dir, config_path):
+def ProcessGooglePlayServices(
+    repo, root_dir, out_dir, gni_out_file, config_path):
   config = utils.ConfigParser(config_path)
 
   tmp_root = tempfile.mkdtemp()
@@ -86,6 +100,7 @@
     _ImportFromExtractedRepo(config, tmp_paths, repo)
     _ProcessResources(config, tmp_paths, repo)
     _CopyToOutput(tmp_paths, out_dir)
+    _EnumerateProguardFiles(root_dir, out_dir, gni_out_file)
     _UpdateVersionInConfig(config, tmp_paths)
   finally:
     shutil.rmtree(tmp_root)
@@ -187,6 +202,37 @@
   shutil.copytree(tmp_paths['imported_clients'], out_dir)
 
 
+# Write a GN file containing a list of each GMS client's proguard file (if any).
+def _EnumerateProguardFiles(root_dir, out_dir, gni_path):
+  gni_dir = os.path.dirname(gni_path)
+  gni_template = textwrap.dedent('''\
+      # 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.
+
+      # This file generated by {script}
+      gms_proguard_configs = [
+      {body}
+      ]
+      ''')
+
+  gni_lines = []
+  for client_dir in os.listdir(out_dir):
+    proguard_path = os.path.join(
+        out_dir, client_dir, 'proguard.txt')
+    if os.path.exists(os.path.dirname(proguard_path)):
+      rooted_path = os.path.relpath(proguard_path, root_dir)
+      gni_lines.append('  "//{}",'.format(rooted_path))
+  gni_lines.sort()
+
+  gni_text = gni_template.format(
+      script=os.path.relpath(sys.argv[0], gni_dir),
+      body='\n'.join(gni_lines))
+
+  with open(gni_path, 'w') as gni_file:
+    gni_file.write(gni_text)
+
+
 def _UpdateVersionInConfig(config, tmp_paths):
   version_xml_path = os.path.join(tmp_paths['imported_clients'],
                                   config.version_xml_path)
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py
index 82ebedc..8c7d6b9 100755
--- a/build/vs_toolchain.py
+++ b/build/vs_toolchain.py
@@ -306,6 +306,28 @@
   if configuration == 'Debug':
     _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=True)
 
+  _CopyDebugger(target_dir, target_cpu)
+
+
+def _CopyDebugger(target_dir, target_cpu):
+  """Copy dbghelp.dll into the requested directory as needed.
+
+  target_cpu is one of 'x86' or 'x64'.
+
+  dbghelp.dll is used when Chrome needs to symbolize stacks. Copying this file
+  from the SDK directory avoids using the system copy of dbghelp.dll which then
+  ensures compatibility with recent debug information formats, such as VS
+  2017 /debug:fastlink PDBs.
+  """
+  win_sdk_dir = SetEnvironmentAndGetSDKDir()
+  if not win_sdk_dir:
+    return
+
+  debug_file = 'dbghelp.dll'
+  full_path = os.path.join(win_sdk_dir, 'Debuggers', target_cpu, debug_file)
+  target_path = os.path.join(target_dir, debug_file)
+  _CopyRuntimeImpl(target_path, full_path)
+
 
 def _GetDesiredVsToolchainHashes():
   """Load a list of SHA1s corresponding to the toolchains that we want installed
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index c038ebb..286744b 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -72,10 +72,6 @@
 
 class CC_EXPORT LayerImpl {
  public:
-  typedef LayerImplList RenderSurfaceListType;
-  typedef LayerImplList LayerListType;
-  typedef RenderSurfaceImpl RenderSurfaceType;
-
   static std::unique_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
     return base::WrapUnique(new LayerImpl(tree_impl, id));
   }
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc
index c881682..65cd061 100644
--- a/cc/layers/scrollbar_layer_unittest.cc
+++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -1211,10 +1211,8 @@
 
     DCHECK(bitmap);
 
-    AutoLockUIResourceBitmap locked_bitmap(*bitmap);
-
     const SkColor* pixels =
-        reinterpret_cast<const SkColor*>(locked_bitmap.GetPixels());
+        reinterpret_cast<const SkColor*>(bitmap->GetPixels());
     SkColor color = argb_to_skia(
         scrollbar_layer->fake_scrollbar()->paint_fill_color());
     int width = bitmap->GetSize().width();
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index 3446cc7..a7fe452 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -2830,7 +2830,6 @@
     if (src_pixels) {
       bitmap.reset(new SkBitmap);
       bitmap->allocN32Pixels(size.width(), size.height());
-      std::unique_ptr<SkAutoLockPixels> lock(new SkAutoLockPixels(*bitmap));
       uint8_t* dest_pixels = static_cast<uint8_t*>(bitmap->getPixels());
 
       size_t row_bytes = size.width() * 4;
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
index f54ab1d..7a9851e 100644
--- a/cc/output/renderer_pixeltest.cc
+++ b/cc/output/renderer_pixeltest.cc
@@ -1986,12 +1986,10 @@
   ResourceId mask_resource_id = this->resource_provider_->CreateResource(
       mask_rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888,
       gfx::ColorSpace());
-  {
-    SkAutoLockPixels lock(bitmap);
-    this->resource_provider_->CopyToResource(
-        mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
-        mask_rect.size());
-  }
+
+  this->resource_provider_->CopyToResource(
+      mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
+      mask_rect.size());
 
   // This RenderPassDrawQuad does not include the full |viewport_rect| which is
   // the size of the child render pass.
@@ -2081,12 +2079,10 @@
   ResourceId mask_resource_id = this->resource_provider_->CreateResource(
       mask_rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888,
       gfx::ColorSpace());
-  {
-    SkAutoLockPixels lock(bitmap);
-    this->resource_provider_->CopyToResource(
-        mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
-        mask_rect.size());
-  }
+
+  this->resource_provider_->CopyToResource(
+      mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
+      mask_rect.size());
 
   // This RenderPassDrawQuad does not include the full |viewport_rect| which is
   // the size of the child render pass.
@@ -2809,25 +2805,19 @@
 
   SkBitmap bitmap;
   bitmap.allocN32Pixels(2, 2);
-  {
-    SkAutoLockPixels lock(bitmap);
-    SkCanvas canvas(bitmap);
-    draw_point_color(&canvas, 0, 0, SK_ColorGREEN);
-    draw_point_color(&canvas, 0, 1, SK_ColorBLUE);
-    draw_point_color(&canvas, 1, 0, SK_ColorBLUE);
-    draw_point_color(&canvas, 1, 1, SK_ColorGREEN);
-  }
+  SkCanvas canvas(bitmap);
+  draw_point_color(&canvas, 0, 0, SK_ColorGREEN);
+  draw_point_color(&canvas, 0, 1, SK_ColorBLUE);
+  draw_point_color(&canvas, 1, 0, SK_ColorBLUE);
+  draw_point_color(&canvas, 1, 1, SK_ColorGREEN);
 
   gfx::Size tile_size(2, 2);
   ResourceId resource = this->resource_provider_->CreateResource(
       tile_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888,
       gfx::ColorSpace());
 
-  {
-    SkAutoLockPixels lock(bitmap);
-    this->resource_provider_->CopyToResource(
-        resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
-  }
+  this->resource_provider_->CopyToResource(
+      resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
 
   int id = 1;
   gfx::Transform transform_to_root;
@@ -2860,25 +2850,19 @@
 
   SkBitmap bitmap;
   bitmap.allocN32Pixels(2, 2);
-  {
-    SkAutoLockPixels lock(bitmap);
-    SkCanvas canvas(bitmap);
-    draw_point_color(&canvas, 0, 0, SK_ColorGREEN);
-    draw_point_color(&canvas, 0, 1, SK_ColorBLUE);
-    draw_point_color(&canvas, 1, 0, SK_ColorBLUE);
-    draw_point_color(&canvas, 1, 1, SK_ColorGREEN);
-  }
+  SkCanvas canvas(bitmap);
+  draw_point_color(&canvas, 0, 0, SK_ColorGREEN);
+  draw_point_color(&canvas, 0, 1, SK_ColorBLUE);
+  draw_point_color(&canvas, 1, 0, SK_ColorBLUE);
+  draw_point_color(&canvas, 1, 1, SK_ColorGREEN);
 
   gfx::Size tile_size(2, 2);
   ResourceId resource = this->resource_provider_->CreateResource(
       tile_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888,
       gfx::ColorSpace());
 
-  {
-    SkAutoLockPixels lock(bitmap);
-    this->resource_provider_->CopyToResource(
-        resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
-  }
+  this->resource_provider_->CopyToResource(
+      resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
 
   int id = 1;
   gfx::Transform transform_to_root;
@@ -2913,7 +2897,6 @@
   SkBitmap bitmap;
   bitmap.allocN32Pixels(2, 2);
   {
-    SkAutoLockPixels lock(bitmap);
     SkCanvas canvas(bitmap);
     draw_point_color(&canvas, 0, 0, SK_ColorGREEN);
     draw_point_color(&canvas, 0, 1, SK_ColorBLUE);
@@ -2926,11 +2909,8 @@
       tile_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888,
       gfx::ColorSpace());
 
-  {
-    SkAutoLockPixels lock(bitmap);
-    this->resource_provider_->CopyToResource(
-        resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
-  }
+  this->resource_provider_->CopyToResource(
+      resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
 
   int id = 1;
   gfx::Transform transform_to_root;
@@ -3289,12 +3269,10 @@
   ResourceId resource = this->resource_provider_->CreateResource(
       mask_rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888,
       gfx::ColorSpace());
-  {
-    SkAutoLockPixels lock(bitmap);
-    this->resource_provider_->CopyToResource(
-        resource, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
-        mask_rect.size());
-  }
+
+  this->resource_provider_->CopyToResource(
+      resource, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
+      mask_rect.size());
 
   // Arbitrary dividing lengths to divide up the resource into 16 quads.
   int widths[] = {
diff --git a/cc/paint/paint_canvas.h b/cc/paint/paint_canvas.h
index d8a58372..b163809 100644
--- a/cc/paint/paint_canvas.h
+++ b/cc/paint/paint_canvas.h
@@ -34,11 +34,6 @@
   // both recording and gpu work.
   virtual void flush() = 0;
 
-  virtual bool writePixels(const SkImageInfo& info,
-                           const void* pixels,
-                           size_t row_bytes,
-                           int x,
-                           int y) = 0;
   virtual int save() = 0;
   virtual int saveLayer(const SkRect* bounds, const PaintFlags* flags) = 0;
   virtual int saveLayerAlpha(const SkRect* bounds, U8CPU alpha) = 0;
diff --git a/cc/paint/skia_paint_canvas.cc b/cc/paint/skia_paint_canvas.cc
index 5034107..57901af 100644
--- a/cc/paint/skia_paint_canvas.cc
+++ b/cc/paint/skia_paint_canvas.cc
@@ -38,14 +38,6 @@
   canvas_->flush();
 }
 
-bool SkiaPaintCanvas::writePixels(const SkImageInfo& info,
-                                  const void* pixels,
-                                  size_t row_bytes,
-                                  int x,
-                                  int y) {
-  return canvas_->writePixels(info, pixels, row_bytes, x, y);
-}
-
 int SkiaPaintCanvas::save() {
   return canvas_->save();
 }
diff --git a/cc/paint/skia_paint_canvas.h b/cc/paint/skia_paint_canvas.h
index f50e2321b..8b29bd6 100644
--- a/cc/paint/skia_paint_canvas.h
+++ b/cc/paint/skia_paint_canvas.h
@@ -38,11 +38,6 @@
 
   void flush() override;
 
-  bool writePixels(const SkImageInfo& info,
-                   const void* pixels,
-                   size_t row_bytes,
-                   int x,
-                   int y) override;
   int save() override;
   int saveLayer(const SkRect* bounds, const PaintFlags* flags) override;
   int saveLayerAlpha(const SkRect* bounds, U8CPU alpha) override;
diff --git a/cc/resources/ui_resource_bitmap.cc b/cc/resources/ui_resource_bitmap.cc
index 4d8d281..17baf529 100644
--- a/cc/resources/ui_resource_bitmap.cc
+++ b/cc/resources/ui_resource_bitmap.cc
@@ -89,18 +89,4 @@
 UIResourceBitmap::UIResourceBitmap(const UIResourceBitmap& other) = default;
 
 UIResourceBitmap::~UIResourceBitmap() {}
-
-AutoLockUIResourceBitmap::AutoLockUIResourceBitmap(
-    const UIResourceBitmap& bitmap) : bitmap_(bitmap) {
-  bitmap_.pixel_ref_->lockPixels();
-}
-
-AutoLockUIResourceBitmap::~AutoLockUIResourceBitmap() {
-  bitmap_.pixel_ref_->unlockPixels();
-}
-
-const uint8_t* AutoLockUIResourceBitmap::GetPixels() const {
-  return static_cast<const uint8_t*>(bitmap_.pixel_ref_->pixels());
-}
-
 }  // namespace cc
diff --git a/cc/resources/ui_resource_bitmap.h b/cc/resources/ui_resource_bitmap.h
index 66a8a38..4acfd2ce 100644
--- a/cc/resources/ui_resource_bitmap.h
+++ b/cc/resources/ui_resource_bitmap.h
@@ -54,6 +54,10 @@
     return pixel_ref_ ? pixel_ref_->rowBytes() * size_.height() : 0;
   }
 
+  const uint8_t* GetPixels() const {
+    return static_cast<const uint8_t*>(pixel_ref_->pixels());
+  }
+
  private:
   friend class AutoLockUIResourceBitmap;
 
@@ -67,16 +71,6 @@
   bool opaque_;
 };
 
-class CC_EXPORT AutoLockUIResourceBitmap {
- public:
-  explicit AutoLockUIResourceBitmap(const UIResourceBitmap& bitmap);
-  ~AutoLockUIResourceBitmap();
-  const uint8_t* GetPixels() const;
-
- private:
-  const UIResourceBitmap& bitmap_;
-};
-
 }  // namespace cc
 
 #endif  // CC_RESOURCES_UI_RESOURCE_BITMAP_H_
diff --git a/cc/scheduler/begin_frame_tracker.cc b/cc/scheduler/begin_frame_tracker.cc
index dc18bea..b7c63e6 100644
--- a/cc/scheduler/begin_frame_tracker.cc
+++ b/cc/scheduler/begin_frame_tracker.cc
@@ -78,12 +78,12 @@
 }
 
 void BeginFrameTracker::AsValueInto(
-    base::TimeTicks now,
     base::trace_event::TracedValue* state) const {
-  state->SetInteger("updated_at_us",
-                    (current_updated_at_ - base::TimeTicks()).InMicroseconds());
-  state->SetInteger("finished_at_us", (current_finished_at_ - base::TimeTicks())
-                                          .InMicroseconds());
+  state->SetDouble("updated_at_ms",
+                   (current_updated_at_ - base::TimeTicks()).InMillisecondsF());
+  state->SetDouble(
+      "finished_at_ms",
+      (current_finished_at_ - base::TimeTicks()).InMillisecondsF());
   if (HasFinished()) {
     state->SetString("state", "FINISHED");
     state->BeginDictionary("current_args_");
@@ -94,6 +94,7 @@
   current_args_.AsValueInto(state);
   state->EndDictionary();
 
+  base::TimeTicks now = base::TimeTicks::Now();
   base::TimeTicks frame_time = current_args_.frame_time;
   base::TimeTicks deadline = current_args_.deadline;
   base::TimeDelta interval = current_args_.interval;
diff --git a/cc/scheduler/begin_frame_tracker.h b/cc/scheduler/begin_frame_tracker.h
index 98b1da4..aefed8a 100644
--- a/cc/scheduler/begin_frame_tracker.h
+++ b/cc/scheduler/begin_frame_tracker.h
@@ -67,8 +67,7 @@
   // any time.
   base::TimeDelta Interval() const;
 
-  void AsValueInto(base::TimeTicks now,
-                   base::trace_event::TracedValue* dict) const;
+  void AsValueInto(base::trace_event::TracedValue* dict) const;
 
   // The following methods violate principles of how BeginFrameArgs should be
   // used. These methods should only be used when there is no other choice.
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index 8b13d94..682944e 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -44,10 +44,6 @@
   TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue());
   DCHECK(client_);
   DCHECK(!state_machine_.BeginFrameNeeded());
-
-  begin_impl_frame_deadline_closure_ = base::Bind(
-      &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
-
   ProcessScheduledActions();
 }
 
@@ -225,19 +221,53 @@
 
   bool needs_begin_frames = state_machine_.BeginFrameNeeded();
   if (needs_begin_frames && !observing_begin_frame_source_) {
-    observing_begin_frame_source_ = true;
-    if (begin_frame_source_)
-      begin_frame_source_->AddObserver(this);
-    devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, true);
+    StartObservingBeginFrameSource();
   } else if (!needs_begin_frames && observing_begin_frame_source_) {
-    observing_begin_frame_source_ = false;
-    if (begin_frame_source_)
-      begin_frame_source_->RemoveObserver(this);
-    missed_begin_frame_task_.Cancel();
-    BeginImplFrameNotExpectedSoon();
-    devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
-                                                     false);
+    StopObservingBeginFrameSource();
   }
+
+  if (missed_begin_frame_args_.IsValid()) {
+    DCHECK(observing_begin_frame_source_);
+    DCHECK(missed_begin_frame_task_.IsCancelled());
+    missed_begin_frame_task_.Reset(base::Bind(&Scheduler::BeginImplFrameMissed,
+                                              weak_factory_.GetWeakPtr(),
+                                              missed_begin_frame_args_));
+    missed_begin_frame_args_ = BeginFrameArgs();
+    task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback());
+  }
+}
+
+void Scheduler::StartObservingBeginFrameSource() {
+  observing_begin_frame_source_ = true;
+
+  if (begin_frame_source_)
+    begin_frame_source_->AddObserver(this);
+
+  devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, true);
+}
+
+void Scheduler::StopObservingBeginFrameSource() {
+  observing_begin_frame_source_ = false;
+
+  if (begin_frame_source_)
+    begin_frame_source_->RemoveObserver(this);
+
+  missed_begin_frame_task_.Cancel();
+
+  if (missed_begin_frame_args_.IsValid()) {
+    // We need to confirm the ignored BeginFrame, since we don't have updates.
+    // To persist the confirmation for future BeginFrameAcks, we let the state
+    // machine know about the BeginFrame.
+    state_machine_.OnBeginFrameDroppedNotObserving(
+        missed_begin_frame_args_.source_id,
+        missed_begin_frame_args_.sequence_number);
+    SendBeginFrameAck(missed_begin_frame_args_, kBeginFrameSkipped);
+    missed_begin_frame_args_ = BeginFrameArgs();
+  }
+
+  BeginImplFrameNotExpectedSoon();
+
+  devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, false);
 }
 
 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) {
@@ -276,14 +306,20 @@
     return true;
   }
 
-  if (inside_process_scheduled_actions_) {
-    // The BFS can send a missed begin frame inside AddObserver. We can't handle
-    // a begin frame inside ProcessScheduledActions so post a task.
-    DCHECK_EQ(args.type, BeginFrameArgs::MISSED);
-    DCHECK(missed_begin_frame_task_.IsCancelled());
-    missed_begin_frame_task_.Reset(base::Bind(
-        &Scheduler::BeginImplFrameWithDeadline, base::Unretained(this), args));
-    task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback());
+  // Cancel any pending missed begin frame task because we're either handling
+  // this begin frame immediately or saving it as a missed frame for which we
+  // will post a new task.
+  missed_begin_frame_task_.Cancel();
+
+  // Save args if we're inside ProcessScheduledActions or the middle of a frame.
+  // At the end of ProcessScheduledActions and at the end of the current frame,
+  // we will post a task to handle the missed begin frame.
+  bool inside_begin_frame =
+      state_machine_.begin_impl_frame_state() ==
+      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME;
+  if (inside_process_scheduled_actions_ || inside_begin_frame) {
+    missed_begin_frame_args_ = args;
+    missed_begin_frame_args_.type = BeginFrameArgs::MISSED;
     return true;
   }
 
@@ -311,55 +347,39 @@
   state_machine_.SetResourcelessSoftwareDraw(false);
 }
 
-void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
-  // The storage for |args| is owned by the missed begin frame task. Therefore
-  // save |args| before cancelling the task either here or in the deadline.
-  BeginFrameArgs adjusted_args = args;
-  // Cancel the missed begin frame task in case the BFS sends a begin frame
-  // before the missed frame task runs.
+void Scheduler::BeginImplFrameMissed(const BeginFrameArgs& args) {
+  // The storage for the args is owned by the task so copy them before canceling
+  // the task.
+  BeginFrameArgs copy_args = args;
   missed_begin_frame_task_.Cancel();
+  BeginImplFrameWithDeadline(copy_args);
+}
+
+void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
+  DCHECK(!inside_process_scheduled_actions_);
+  DCHECK_EQ(state_machine_.begin_impl_frame_state(),
+            SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
 
   base::TimeTicks now = Now();
 
   // Discard missed begin frames if they are too late.
-  if (adjusted_args.type == BeginFrameArgs::MISSED &&
-      now > adjusted_args.deadline) {
+  if (args.type == BeginFrameArgs::MISSED && now > args.deadline) {
     skipped_last_frame_missed_exceeded_deadline_ = true;
-    SendBeginFrameAck(adjusted_args, kBeginFrameSkipped);
+    SendBeginFrameAck(args, kBeginFrameSkipped);
     return;
   }
 
   skipped_last_frame_missed_exceeded_deadline_ = false;
 
-  // Run the previous deadline if any.
-  if (state_machine_.begin_impl_frame_state() ==
-      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) {
-    OnBeginImplFrameDeadline();
-    // We may not need begin frames any longer.
-    if (!observing_begin_frame_source_) {
-      // We need to confirm the ignored BeginFrame, since we don't have updates.
-      // To persist the confirmation for future BeginFrameAcks, we let the state
-      // machine know about the BeginFrame.
-      state_machine_.OnBeginFrameDroppedNotObserving(args.source_id,
-                                                     args.sequence_number);
-      SendBeginFrameAck(adjusted_args, kBeginFrameSkipped);
-      return;
-    }
-  }
-  DCHECK_EQ(state_machine_.begin_impl_frame_state(),
-            SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
-
   bool main_thread_is_in_high_latency_mode =
       state_machine_.main_thread_missed_last_deadline();
   TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args",
-               adjusted_args.AsValue(), "main_thread_missed_last_deadline",
+               args.AsValue(), "main_thread_missed_last_deadline",
                main_thread_is_in_high_latency_mode);
   TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
                  "MainThreadLatency", main_thread_is_in_high_latency_mode);
 
-  DCHECK_EQ(state_machine_.begin_impl_frame_state(),
-            SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
-
+  BeginFrameArgs adjusted_args = args;
   adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate();
   adjusted_args.deadline -= kDeadlineFudgeFactor;
 
@@ -428,10 +448,14 @@
 
 void Scheduler::FinishImplFrame() {
   state_machine_.OnBeginImplFrameIdle();
+
+  // Call this before ProcessScheduledActions because we might send an ack for
+  // missed begin frame there.
+  SendBeginFrameAck(begin_impl_frame_tracker_.Current(), kBeginFrameFinished);
+
   ProcessScheduledActions();
 
   client_->DidFinishImplFrame();
-  SendBeginFrameAck(begin_main_frame_args_, kBeginFrameFinished);
   begin_impl_frame_tracker_.Finish();
 }
 
@@ -482,12 +506,11 @@
   // The synchronous compositor does not post a deadline task.
   DCHECK(!settings_.using_synchronous_renderer_compositor);
 
-  begin_impl_frame_deadline_task_.Cancel();
-  begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_);
+  begin_impl_frame_deadline_task_.Reset(base::Bind(
+      &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()));
 
   begin_impl_frame_deadline_mode_ =
       state_machine_.CurrentBeginImplFrameDeadlineMode();
-  base::TimeTicks deadline;
   switch (begin_impl_frame_deadline_mode_) {
     case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE:
       // No deadline.
@@ -495,18 +518,18 @@
     case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE:
       // We are ready to draw a new active tree immediately.
       // We don't use Now() here because it's somewhat expensive to call.
-      deadline = base::TimeTicks();
+      deadline_ = base::TimeTicks();
       break;
     case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR:
       // We are animating on the impl thread but we can wait for some time.
-      deadline = begin_impl_frame_tracker_.Current().deadline;
+      deadline_ = begin_impl_frame_tracker_.Current().deadline;
       break;
     case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE:
       // We are blocked for one reason or another and we should wait.
       // TODO(brianderson): Handle long deadlines (that are past the next
       // frame's frame time) properly instead of using this hack.
-      deadline = begin_impl_frame_tracker_.Current().frame_time +
-                 begin_impl_frame_tracker_.Current().interval;
+      deadline_ = begin_impl_frame_tracker_.Current().frame_time +
+                  begin_impl_frame_tracker_.Current().interval;
       break;
     case SchedulerStateMachine::
         BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW:
@@ -520,9 +543,11 @@
   TRACE_EVENT2("cc", "Scheduler::ScheduleBeginImplFrameDeadline", "mode",
                SchedulerStateMachine::BeginImplFrameDeadlineModeToString(
                    begin_impl_frame_deadline_mode_),
-               "deadline", deadline);
+               "deadline", deadline_);
 
-  base::TimeDelta delta = std::max(deadline - Now(), base::TimeDelta());
+  deadline_scheduled_at_ = Now();
+  base::TimeDelta delta =
+      std::max(deadline_ - deadline_scheduled_at_, base::TimeDelta());
   task_runner_->PostDelayedTask(
       FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta);
 }
@@ -685,8 +710,6 @@
 }
 
 void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const {
-  base::TimeTicks now = Now();
-
   state->BeginDictionary("state_machine");
   state_machine_.AsValueInto(state);
   state->EndDictionary();
@@ -707,8 +730,23 @@
                    SchedulerStateMachine::BeginImplFrameDeadlineModeToString(
                        begin_impl_frame_deadline_mode_));
 
-  state->BeginDictionary("begin_impl_frame_args");
-  begin_impl_frame_tracker_.AsValueInto(now, state);
+  state->SetDouble("deadline_ms",
+                   (deadline_ - base::TimeTicks()).InMillisecondsF());
+  state->SetDouble(
+      "deadline_scheduled_at_ms",
+      (deadline_scheduled_at_ - base::TimeTicks()).InMillisecondsF());
+
+  state->SetDouble("now_ms", (Now() - base::TimeTicks()).InMillisecondsF());
+  state->SetDouble("now_to_deadline_ms", (deadline_ - Now()).InMillisecondsF());
+  state->SetDouble("now_to_deadline_scheduled_at_ms",
+                   (deadline_scheduled_at_ - Now()).InMillisecondsF());
+
+  state->BeginDictionary("begin_impl_frame_tracker");
+  begin_impl_frame_tracker_.AsValueInto(state);
+  state->EndDictionary();
+
+  state->BeginDictionary("missed_begin_frame_args");
+  missed_begin_frame_args_.AsValueInto(state);
   state->EndDictionary();
 
   state->BeginDictionary("begin_frame_observer_state");
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h
index b22e9c3..ed609b31 100644
--- a/cc/scheduler/scheduler.h
+++ b/cc/scheduler/scheduler.h
@@ -176,11 +176,13 @@
   SchedulerStateMachine::BeginImplFrameDeadlineMode
       begin_impl_frame_deadline_mode_ =
           SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE;
+  base::TimeTicks deadline_;
+  base::TimeTicks deadline_scheduled_at_;
 
   BeginFrameTracker begin_impl_frame_tracker_;
   BeginFrameArgs begin_main_frame_args_;
+  BeginFrameArgs missed_begin_frame_args_;
 
-  base::Closure begin_impl_frame_deadline_closure_;
   base::CancelableClosure begin_impl_frame_deadline_task_;
   base::CancelableClosure missed_begin_frame_task_;
 
@@ -196,6 +198,8 @@
   void ScheduleBeginImplFrameDeadlineIfNeeded();
   void BeginImplFrameNotExpectedSoon();
   void SetupNextBeginFrameIfNeeded();
+  void StartObservingBeginFrameSource();
+  void StopObservingBeginFrameSource();
   void DrawIfPossible();
   void DrawForced();
   void ProcessScheduledActions();
@@ -210,6 +214,7 @@
       base::TimeTicks now) const;
   void AdvanceCommitStateIfPossible();
   bool IsBeginMainFrameSentOrStarted() const;
+  void BeginImplFrameMissed(const BeginFrameArgs& args);
   void BeginImplFrameWithDeadline(const BeginFrameArgs& args);
   void BeginImplFrameSynchronous(const BeginFrameArgs& args);
   void BeginImplFrame(const BeginFrameArgs& args, base::TimeTicks now);
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
index e0d6bad..5cb4a2d 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -288,6 +288,10 @@
   state->SetBoolean("did_submit_in_last_frame", did_submit_in_last_frame_);
   state->SetBoolean("needs_impl_side_invalidation",
                     needs_impl_side_invalidation_);
+  state->SetBoolean("current_pending_tree_is_impl_side",
+                    current_pending_tree_is_impl_side_);
+  state->SetBoolean("previous_pending_tree_was_impl_side",
+                    previous_pending_tree_was_impl_side_);
   state->EndDictionary();
 }
 
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc
index 72e31f5..82446ad7 100644
--- a/cc/scheduler/scheduler_unittest.cc
+++ b/cc/scheduler/scheduler_unittest.cc
@@ -397,9 +397,13 @@
     // it will be already in the task queue.
     if (scheduler_->begin_frame_source() ==
         fake_external_begin_frame_source_.get()) {
+      // Run pending task for previous deadline first.
+      task_runner_->RunPendingTasks();
       EXPECT_TRUE(scheduler_->begin_frames_expected());
       SendNextBeginFrame();
     } else {
+      // Begin frame might be queued up and posted after the previous deadline
+      // runs so run tasks until we get to the next frame.
       task_runner_->RunTasksWhile(client_->FrameHasNotAdvancedCallback());
     }
   }
@@ -3510,10 +3514,11 @@
   client_->Reset();
 
   // Send the next BeginFrame before the previous one's deadline was executed.
-  // This should trigger the previous BeginFrame's deadline synchronously,
-  // during which tiles will be prepared. As a result of that, no further
-  // BeginFrames will be needed, and the new BeginFrame should be dropped.
+  // This will wait for the previous deadline after which no further BeginFrames
+  // will be needed, and the new BeginFrame should be dropped.
   BeginFrameArgs args = SendNextBeginFrame();
+
+  task_runner().RunPendingTasks();  // Run posted deadline.
   EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 3);
   EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
   EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
@@ -3680,5 +3685,60 @@
       fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
 }
 
+TEST_F(SchedulerTest, BeginFrameWhilePreviousDeadlinePending) {
+  SetUpScheduler(EXTERNAL_BFS);
+
+  scheduler_->SetNeedsRedraw();
+
+  client_->Reset();
+  EXPECT_SCOPED(AdvanceFrame());
+  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
+
+  // Do not run pending deadline but send a new begin frame. The begin frame is
+  // saved and run when the previous frame is over.
+  client_->Reset();
+  SendNextBeginFrame();
+  EXPECT_NO_ACTION(client_);
+
+  task_runner_->RunPendingTasks();
+  EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+
+  // The saved begin frame is posted as a task.
+  client_->Reset();
+  task_runner_->RunPendingTasks();
+  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
+}
+
+TEST_F(SchedulerTest, IncomingBeginFrameReplacesSavedBeginFrame) {
+  SetUpScheduler(EXTERNAL_BFS);
+
+  scheduler_->SetNeedsRedraw();
+
+  client_->Reset();
+  EXPECT_SCOPED(AdvanceFrame());
+  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
+
+  // Send two BeginFrames while deadline is pending.
+  client_->Reset();
+  SendNextBeginFrame();
+  EXPECT_NO_ACTION(client_);
+
+  SendNextBeginFrame();
+  EXPECT_NO_ACTION(client_);
+
+  task_runner_->RunPendingTasks();
+  EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
+
+  // Only the last BeginFrame runs.
+  client_->Reset();
+  task_runner_->RunPendingTasks();
+  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
+
+  client_->Reset();
+  task_runner_->RunPendingTasks();
+  EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
+  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
+}
+
 }  // namespace
 }  // namespace cc
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 39e641c1..8a16671 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -364,6 +364,8 @@
     test_hooks_->BeginMainFrameNotExpectedSoon();
   }
 
+  bool IsForSubframe() override { return false; }
+
  private:
   explicit LayerTreeHostClientForTesting(TestHooks* test_hooks)
       : test_hooks_(test_hooks) {}
diff --git a/cc/test/pixel_comparator.cc b/cc/test/pixel_comparator.cc
index 4b43188..229235b5 100644
--- a/cc/test/pixel_comparator.cc
+++ b/cc/test/pixel_comparator.cc
@@ -28,9 +28,6 @@
   DCHECK(actual_bmp.width() == expected_bmp.width() &&
          actual_bmp.height() == expected_bmp.height());
 
-  SkAutoLockPixels lock_actual_bmp(actual_bmp);
-  SkAutoLockPixels lock_expected_bmp(expected_bmp);
-
   for (int x = 0; x < actual_bmp.width(); ++x) {
     for (int y = 0; y < actual_bmp.height(); ++y) {
       SkColor actual_color = actual_bmp.getColor(x, y);
@@ -96,9 +93,6 @@
   // Check that bitmaps are not empty.
   DCHECK(actual_bmp.width() > 0 && actual_bmp.height() > 0);
 
-  SkAutoLockPixels lock_actual_bmp(actual_bmp);
-  SkAutoLockPixels lock_expected_bmp(expected_bmp);
-
   for (int x = 0; x < actual_bmp.width(); ++x) {
     for (int y = 0; y < actual_bmp.height(); ++y) {
       SkColor actual_color = actual_bmp.getColor(x, y);
diff --git a/cc/test/stub_layer_tree_host_client.cc b/cc/test/stub_layer_tree_host_client.cc
index 650faaf..a3205d75 100644
--- a/cc/test/stub_layer_tree_host_client.cc
+++ b/cc/test/stub_layer_tree_host_client.cc
@@ -8,4 +8,8 @@
 
 StubLayerTreeHostClient::~StubLayerTreeHostClient() = default;
 
+bool StubLayerTreeHostClient::IsForSubframe() {
+  return false;
+}
+
 }  // namespace cc
diff --git a/cc/test/stub_layer_tree_host_client.h b/cc/test/stub_layer_tree_host_client.h
index dca0005..065f692 100644
--- a/cc/test/stub_layer_tree_host_client.h
+++ b/cc/test/stub_layer_tree_host_client.h
@@ -34,6 +34,8 @@
   void DidCommitAndDrawFrame() override {}
   void DidReceiveCompositorFrameAck() override {}
   void DidCompletePageScaleAnimation() override {}
+
+  bool IsForSubframe() override;
 };
 
 }  // namespace cc
diff --git a/cc/trees/layer_tree_host_client.h b/cc/trees/layer_tree_host_client.h
index 03c2431..84416d6 100644
--- a/cc/trees/layer_tree_host_client.h
+++ b/cc/trees/layer_tree_host_client.h
@@ -58,6 +58,10 @@
   virtual void DidCommitAndDrawFrame() = 0;
   virtual void DidReceiveCompositorFrameAck() = 0;
   virtual void DidCompletePageScaleAnimation() = 0;
+  // The only time a subframe ever gets its own LayerTree is when the subframe
+  // renders in a different process its ancestors; this returns true in
+  // that case.
+  virtual bool IsForSubframe() = 0;
 
  protected:
   virtual ~LayerTreeHostClient() {}
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index bd017fa7..3a117b2 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -3007,6 +3007,14 @@
   }
   scroll_state.set_is_ending(true);
   ScrollEnd(&scroll_state);
+  if (settings_.is_layer_tree_for_subframe &&
+      scroll_status.thread == SCROLL_ON_IMPL_THREAD) {
+    // If we get to here, we shouldn't return SCROLL_ON_IMPL_THREAD as otherwise
+    // we'll mark the scroll as handled and the scroll won't bubble.
+    scroll_status.thread = SCROLL_IGNORED;
+    scroll_status.main_thread_scrolling_reasons =
+        MainThreadScrollingReason::kNotScrollable;
+  }
   return scroll_status;
 }
 
@@ -3876,9 +3884,7 @@
       gfx::ColorSpace::CreateSRGB());
 
   if (!scaled) {
-    AutoLockUIResourceBitmap bitmap_lock(bitmap);
-    auto* pixels = bitmap_lock.GetPixels();
-    resource_provider_->CopyToResource(id, pixels, source_size);
+    resource_provider_->CopyToResource(id, bitmap.GetPixels(), source_size);
   } else {
     // Only support auto-resizing for N32 textures (since this is primarily for
     // scrollbars). Users of other types need to ensure they are not too big.
@@ -3895,10 +3901,9 @@
         source_size.width(), source_size.height(), kPremul_SkAlphaType);
     int row_bytes = source_size.width() * 4;
 
-    AutoLockUIResourceBitmap bitmap_lock(bitmap);
     SkBitmap source_bitmap;
     source_bitmap.setInfo(info, row_bytes);
-    source_bitmap.setPixels(const_cast<uint8_t*>(bitmap_lock.GetPixels()));
+    source_bitmap.setPixels(const_cast<uint8_t*>(bitmap.GetPixels()));
 
     // This applies the scale to draw the |bitmap| into |scaled_bitmap|.
     SkBitmap scaled_bitmap;
@@ -3912,7 +3917,6 @@
     scaled_canvas.clear(SK_ColorTRANSPARENT);
     scaled_canvas.drawBitmap(source_bitmap, 0, 0);
 
-    SkAutoLockPixels scaled_bitmap_lock(scaled_bitmap);
     auto* pixels = static_cast<uint8_t*>(scaled_bitmap.getPixels());
     resource_provider_->CopyToResource(id, pixels, upload_size);
   }
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index b6237c9..996d627 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -110,6 +110,10 @@
   // Indicates that the LayerTreeHost should defer commits unless it has a valid
   // LocalSurfaceId set.
   bool enable_surface_synchronization = false;
+
+  // Indicates the case when a sub-frame gets its own LayerTree because it's
+  // rendered in a different process from its ancestor frames.
+  bool is_layer_tree_for_subframe = false;
 };
 
 }  // namespace cc
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbar.java
index 7bdda2b..f7982742 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbar.java
@@ -82,6 +82,9 @@
     /** Whether the search key should trigger a new search. */
     private boolean mSearchKeyShouldTriggerSearch;
 
+    /** Whether startFinding() should also hide the keyboard. **/
+    private boolean mHideKeyboardWhileFinding;
+
     private boolean mActive;
 
     private Handler mHandler = new Handler();
@@ -124,7 +127,7 @@
         public boolean onKeyDown(int keyCode, KeyEvent event) {
             if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_F3
                     || (keyCode == KeyEvent.KEYCODE_G && event.isCtrlPressed())) {
-                mFindToolbar.hideKeyboardAndStartFinding(!event.isShiftPressed());
+                mFindToolbar.startFinding(!event.isShiftPressed());
                 return true;
             }
             return super.onKeyDown(keyCode, event);
@@ -204,6 +207,8 @@
                 deactivate();
             }
         };
+
+        mHideKeyboardWhileFinding = true;
     }
 
     @Override
@@ -280,7 +285,7 @@
                 // Otherwise just revisit the current active match.
                 if (mSearchKeyShouldTriggerSearch) {
                     mSearchKeyShouldTriggerSearch = false;
-                    hideKeyboardAndStartFinding(true);
+                    startFinding(true);
                 } else {
                     UiUtils.hideKeyboard(mFindQuery);
                     mFindInPageBridge.activateFindInPageResultForAccessibility();
@@ -296,7 +301,7 @@
         mFindPrevButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
-                hideKeyboardAndStartFinding(false);
+                startFinding(false);
             }
         });
 
@@ -304,7 +309,7 @@
         mFindNextButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
-                hideKeyboardAndStartFinding(true);
+                startFinding(true);
             }
         });
 
@@ -323,13 +328,13 @@
     protected void findResultSelected(Rect rect) {
     }
 
-    private void hideKeyboardAndStartFinding(boolean forward) {
+    private void startFinding(boolean forward) {
         if (mFindInPageBridge == null) return;
 
         final String findQuery = mFindQuery.getText().toString();
         if (findQuery.length() == 0) return;
 
-        UiUtils.hideKeyboard(mFindQuery);
+        if (mHideKeyboardWhileFinding) UiUtils.hideKeyboard(mFindQuery);
         mFindInPageBridge.startFinding(findQuery, forward, false);
         mFindInPageBridge.activateFindInPageResultForAccessibility();
         mAccessibilityDidActivateResult = true;
@@ -502,6 +507,13 @@
     }
 
     /**
+     * By default the keyboard is hidden when the user arrows through results. Calling this method
+     * will disable keyboard hiding while finding.
+     */
+    public void disableHideKeyboardWhileFinding() {
+        mHideKeyboardWhileFinding = false;
+    }
+    /**
      * Handles updating any visual elements of the find toolbar based on changes to the tab model.
      * @param isIncognito Whether the current tab model is incognito or not.
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarManager.java
index 1d3152b9..bcc3cd6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/findinpage/FindToolbarManager.java
@@ -70,6 +70,7 @@
             mFindToolbar = (FindToolbar) ((ViewStub) mActivity.findViewById(stubId)).inflate();
             mFindToolbar.setTabModelSelector(mActivity.getTabModelSelector());
             mFindToolbar.setWindowAndroid(mActivity.getWindowAndroid());
+            if (mActivity.getBottomSheet() != null) mFindToolbar.disableHideKeyboardWhileFinding();
             mFindToolbar.setActionModeCallbackForTextEdit(mCallback);
             mFindToolbar.setObserver(new FindToolbarObserver() {
                 @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/snackbar/DataReductionPromoSnackbarControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/snackbar/DataReductionPromoSnackbarControllerTest.java
index c165612..678be82 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/snackbar/DataReductionPromoSnackbarControllerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/snackbar/DataReductionPromoSnackbarControllerTest.java
@@ -151,7 +151,9 @@
 
     @UiThreadTest
     @MediumTest
-    @CommandLineFlags.Add({ "enable-data-reduction-proxy-savings-promo" })
+    @CommandLineFlags.Add({
+            "enable-data-reduction-proxy-savings-promo",
+            "disable-field-trial-config"})
     public void testDataReductionPromoSnackbarControllerCommandLineFlag() {
         assertFalse(DataReductionPromoUtils.hasSnackbarPromoBeenInitWithStartingSavedBytes());
         mController.maybeShowDataReductionPromoSnackbar(0);
diff --git a/chrome/browser/android/thumbnail/thumbnail_cache.cc b/chrome/browser/android/thumbnail/thumbnail_cache.cc
index ab430d29..c75c19e 100644
--- a/chrome/browser/android/thumbnail/thumbnail_cache.cc
+++ b/chrome/browser/android/thumbnail/thumbnail_cache.cc
@@ -502,8 +502,6 @@
     return false;
 
   // Write ETC1 header.
-  compressed_data->lockPixels();
-
   unsigned char etc1_buffer[ETC_PKM_HEADER_SIZE];
   etc1_pkm_format_header(etc1_buffer,
                          compressed_data->info().width(),
@@ -523,8 +521,6 @@
   if (pixel_bytes_written != data_size)
     return false;
 
-  compressed_data->unlockPixels();
-
   if (!WriteBigEndianToFile(file, kCurrentExtraVersion))
     return false;
 
@@ -575,7 +571,6 @@
   gfx::Size content_size;
 
   if (!raw_data.empty()) {
-    SkAutoLockPixels raw_data_lock(raw_data);
     gfx::Size raw_data_size(raw_data.width(), raw_data.height());
     size_t pixel_size = 4;  // Pixel size is 4 bytes for kARGB_8888_Config.
     size_t stride = pixel_size * raw_data_size.width();
@@ -590,7 +585,6 @@
     sk_sp<SkPixelRef> etc1_pixel_ref(SkMallocPixelRef::MakeWithData(
         info, 0, NULL, std::move(etc1_pixel_data)));
 
-    etc1_pixel_ref->lockPixels();
     bool success = etc1_encode_image(
         reinterpret_cast<unsigned char*>(raw_data.getPixels()),
         raw_data_size.width(),
@@ -601,7 +595,6 @@
         encoded_size.width(),
         encoded_size.height());
     etc1_pixel_ref->setImmutable();
-    etc1_pixel_ref->unlockPixels();
 
     if (success) {
       compressed_data = std::move(etc1_pixel_ref);
@@ -860,8 +853,6 @@
                                            buffer_size.height(),
                                            kRGBA_8888_SkColorType,
                                            kOpaque_SkAlphaType));
-    SkAutoLockPixels raw_data_lock(raw_data);
-    compressed_data->lockPixels();
     success = etc1_decode_image(
         reinterpret_cast<unsigned char*>(compressed_data->pixels()),
         reinterpret_cast<unsigned char*>(raw_data.getPixels()),
@@ -869,7 +860,6 @@
         buffer_size.height(),
         raw_data.bytesPerPixel(),
         raw_data.rowBytes());
-    compressed_data->unlockPixels();
     raw_data.setImmutable();
 
     if (!success) {
@@ -884,7 +874,6 @@
                                                    content_size.height(),
                                                    kRGBA_8888_SkColorType,
                                                    kOpaque_SkAlphaType));
-      SkAutoLockPixels raw_data_small_lock(raw_data_small);
       SkCanvas small_canvas(raw_data_small);
       small_canvas.drawBitmap(raw_data, 0, 0);
       raw_data_small.setImmutable();
@@ -911,7 +900,6 @@
     float scale) {
   DCHECK(!bitmap.empty());
   DCHECK_GT(scale, 0);
-  SkAutoLockPixels bitmap_lock(bitmap);
   float new_scale = 1.f / kApproximationScaleFactor;
 
   gfx::Size dst_size = gfx::ScaleToFlooredSize(
@@ -922,8 +910,6 @@
                                            bitmap.info().colorType(),
                                            bitmap.info().alphaType()));
   dst_bitmap.eraseColor(0);
-  SkAutoLockPixels dst_bitmap_lock(dst_bitmap);
-
   SkCanvas canvas(dst_bitmap);
   canvas.scale(new_scale, new_scale);
   canvas.drawBitmap(bitmap, 0, 0, NULL);
diff --git a/chrome/browser/chromeos/accessibility/accessibility_highlight_manager_interactive_uitest.cc b/chrome/browser/chromeos/accessibility/accessibility_highlight_manager_interactive_uitest.cc
index 5511e7ea..ae08305aba9 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_highlight_manager_interactive_uitest.cc
+++ b/chrome/browser/chromeos/accessibility/accessibility_highlight_manager_interactive_uitest.cc
@@ -92,8 +92,6 @@
   void ComputeImageStats() {
     diff_count_ = 0;
     double accum[4] = {0, 0, 0, 0};
-    SkAutoLockPixels lock_before(before_bmp_);
-    SkAutoLockPixels lock_after(after_bmp_);
     for (int x = 0; x < before_bmp_.width(); ++x) {
       for (int y = 0; y < before_bmp_.height(); ++y) {
         SkColor before_color = before_bmp_.getColor(x, y);
@@ -139,7 +137,6 @@
       run_loop_quitter_ = run_loop.QuitClosure();
       run_loop.Run();
       SkBitmap bitmap = image_.AsBitmap();
-      SkAutoLockPixels lock(bitmap);
       if (bitmap.width() != bounds.width() ||
           bitmap.height() != bounds.height()) {
         LOG(INFO) << "Bitmap not correct size, trying to capture again";
diff --git a/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler.cc b/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler.cc
index e5f8402..952e4de2 100644
--- a/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler.cc
+++ b/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler.h"
 
-#include "ash/shelf/shelf_delegate.h"
+#include "ash/shelf/shelf_model.h"
 #include "ash/shell.h"
 #include "base/bind.h"
 #include "base/command_line.h"
@@ -93,11 +93,11 @@
       // Remove the pinned Play Store icon launcher in Shelf.
       // This is only for non-Managed cases. In managed cases, it is expected
       // to be "disabled" rather than "removed", so keep it here.
-      auto* shelf_delegate = ash::Shell::HasInstance()
-                                 ? ash::Shell::Get()->shelf_delegate()
-                                 : nullptr;
-      if (shelf_delegate)
-        shelf_delegate->UnpinAppWithID(ArcSupportHost::kHostAppId);
+      auto* shelf_model = ash::Shell::HasInstance()
+                              ? ash::Shell::Get()->shelf_model()
+                              : nullptr;
+      if (shelf_model)
+        shelf_model->UnpinAppWithID(ArcSupportHost::kHostAppId);
     }
   }
 
diff --git a/chrome/browser/chromeos/certificate_provider/certificate_info.h b/chrome/browser/chromeos/certificate_provider/certificate_info.h
index 59eb7b5..5f70613 100644
--- a/chrome/browser/chromeos/certificate_provider/certificate_info.h
+++ b/chrome/browser/chromeos/certificate_provider/certificate_info.h
@@ -5,7 +5,6 @@
 #ifndef CHROME_BROWSER_CHROMEOS_CERTIFICATE_PROVIDER_CERTIFICATE_INFO_H_
 #define CHROME_BROWSER_CHROMEOS_CERTIFICATE_PROVIDER_CERTIFICATE_INFO_H_
 
-#include <stddef.h>
 #include <vector>
 
 #include "base/memory/ref_counted.h"
@@ -22,8 +21,6 @@
   CertificateInfo(const CertificateInfo& other);
   ~CertificateInfo();
 
-  net::SSLPrivateKey::Type type = net::SSLPrivateKey::Type::RSA;
-  size_t max_signature_length_in_bytes = 0;
   scoped_refptr<net::X509Certificate> certificate;
   std::vector<net::SSLPrivateKey::Hash> supported_hashes;
 };
diff --git a/chrome/browser/chromeos/certificate_provider/certificate_provider_service.cc b/chrome/browser/chromeos/certificate_provider/certificate_provider_service.cc
index 6726c97..7e4294e 100644
--- a/chrome/browser/chromeos/certificate_provider/certificate_provider_service.cc
+++ b/chrome/browser/chromeos/certificate_provider/certificate_provider_service.cc
@@ -113,9 +113,7 @@
       const base::WeakPtr<CertificateProviderService>& service);
 
   // net::SSLPrivateKey:
-  Type GetType() override;
   std::vector<net::SSLPrivateKey::Hash> GetDigestPreferences() override;
-  size_t GetMaxSignatureLengthInBytes() override;
   void SignDigest(Hash hash,
                   const base::StringPiece& input,
                   const SignCallback& callback) override;
@@ -227,24 +225,12 @@
   thread_checker_.DetachFromThread();
 }
 
-CertificateProviderService::SSLPrivateKey::Type
-CertificateProviderService::SSLPrivateKey::GetType() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  return cert_info_.type;
-}
-
 std::vector<net::SSLPrivateKey::Hash>
 CertificateProviderService::SSLPrivateKey::GetDigestPreferences() {
   DCHECK(thread_checker_.CalledOnValidThread());
   return cert_info_.supported_hashes;
 }
 
-size_t
-CertificateProviderService::SSLPrivateKey::GetMaxSignatureLengthInBytes() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  return cert_info_.max_signature_length_in_bytes;
-}
-
 // static
 void CertificateProviderService::SSLPrivateKey::SignDigestOnServiceTaskRunner(
     const base::WeakPtr<CertificateProviderService>& service,
diff --git a/chrome/browser/chromeos/certificate_provider/certificate_provider_service_unittest.cc b/chrome/browser/chromeos/certificate_provider/certificate_provider_service_unittest.cc
index 71ae76ff..3fd5e99 100644
--- a/chrome/browser/chromeos/certificate_provider/certificate_provider_service_unittest.cc
+++ b/chrome/browser/chromeos/certificate_provider/certificate_provider_service_unittest.cc
@@ -53,21 +53,14 @@
   cert_info.certificate =
       net::ImportCertFromFile(net::GetTestCertsDirectory(), cert_filename);
   EXPECT_TRUE(cert_info.certificate) << "Could not load " << cert_filename;
-  cert_info.type = net::SSLPrivateKey::Type::RSA;
   cert_info.supported_hashes.push_back(net::SSLPrivateKey::Hash::SHA256);
-  cert_info.max_signature_length_in_bytes = 123;
 
   return cert_info;
 }
 
 bool IsKeyEqualToCertInfo(const certificate_provider::CertificateInfo& info,
                           net::SSLPrivateKey* key) {
-  if (info.supported_hashes != key->GetDigestPreferences())
-    return false;
-
-  return key->GetType() == info.type &&
-         key->GetMaxSignatureLengthInBytes() ==
-             info.max_signature_length_in_bytes;
+  return info.supported_hashes == key->GetDigestPreferences();
 }
 
 class TestDelegate : public CertificateProviderService::Delegate {
diff --git a/chrome/browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric_cpu.cpp b/chrome/browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric_cpu.cpp
index 03c3789c..b77a3bc 100644
--- a/chrome/browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric_cpu.cpp
+++ b/chrome/browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric_cpu.cpp
@@ -53,8 +53,6 @@
 
   // Prepare the pixels for comparison
   result->poiCount = 0;
-  baseline->lockPixels();
-  test->lockPixels();
   for (int y = 0; y < height; y++) {
     // Grab a row from each image for easy comparison
     // TODO(epoger): The code below already assumes 4 bytes per pixel, so I
@@ -102,23 +100,11 @@
       }
     }
   }
-  test->unlockPixels();
-  baseline->unlockPixels();
 
   result->maxRedDiff = maxRedDiff;
   result->maxGreenDiff = maxGreenDiff;
   result->maxBlueDiff = maxBlueDiff;
 
-  if (bitmapsToCreate.alphaMask) {
-    result->poiAlphaMask.unlockPixels();
-  }
-  if (bitmapsToCreate.rgbDiff) {
-    result->rgbDiffBitmap.unlockPixels();
-  }
-  if (bitmapsToCreate.whiteDiff) {
-    result->whiteDiffBitmap.unlockPixels();
-  }
-
   // Calculates the percentage of identical pixels
   result->result = 1.0 - ((double)result->poiCount / (width * height));
 
diff --git a/chrome/browser/chromeos/login/screenshot_testing/SkPMetric.cpp b/chrome/browser/chromeos/login/screenshot_testing/SkPMetric.cpp
index 0f71ad5d..c551c504 100644
--- a/chrome/browser/chromeos/login/screenshot_testing/SkPMetric.cpp
+++ b/chrome/browser/chromeos/login/screenshot_testing/SkPMetric.cpp
@@ -139,7 +139,6 @@
   DCHECK(outImageLAB->width == width);
   DCHECK(outImageLAB->height == height);
 
-  bitmap->lockPixels();
   RGB rgb;
   LAB lab;
   for (int y = 0; y < height; y++) {
@@ -153,7 +152,6 @@
       outImageLAB->writePixel(x, y, lab);
     }
   }
-  bitmap->unlockPixels();
   return true;
 }
 
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_manager_test_util.cc b/chrome/browser/chromeos/login/users/avatar/user_image_manager_test_util.cc
index 33e8b476b..1875e95 100644
--- a/chrome/browser/chromeos/login/users/avatar/user_image_manager_test_util.cc
+++ b/chrome/browser/chromeos/login/users/avatar/user_image_manager_test_util.cc
@@ -37,8 +37,6 @@
   if (second_bitmap->getSize() != size)
     return false;
 
-  SkAutoLockPixels first_pixel_lock(*first_bitmap);
-  SkAutoLockPixels second_pixel_lock(*second_bitmap);
   uint8_t* first_data = reinterpret_cast<uint8_t*>(first_bitmap->getPixels());
   uint8_t* second_data = reinterpret_cast<uint8_t*>(second_bitmap->getPixels());
   for (size_t i = 0; i < size; ++i) {
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_policy_browsertest.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_policy_browsertest.cc
index 0b12461d..fdf9002 100644
--- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_policy_browsertest.cc
+++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_policy_browsertest.cc
@@ -102,7 +102,6 @@
     return SkColorSetARGB(0, 0, 0, 0);
   }
   uint64_t a = 0, r = 0, g = 0, b = 0;
-  bitmap.lockPixels();
   for (int x = 0; x < bitmap.width(); ++x) {
     for (int y = 0; y < bitmap.height(); ++y) {
       const SkColor color = bitmap.getColor(x, y);
@@ -112,7 +111,6 @@
       b += SkColorGetB(color);
     }
   }
-  bitmap.unlockPixels();
   uint64_t pixel_number = bitmap.width() * bitmap.height();
   return SkColorSetARGB((a + pixel_number / 2) / pixel_number,
                         (r + pixel_number / 2) / pixel_number,
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.cc
index 6015a69..83d0e09 100644
--- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.cc
+++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.cc
@@ -137,10 +137,8 @@
     return false;
   }
 
-  bitmap->lockPixels();
   gfx::Point center = gfx::Rect(image.size()).CenterPoint();
   SkColor image_color = bitmap->getColor(center.x(), center.y());
-  bitmap->unlockPixels();
 
   const int kDiff = 3;
   if (std::abs(static_cast<int>(SkColorGetA(image_color)) -
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc b/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc
index f9948acc..c82a55c 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc
@@ -153,11 +153,6 @@
 
   MessageCenter* message_center() { return MessageCenter::Get(); }
 
-  void SetIgnoreNoNetworkForTesting() {
-    network_portal_detector_->notification_controller_
-        ->SetIgnoreNoNetworkForTesting();
-  }
-
   const NetworkPortalWebDialog* GetDialog() const {
     return network_portal_detector_->notification_controller_
         ->GetDialogForTesting();
@@ -253,8 +248,6 @@
   LoginUser(kTestUser);
   content::RunAllPendingInMessageLoop();
 
-  SetIgnoreNoNetworkForTesting();
-
   ProfileManager::GetActiveUserProfile()->GetPrefs()->SetBoolean(
       prefs::kCaptivePortalAuthenticationIgnoresProxy, preference_value);
 
diff --git a/chrome/browser/chromeos/net/network_portal_notification_controller.cc b/chrome/browser/chromeos/net/network_portal_notification_controller.cc
index fcf4817..1a56ac53 100644
--- a/chrome/browser/chromeos/net/network_portal_notification_controller.cc
+++ b/chrome/browser/chromeos/net/network_portal_notification_controller.cc
@@ -259,6 +259,14 @@
     const NetworkState* network) {
   if (!network)
     return;
+
+  bool network_changed = (default_network_id_ != network->guid());
+  default_network_id_ = network->guid();
+  if (!network_changed && network->connection_state() == shill::kStateOnline &&
+      dialog_) {
+    dialog_->Close();
+  }
+
   Profile* profile = GetProfileForPrimaryUser();
   extensions::NetworkingConfigService* networking_config_service =
       GetNetworkingConfigService(profile);
@@ -276,16 +284,6 @@
   if (!network ||
       state.status != NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL) {
     last_network_guid_.clear();
-
-    // In browser tests we initiate fake network portal detection, but network
-    // state usually stays connected. This way, after dialog is shown, it is
-    // immediately closed. The testing check below prevents dialog from closing.
-    if (dialog_ &&
-        (!ignore_no_network_for_testing_ ||
-         state.status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE)) {
-      dialog_->Close();
-    }
-
     CloseNotification();
     return;
   }
@@ -432,10 +430,6 @@
     retry_detection_callback_.Run();
 }
 
-void NetworkPortalNotificationController::SetIgnoreNoNetworkForTesting() {
-  ignore_no_network_for_testing_ = true;
-}
-
 void NetworkPortalNotificationController::CloseDialog() {
   if (dialog_)
     dialog_->Close();
diff --git a/chrome/browser/chromeos/net/network_portal_notification_controller.h b/chrome/browser/chromeos/net/network_portal_notification_controller.h
index 635d104..4a3dfdb 100644
--- a/chrome/browser/chromeos/net/network_portal_notification_controller.h
+++ b/chrome/browser/chromeos/net/network_portal_notification_controller.h
@@ -125,6 +125,9 @@
       const NetworkState* network,
       const NetworkPortalDetector::CaptivePortalState& state) override;
 
+  // Unique identifier of the default network.
+  std::string default_network_id_;
+
   // Last network guid for which notification was displayed.
   std::string last_network_guid_;
 
@@ -134,9 +137,6 @@
   // Currently displayed authorization dialog, or NULL if none.
   NetworkPortalWebDialog* dialog_ = nullptr;
 
-  // Do not close Portal Login dialog on "No network" error in browser tests.
-  bool ignore_no_network_for_testing_ = false;
-
   // This is called if the controller learns about a potential change of the
   // captive portal.
   base::Closure retry_detection_callback_;
diff --git a/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job_unittest.cc b/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job_unittest.cc
index 574f538..72b3b4e5 100644
--- a/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job_unittest.cc
+++ b/chrome/browser/chromeos/policy/remote_commands/device_command_screenshot_job_unittest.cc
@@ -124,7 +124,6 @@
     for (int x = 0; x < width; ++x)
       *bmp.getAddr32(x, y) = background_color;
   }
-  SkAutoLockPixels lock(bmp);
   scoped_refptr<base::RefCountedBytes> png_bytes(new base::RefCountedBytes());
   gfx::PNGCodec::ColorFormat color_format = gfx::PNGCodec::FORMAT_RGBA;
   if (!gfx::PNGCodec::Encode(
diff --git a/chrome/browser/devtools/devtools_eye_dropper.cc b/chrome/browser/devtools/devtools_eye_dropper.cc
index ca08c13..bb38173b 100644
--- a/chrome/browser/devtools/devtools_eye_dropper.cc
+++ b/chrome/browser/devtools/devtools_eye_dropper.cc
@@ -126,7 +126,6 @@
       return true;
     }
 
-    SkAutoLockPixels lock_image(frame_);
     SkColor sk_color = frame_.getColor(last_cursor_x_, last_cursor_y_);
     callback_.Run(SkColorGetR(sk_color), SkColorGetG(sk_color),
                   SkColorGetB(sk_color), SkColorGetA(sk_color));
diff --git a/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc b/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc
index 917a7d8..b324f2171 100644
--- a/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc
+++ b/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc
@@ -140,12 +140,6 @@
 
   switch (type) {
     case net::X509Certificate::kPublicKeyTypeRSA:
-      DCHECK(public_key_length_in_bits);
-
-      // Convert bits to bytes.
-      out_info->max_signature_length_in_bytes =
-          (public_key_length_in_bits + 7) / 8;
-      out_info->type = net::SSLPrivateKey::Type::RSA;
       break;
     case net::X509Certificate::kPublicKeyTypeECDSA:
       WriteToConsole(content::CONSOLE_MESSAGE_LEVEL_ERROR,
diff --git a/chrome/browser/extensions/bookmark_app_helper.cc b/chrome/browser/extensions/bookmark_app_helper.cc
index 9b1526f..3c327d2 100644
--- a/chrome/browser/extensions/bookmark_app_helper.cc
+++ b/chrome/browser/extensions/bookmark_app_helper.cc
@@ -76,8 +76,8 @@
 #endif  // defined(OS_WIN)
 
 #if defined(USE_ASH)
-#include "ash/shelf/shelf_delegate.h"  // nogncheck
-#include "ash/shell.h"                        // nogncheck
+#include "ash/shelf/shelf_model.h"  // nogncheck
+#include "ash/shell.h"              // nogncheck
 #endif
 
 namespace {
@@ -732,9 +732,7 @@
   web_app::CreateShortcuts(web_app::SHORTCUT_CREATION_BY_USER,
                            creation_locations, current_profile, extension);
 #else
-  ash::ShelfDelegate* shelf_delegate = ash::Shell::Get()->shelf_delegate();
-  DCHECK(shelf_delegate);
-  shelf_delegate->PinAppWithID(extension->id());
+  ash::Shell::Get()->shelf_model()->PinAppWithID(extension->id());
 #endif  // !defined(USE_ASH)
 #endif  // !defined(OS_MACOSX)
 
diff --git a/chrome/browser/extensions/bookmark_app_helper_unittest.cc b/chrome/browser/extensions/bookmark_app_helper_unittest.cc
index 5327081..87c99ef 100644
--- a/chrome/browser/extensions/bookmark_app_helper_unittest.cc
+++ b/chrome/browser/extensions/bookmark_app_helper_unittest.cc
@@ -105,7 +105,6 @@
 
 void ValidateBitmapSizeAndColor(SkBitmap bitmap, int size, SkColor color) {
   // Obtain pixel lock to access pixels.
-  SkAutoLockPixels lock(bitmap);
   EXPECT_EQ(color, bitmap.getColor(0, 0));
   EXPECT_EQ(size, bitmap.width());
   EXPECT_EQ(size, bitmap.height());
diff --git a/chrome/browser/extensions/extension_action_storage_manager.cc b/chrome/browser/extensions/extension_action_storage_manager.cc
index a00a595..61c83f9 100644
--- a/chrome/browser/extensions/extension_action_storage_manager.cc
+++ b/chrome/browser/extensions/extension_action_storage_manager.cc
@@ -80,7 +80,6 @@
 
 // Conversion function for reading/writing to storage.
 std::string BitmapToString(const SkBitmap& bitmap) {
-  SkAutoLockPixels lock_image(bitmap);
   std::vector<unsigned char> data;
   bool success = gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &data);
   if (!success)
diff --git a/chrome/browser/geolocation/geolocation_permission_context_android.cc b/chrome/browser/geolocation/geolocation_permission_context_android.cc
index 64e49f6..b243822 100644
--- a/chrome/browser/geolocation/geolocation_permission_context_android.cc
+++ b/chrome/browser/geolocation/geolocation_permission_context_android.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/android/location_settings_impl.h"
 #include "chrome/browser/android/search_geolocation/search_geolocation_disclosure_tab_helper.h"
 #include "chrome/browser/android/search_geolocation/search_geolocation_service.h"
+#include "chrome/browser/android/tab_android.h"
 #include "chrome/browser/permissions/permission_request_id.h"
 #include "chrome/browser/permissions/permission_update_infobar_delegate_android.h"
 #include "chrome/browser/profiles/profile.h"
@@ -237,6 +238,23 @@
         content::WebContents::FromRenderFrameHost(
             content::RenderFrameHost::FromID(id.render_process_id(),
                                              id.render_frame_id()));
+
+    // Only show the location settings dialog if the tab for |web_contents| is
+    // user-interactable (i.e. is the current tab, and Chrome is active and not
+    // in tab-switching mode).
+    TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
+    if (tab && !tab->IsUserInteractable()) {
+      FinishNotifyPermissionSet(id, requesting_origin, embedding_origin,
+                                callback, false /* persist */,
+                                CONTENT_SETTING_BLOCK);
+      // This case should be very rare, so just pretend it was a denied prompt
+      // for metrics purposes.
+      LogLocationSettingsMetric(
+          kLocationSettingsDenyMetricBase, is_default_search,
+          LocationSettingsBackOffLevel(is_default_search));
+      return;
+    }
+
     location_settings_->PromptToEnableSystemLocationSetting(
         is_default_search ? SEARCH : DEFAULT, web_contents,
         base::BindOnce(
diff --git a/chrome/browser/media/webrtc/desktop_media_list_base.cc b/chrome/browser/media/webrtc/desktop_media_list_base.cc
index 33f560ff..2f700d3 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_base.cc
+++ b/chrome/browser/media/webrtc/desktop_media_list_base.cc
@@ -137,10 +137,7 @@
 // static
 uint32_t DesktopMediaListBase::GetImageHash(const gfx::Image& image) {
   SkBitmap bitmap = image.AsBitmap();
-  bitmap.lockPixels();
   uint32_t value =
       base::Hash(reinterpret_cast<char*>(bitmap.getPixels()), bitmap.getSize());
-  bitmap.unlockPixels();
-
   return value;
 }
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list.cc b/chrome/browser/media/webrtc/native_desktop_media_list.cc
index d6039e1..70c4eb5 100644
--- a/chrome/browser/media/webrtc/native_desktop_media_list.cc
+++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc
@@ -54,7 +54,6 @@
 
   SkBitmap result;
   result.allocN32Pixels(scaled_rect.width(), scaled_rect.height(), true);
-  result.lockPixels();
 
   uint8_t* pixels_data = reinterpret_cast<uint8_t*>(result.getPixels());
   libyuv::ARGBScale(frame->data(), frame->stride(),
@@ -75,8 +74,6 @@
     }
   }
 
-  result.unlockPixels();
-
   return gfx::ImageSkia::CreateFrom1xBitmap(result);
 }
 
diff --git a/chrome/browser/media/webrtc/tab_desktop_media_list_unittest.cc b/chrome/browser/media/webrtc/tab_desktop_media_list_unittest.cc
index 3ad2de00..183441a 100644
--- a/chrome/browser/media/webrtc/tab_desktop_media_list_unittest.cc
+++ b/chrome/browser/media/webrtc/tab_desktop_media_list_unittest.cc
@@ -62,7 +62,6 @@
   SkBitmap result;
   result.allocN32Pixels(size.width(), size.height(), true);
 
-  result.lockPixels();
   uint8_t* pixels_data = reinterpret_cast<uint8_t*>(result.getPixels());
 
   // Set greyscale value for all pixels.
@@ -79,8 +78,6 @@
     }
   }
 
-  result.unlockPixels();
-
   return gfx::Image::CreateFrom1xBitmap(result);
 }
 
diff --git a/chrome/browser/media/webrtc/window_icon_util_mac.mm b/chrome/browser/media/webrtc/window_icon_util_mac.mm
index 4235b58..690c875 100644
--- a/chrome/browser/media/webrtc/window_icon_util_mac.mm
+++ b/chrome/browser/media/webrtc/window_icon_util_mac.mm
@@ -53,7 +53,6 @@
 
   SkBitmap result;
   result.allocN32Pixels(width, height, false);
-  result.lockPixels();
 
   uint8_t* pixels_data = reinterpret_cast<uint8_t*>(result.getPixels());
 
diff --git a/chrome/browser/media/webrtc/window_icon_util_x11.cc b/chrome/browser/media/webrtc/window_icon_util_x11.cc
index c316c948..a69c365 100644
--- a/chrome/browser/media/webrtc/window_icon_util_x11.cc
+++ b/chrome/browser/media/webrtc/window_icon_util_x11.cc
@@ -59,7 +59,6 @@
   SkBitmap result;
   SkImageInfo info = SkImageInfo::MakeN32(width, height, kUnpremul_SkAlphaType);
   result.allocPixels(info);
-  result.lockPixels();
 
   uint32_t* pixels_data = reinterpret_cast<uint32_t*>(result.getPixels());
 
diff --git a/chrome/browser/plugins/plugin_power_saver_browsertest.cc b/chrome/browser/plugins/plugin_power_saver_browsertest.cc
index 5f98efc..61e5130 100644
--- a/chrome/browser/plugins/plugin_power_saver_browsertest.cc
+++ b/chrome/browser/plugins/plugin_power_saver_browsertest.cc
@@ -184,7 +184,6 @@
     return false;
 
   int32_t* ref_pixels = reinterpret_cast<int32_t*>(decoded.data());
-  SkAutoLockPixels lock_image(bitmap);
   int32_t* pixels = static_cast<int32_t*>(bitmap.getPixels());
 
   bool success = true;
diff --git a/chrome/browser/resources/net_internals/quic_view.html b/chrome/browser/resources/net_internals/quic_view.html
index 6701c12..f116c2b 100644
--- a/chrome/browser/resources/net_internals/quic_view.html
+++ b/chrome/browser/resources/net_internals/quic_view.html
@@ -1,22 +1,103 @@
 <div id=quic-view-tab-content class=content-box>
-  <ul style='margin-top:0'>
-    <li>QUIC Enabled: <span jscontent="!!quic_enabled"></span></li>
-    <li>Origins To Force QUIC On: <span jscontent="origins_to_force_quic_on"></span></li>
-    <li>Connection options: <span jscontent="connection_options"></span></li>
-    <li>Load Server Info Timeout Multiplier: <span jscontent="$this.load_server_info_timeout_srtt_multiplier"></span></li>
-    <li>Enable Connection Racing: <span jscontent="!!enable_connection_racing"></span></li>
-    <li>Disable Disk Cache: <span jscontent="!!disable_disk_cache"></span></li>
-    <li>Prefer AES: <span jscontent="!!prefer_aes"></span></li>
-    <li>Maximum Number Of Lossy Connections: <span jscontent="$this.max_number_of_lossy_connections"></span></li>
-    <li>Packet Loss Threshold: <span jscontent="$this.packet_loss_threshold"></span></li>
-    <li>Delay TCP Race: <span jscontent="!!delay_tcp_race"></span></li>
-    <li>Store Server Configs In Properties File: <span jscontent="!!store_server_configs_in_properties"></span></li>
-    <li>Idle Connection Timeout In Seconds: <span jscontent="$this.idle_connection_timeout_seconds"></span></li>
-    <li>Disable PreConnect If 0RTT: <span jscontent="$this.disable_preconnect_if_0rtt"></span></li>
-    <li>Disable QUIC On Timeout With Open Streams: <span jscontent="$this.disable_quic_on_timeout_with_open_streams"></span></li>
-    <li>Race Cert Verification: <span jscontent="!!race_cert_verification"></span></li>
-    <li jsdisplay="!!$this.is_quic_disabled">QUIC dynamically disabled: <span jscontent="!!$this.is_quic_disabled"></span></li>
-  </ul>
+  <!-- Only one of these two are shown -->
+  <div jsdisplay="!quic_enabled"><h4>QUIC is disabled</h4></div>
+  <div jsdisplay="!!quic_enabled">
+  <table class="styled-table">
+    <thead>
+      <tr>
+        <th>QUIC Option</th>
+        <th>Value</th>
+     </tr>
+    </thead>
+    <tbody>
+      <tr>
+         <td>Supported Versions</td>
+         <td><span jscontent="$this.supported_versions || ''"></span></td>
+     </tr><tr>
+         <td>Connection options</td>
+         <td><span jscontent="$this.connection_options || ''"></span></td>
+      </tr><tr>
+        <td>Max Packet Length</td>
+        <td><span jscontent="$this.max_packet_length || ''"></span></td>
+      </tr><tr>
+        <td>Idle Connection Timeout In Seconds</td>
+        <td>
+          <span jscontent="$this.idle_connection_timeout_seconds || ''">
+          </span>
+        </td>
+      </tr><tr>
+        <td>Reduced Ping Timeout In Seconds</td>
+        <td>
+          <span jscontent="$this.reduced_ping_timeout_seconds || ''">
+          </span>
+        </td>
+      </tr><tr>
+        <td>Packet Reader Yield After Duration in Milliseconds</td>
+        <td>
+          <span jscontent=
+            "$this.packet_reader_yield_after_duration_milliseconds || ''">
+          </span>
+       </td>
+      </tr><tr>
+        <td>Mark QUIC Broken When Network Blacholes</td>
+        <td>
+          <span jscontent="!!$this.mark_quic_broken_when_network_blackholes">
+          </span>
+        </td>
+      </tr><tr>
+        <td>Do Not Mark QUIC Broken on Network Changes</td>
+        <td>
+          <span jscontent="!!$this.do_not_mark_as_broken_on_network_change">
+          </span>
+        </td>
+      </tr><tr>
+        <td>Retry without Alt-Svc on QUIC Errors</td>
+        <td>
+          <span jscontent="!!$this.retry_without_alt_svc_on_quic_errors">
+          </span>
+        </td>
+      </tr><tr>
+        <td>Do Not Fragment</td>
+        <td><span jscontent="!!$this.do_not_fragment"></span></td>
+      </tr><tr>
+        <td>Allow Server Migrations</td>
+        <td><span jscontent="!!$this.allow_server_migration"></span></td>
+      </tr><tr>
+        <td>Migrate Sessions Early</td>
+        <td><span jscontent="!!$this.migrate_sessions_early"></span></td>
+     </tr><tr>
+        <td>Migrate Sessions on Network Change</td>
+        <td>
+          <span jscontent="!!$this.migrate_sessions_on_network_change">
+          </span>
+        </td>
+      </tr><tr>
+        <td>Close Sessions on IP Change</td>
+        <td><span jscontent="!!$this.close_sessions_on_ip_change"></span></td>
+      </tr><tr>
+        <td>Disable Bidirectional Streams</td>
+        <td><span jscontent="!!$this.disable_bidirectional_streams"></span></td>
+      </tr><tr>
+        <td>Race Cert Verification</td>
+        <td><span jscontent="!!$this.race_cert_verification"></span></td>
+      </tr><tr>
+        <td>Estimate Initial RTT</td>
+        <td><span jscontent="!!$this.estimate_initial_rtt"></span></td>
+      </tr><tr>
+        <td>Force Head of Line Blocking</td>
+        <td><span jscontent="!!$this.force_hol_blocking"></span></td>
+      </tr><tr>
+        <td>Max Server Configs Stored in Properties</td>
+        <td>
+          <span jscontent="$this.max_server_configs_stored_in_properties || ''">
+          </span>
+        </td>
+      </tr><tr>
+        <td>Origins To Force QUIC On</td>
+        <td><span jscontent="$this.origins_to_force_quic_on || ''"></span></td>
+      </tr>
+    </tbody>
+  </table>
 
   <h4>QUIC sessions</h4>
     <!-- Only one of these two are shown -->
@@ -30,7 +111,7 @@
               <th>Host</th>
               <th>Version</th>
               <th>Peer address</th>
-              <th>Connection UID</th>
+              <th>Connection ID</th>
               <th>Active stream count</th>
               <th>Active streams</th>
               <th>Total stream count</th>
@@ -59,3 +140,4 @@
       </p>
     </div>
 </div>
+</div>
diff --git a/chrome/browser/resources/settings/controls/settings_slider.js b/chrome/browser/resources/settings/controls/settings_slider.js
index c6b9b59..1d7e2a9 100644
--- a/chrome/browser/resources/settings/controls/settings_slider.js
+++ b/chrome/browser/resources/settings/controls/settings_slider.js
@@ -50,11 +50,15 @@
    * @private
    */
   onSliderChanged_: function() {
+    var sliderValue = isNaN(this.$.slider.immediateValue)
+                         ? this.$.slider.value
+                         : this.$.slider.immediateValue;
+
     var newValue;
     if (this.tickValues && this.tickValues.length > 0)
-      newValue = this.tickValues[this.$.slider.immediateValue];
+      newValue = this.tickValues[sliderValue];
     else
-      newValue = this.$.slider.immediateValue;
+      newValue = sliderValue;
 
     this.set('pref.value', newValue);
   },
diff --git a/chrome/browser/sync/test/integration/bookmarks_helper.cc b/chrome/browser/sync/test/integration/bookmarks_helper.cc
index 2bf99e1f..da2ab1c 100644
--- a/chrome/browser/sync/test/integration/bookmarks_helper.cc
+++ b/chrome/browser/sync/test/integration/bookmarks_helper.cc
@@ -190,8 +190,6 @@
                << bitmap_b.height() << ")";
     return false;
   }
-  SkAutoLockPixels bitmap_lock_a(bitmap_a);
-  SkAutoLockPixels bitmap_lock_b(bitmap_b);
   void* node_pixel_addr_a = bitmap_a.getPixels();
   EXPECT_TRUE(node_pixel_addr_a);
   void* node_pixel_addr_b = bitmap_b.getPixels();
diff --git a/chrome/browser/themes/browser_theme_pack_unittest.cc b/chrome/browser/themes/browser_theme_pack_unittest.cc
index a2dd82f..1833a1e3 100644
--- a/chrome/browser/themes/browser_theme_pack_unittest.cc
+++ b/chrome/browser/themes/browser_theme_pack_unittest.cc
@@ -287,25 +287,21 @@
     ASSERT_FALSE(rep1.is_null());
     EXPECT_EQ(80, rep1.sk_bitmap().width());
     EXPECT_EQ(80, rep1.sk_bitmap().height());
-    rep1.sk_bitmap().lockPixels();
     EXPECT_EQ(SkColorSetRGB(255, 255, 255), rep1.sk_bitmap().getColor(4, 4));
     EXPECT_EQ(SkColorSetRGB(255, 255, 255), rep1.sk_bitmap().getColor(8, 8));
     EXPECT_EQ(SkColorSetRGB(0, 241, 237), rep1.sk_bitmap().getColor(16, 16));
     EXPECT_EQ(SkColorSetRGB(255, 255, 255), rep1.sk_bitmap().getColor(24, 24));
     EXPECT_EQ(SkColorSetRGB(0, 241, 237), rep1.sk_bitmap().getColor(32, 32));
-    rep1.sk_bitmap().unlockPixels();
     // Scale 200%.
     const gfx::ImageSkiaRep& rep2 = image_skia->GetRepresentation(2.0f);
     ASSERT_FALSE(rep2.is_null());
     EXPECT_EQ(160, rep2.sk_bitmap().width());
     EXPECT_EQ(160, rep2.sk_bitmap().height());
-    rep2.sk_bitmap().lockPixels();
     EXPECT_EQ(SkColorSetRGB(255, 255, 255), rep2.sk_bitmap().getColor(4, 4));
     EXPECT_EQ(SkColorSetRGB(223, 42, 0), rep2.sk_bitmap().getColor(8, 8));
     EXPECT_EQ(SkColorSetRGB(223, 42, 0), rep2.sk_bitmap().getColor(16, 16));
     EXPECT_EQ(SkColorSetRGB(223, 42, 0), rep2.sk_bitmap().getColor(24, 24));
     EXPECT_EQ(SkColorSetRGB(255, 255, 255), rep2.sk_bitmap().getColor(32, 32));
-    rep2.sk_bitmap().unlockPixels();
 
     // TODO(sschmitz): I plan to remove the following (to the end of the fct)
     // Reason: this test may be brittle. It depends on details of how we scale
@@ -327,7 +323,6 @@
     ASSERT_FALSE(rep3.is_null());
     EXPECT_EQ(80, rep3.sk_bitmap().width());
     EXPECT_EQ(80, rep3.sk_bitmap().height());
-    rep3.sk_bitmap().lockPixels();
     // We take samples of colors and locations along the diagonal whenever
     // the color changes. Note these colors are slightly different from
     // the input PNG file due to input processing.
@@ -343,13 +338,11 @@
       }
     }
     EXPECT_EQ(static_cast<size_t>(9), normal.size());
-    rep3.sk_bitmap().unlockPixels();
     // Scale 200%.
     const gfx::ImageSkiaRep& rep4 = image_skia->GetRepresentation(2.0f);
     ASSERT_FALSE(rep4.is_null());
     EXPECT_EQ(160, rep4.sk_bitmap().width());
     EXPECT_EQ(160, rep4.sk_bitmap().height());
-    rep4.sk_bitmap().lockPixels();
     // We expect the same colors and at locations scaled by 2
     // since this bitmap was scaled by 2.
     for (size_t i = 0; i < normal.size(); ++i) {
@@ -357,7 +350,6 @@
       SkColor color = normal[i].second;
       EXPECT_EQ(color, rep4.sk_bitmap().getColor(xy, xy));
     }
-    rep4.sk_bitmap().unlockPixels();
   }
 
   base::MessageLoop message_loop;
diff --git a/chrome/browser/thumbnails/content_analysis.cc b/chrome/browser/thumbnails/content_analysis.cc
index c795b1f..70743e6 100644
--- a/chrome/browser/thumbnails/content_analysis.cc
+++ b/chrome/browser/thumbnails/content_analysis.cc
@@ -234,7 +234,6 @@
   // The purpose of this function is to highlight salient
   // (attention-attracting?) features of the image for use in image
   // retargeting.
-  SkAutoLockPixels source_lock(*input_bitmap);
   DCHECK(input_bitmap);
   DCHECK(input_bitmap->getPixels());
   DCHECK_EQ(kAlpha_8_SkColorType, input_bitmap->colorType());
@@ -383,7 +382,6 @@
                                     bool apply_log,
                                     std::vector<float>* rows,
                                     std::vector<float>* columns) {
-  SkAutoLockPixels source_lock(input_bitmap);
   DCHECK(rows);
   DCHECK(columns);
   DCHECK(input_bitmap.getPixels());
@@ -664,7 +662,6 @@
 SkBitmap ComputeDecimatedImage(const SkBitmap& bitmap,
                                const std::vector<bool>& rows,
                                const std::vector<bool>& columns) {
-  SkAutoLockPixels source_lock(bitmap);
   DCHECK(bitmap.getPixels());
   DCHECK_GT(bitmap.bytesPerPixel(), 0);
   DCHECK_EQ(bitmap.width(), static_cast<int>(columns.size()));
diff --git a/chrome/browser/thumbnails/content_analysis_unittest.cc b/chrome/browser/thumbnails/content_analysis_unittest.cc
index 547c51a4..387da01e 100644
--- a/chrome/browser/thumbnails/content_analysis_unittest.cc
+++ b/chrome/browser/thumbnails/content_analysis_unittest.cc
@@ -54,8 +54,6 @@
                            const gfx::Size& comparison_area,
                            const gfx::Point& origin_left,
                            const gfx::Point& origin_right) {
-  SkAutoLockPixels left_lock(bitmap_left);
-  SkAutoLockPixels right_lock(bitmap_right);
   for (int r = 0; r < comparison_area.height(); ++r) {
     for (int c = 0; c < comparison_area.width(); ++c) {
       SkColor color_left = bitmap_left.getColor(origin_left.x() + c,
diff --git a/chrome/browser/ui/ash/app_list/app_list_controller_ash.cc b/chrome/browser/ui/ash/app_list/app_list_controller_ash.cc
index b7de9b3..94d2e395 100644
--- a/chrome/browser/ui/ash/app_list/app_list_controller_ash.cc
+++ b/chrome/browser/ui/ash/app_list/app_list_controller_ash.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/ui/ash/app_list/app_list_controller_ash.h"
 
-#include "ash/shelf/shelf_delegate.h"
+#include "ash/shelf/shelf_model.h"
 #include "ash/shell.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
@@ -38,21 +38,21 @@
 }
 
 bool AppListControllerDelegateAsh::IsAppPinned(const std::string& app_id) {
-  return ash::Shell::Get()->shelf_delegate()->IsAppPinned(app_id);
+  return ash::Shell::Get()->shelf_model()->IsAppPinned(app_id);
 }
 
 bool AppListControllerDelegateAsh::IsAppOpen(const std::string& app_id) const {
   ash::ShelfID id =
-      ash::Shell::Get()->shelf_delegate()->GetShelfIDForAppID(app_id);
+      ash::Shell::Get()->shelf_model()->GetShelfIDForAppID(app_id);
   return id && ChromeLauncherController::instance()->IsOpen(id);
 }
 
 void AppListControllerDelegateAsh::PinApp(const std::string& app_id) {
-  ash::Shell::Get()->shelf_delegate()->PinAppWithID(app_id);
+  ash::Shell::Get()->shelf_model()->PinAppWithID(app_id);
 }
 
 void AppListControllerDelegateAsh::UnpinApp(const std::string& app_id) {
-  ash::Shell::Get()->shelf_delegate()->UnpinAppWithID(app_id);
+  ash::Shell::Get()->shelf_model()->UnpinAppWithID(app_id);
 }
 
 AppListControllerDelegate::Pinnable AppListControllerDelegateAsh::GetPinnable(
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc
index 3f07842..b92e096 100644
--- a/chrome/browser/ui/ash/chrome_shell_delegate.cc
+++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -389,13 +389,11 @@
 
 }  // namespace
 
-ChromeShellDelegate::ChromeShellDelegate()
-    : shelf_delegate_(NULL) {
+ChromeShellDelegate::ChromeShellDelegate() {
   PlatformInit();
 }
 
-ChromeShellDelegate::~ChromeShellDelegate() {
-}
+ChromeShellDelegate::~ChromeShellDelegate() {}
 
 service_manager::Connector* ChromeShellDelegate::GetShellConnector() const {
   return content::ServiceManagerConnection::GetForProcess()->GetConnector();
@@ -499,13 +497,16 @@
       displayer.browser()->window()->GetNativeWindow());
 }
 
-ash::ShelfDelegate* ChromeShellDelegate::CreateShelfDelegate(
-    ash::ShelfModel* model) {
-  if (!shelf_delegate_) {
-    shelf_delegate_ = new ChromeLauncherControllerImpl(nullptr, model);
-    shelf_delegate_->Init();
+void ChromeShellDelegate::ShelfInit() {
+  if (!launcher_controller_) {
+    launcher_controller_ = base::MakeUnique<ChromeLauncherControllerImpl>(
+        nullptr, ash::Shell::Get()->shelf_model());
+    launcher_controller_->Init();
   }
-  return shelf_delegate_;
+}
+
+void ChromeShellDelegate::ShelfShutdown() {
+  launcher_controller_.reset();
 }
 
 ui::MenuModel* ChromeShellDelegate::CreateContextMenu(
@@ -515,14 +516,15 @@
   if (chrome::IsRunningInAppMode())
     return nullptr;
 
-  // No context menu before |shelf_delegate_| is created. This is possible
-  // now because CreateShelfDelegate is called by session state change
-  // via mojo asynchronously. Context menu could be triggered when the
-  // mojo message is still in-fly and crashes.
-  if (!shelf_delegate_)
+  // No context menu before |launcher_controller_| is created. This is possible
+  // now because ShelfInit() is called by session state change via mojo
+  // asynchronously. Context menu could be triggered when the mojo message is
+  // still in-fly and crashes.
+  if (!launcher_controller_)
     return nullptr;
 
-  return LauncherContextMenu::Create(shelf_delegate_, item, wm_shelf);
+  return LauncherContextMenu::Create(launcher_controller_.get(), item,
+                                     wm_shelf);
 }
 
 ash::GPUSupport* ChromeShellDelegate::CreateGPUSupport() {
@@ -618,8 +620,8 @@
       // Do not use chrome::NOTIFICATION_PROFILE_ADDED because the
       // profile is not fully initialized by user_manager.  Use
       // chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED instead.
-      if (shelf_delegate_)
-        shelf_delegate_->OnUserProfileReadyToSwitch(profile);
+      if (launcher_controller_)
+        launcher_controller_->OnUserProfileReadyToSwitch(profile);
       break;
     }
     case chrome::NOTIFICATION_SESSION_STARTED:
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.h b/chrome/browser/ui/ash/chrome_shell_delegate.h
index 0bff55ab..564d24c 100644
--- a/chrome/browser/ui/ash/chrome_shell_delegate.h
+++ b/chrome/browser/ui/ash/chrome_shell_delegate.h
@@ -42,7 +42,8 @@
   void Exit() override;
   keyboard::KeyboardUI* CreateKeyboardUI() override;
   void OpenUrlFromArc(const GURL& url) override;
-  ash::ShelfDelegate* CreateShelfDelegate(ash::ShelfModel* model) override;
+  void ShelfInit() override;
+  void ShelfShutdown() override;
   ash::SystemTrayDelegate* CreateSystemTrayDelegate() override;
   std::unique_ptr<ash::WallpaperDelegate> CreateWallpaperDelegate() override;
   ash::SessionStateDelegate* CreateSessionStateDelegate() override;
@@ -70,7 +71,7 @@
 
   content::NotificationRegistrar registrar_;
 
-  ChromeLauncherControllerImpl* shelf_delegate_;
+  std::unique_ptr<ChromeLauncherControllerImpl> launcher_controller_;
 
   std::unique_ptr<chromeos::DisplayConfigurationObserver>
       display_configuration_observer_;
diff --git a/chrome/browser/ui/ash/launcher/arc_app_launcher_browsertest.cc b/chrome/browser/ui/ash/launcher/arc_app_launcher_browsertest.cc
index 2f452268..57c88c0d 100644
--- a/chrome/browser/ui/ash/launcher/arc_app_launcher_browsertest.cc
+++ b/chrome/browser/ui/ash/launcher/arc_app_launcher_browsertest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "ash/public/cpp/shelf_item_delegate.h"
-#include "ash/shelf/shelf_delegate.h"
 #include "ash/shelf/shelf_model.h"
 #include "ash/shell.h"
 #include "ash/wm/window_util.h"
@@ -108,10 +107,6 @@
   return ChromeLauncherController::instance();
 }
 
-ash::ShelfDelegate* shelf_delegate() {
-  return ash::Shell::Get()->shelf_delegate();
-}
-
 class AppAnimatedWaiter {
  public:
   explicit AppAnimatedWaiter(const std::string& app_id) : app_id_(app_id) {}
@@ -258,9 +253,9 @@
     app_instance_observer()->OnInstanceClosed();
   }
 
-  ash::ShelfItemDelegate* GetAppItemController(const std::string& id) {
-    const ash::ShelfID shelf_id = shelf_delegate()->GetShelfIDForAppID(id);
-    return ash::Shell::Get()->shelf_model()->GetShelfItemDelegate(shelf_id);
+  ash::ShelfItemDelegate* GetShelfItemDelegate(const std::string& id) {
+    ash::ShelfModel* model = ash::Shell::Get()->shelf_model();
+    return model->GetShelfItemDelegate(model->GetShelfIDForAppID(id));
   }
 
   ArcAppListPrefs* app_prefs() { return ArcAppListPrefs::Get(profile()); }
@@ -308,14 +303,15 @@
   SendPackageAdded(kTestAppPackage, false);
 
   const std::string app_id = GetTestApp1Id(kTestAppPackage);
+  ash::ShelfModel* shelf_model = ash::Shell::Get()->shelf_model();
   if (is_pinned()) {
-    shelf_delegate()->PinAppWithID(app_id);
-    const ash::ShelfID shelf_id = shelf_delegate()->GetShelfIDForAppID(app_id);
+    shelf_model->PinAppWithID(app_id);
+    const ash::ShelfID shelf_id = shelf_model->GetShelfIDForAppID(app_id);
     EXPECT_TRUE(shelf_id);
     const ash::ShelfItem* item = chrome_controller()->GetItem(shelf_id);
     EXPECT_EQ(base::UTF8ToUTF16(kTestAppName), item->title);
   } else {
-    EXPECT_FALSE(shelf_delegate()->GetShelfIDForAppID(app_id));
+    EXPECT_FALSE(shelf_model->GetShelfIDForAppID(app_id));
   }
 
   StopInstance();
@@ -330,13 +326,13 @@
   ASSERT_TRUE(app_info);
   EXPECT_FALSE(app_info->ready);
   if (is_pinned())
-    EXPECT_TRUE(shelf_delegate()->GetShelfIDForAppID(app_id));
+    EXPECT_TRUE(shelf_model->GetShelfIDForAppID(app_id));
   else
-    EXPECT_FALSE(shelf_delegate()->GetShelfIDForAppID(app_id));
+    EXPECT_FALSE(shelf_model->GetShelfIDForAppID(app_id));
 
   // Launching non-ready ARC app creates item on shelf and spinning animation.
   arc::LaunchApp(profile(), app_id, ui::EF_LEFT_MOUSE_BUTTON);
-  const ash::ShelfID shelf_id = shelf_delegate()->GetShelfIDForAppID(app_id);
+  const ash::ShelfID shelf_id = shelf_model->GetShelfIDForAppID(app_id);
   EXPECT_TRUE(shelf_id);
   const ash::ShelfItem* item = chrome_controller()->GetItem(shelf_id);
   EXPECT_EQ(base::UTF8ToUTF16(kTestAppName), item->title);
@@ -353,9 +349,9 @@
                       ->GetActiveTime(app_id)
                       .is_zero());
       if (is_pinned())
-        EXPECT_TRUE(shelf_delegate()->GetShelfIDForAppID(app_id));
+        EXPECT_TRUE(shelf_model->GetShelfIDForAppID(app_id));
       else
-        EXPECT_FALSE(shelf_delegate()->GetShelfIDForAppID(app_id));
+        EXPECT_FALSE(shelf_model->GetShelfIDForAppID(app_id));
       break;
     case TEST_ACTION_EXIT:
       // Just exist Chrome.
@@ -363,17 +359,17 @@
     case TEST_ACTION_CLOSE:
       // Close item during animation.
       {
-        ash::ShelfItemDelegate* controller = GetAppItemController(app_id);
-        ASSERT_TRUE(controller);
-        controller->Close();
+        ash::ShelfItemDelegate* delegate = GetShelfItemDelegate(app_id);
+        ASSERT_TRUE(delegate);
+        delegate->Close();
         EXPECT_TRUE(chrome_controller()
                         ->GetArcDeferredLauncher()
                         ->GetActiveTime(app_id)
                         .is_zero());
         if (is_pinned())
-          EXPECT_TRUE(shelf_delegate()->GetShelfIDForAppID(app_id));
+          EXPECT_TRUE(shelf_model->GetShelfIDForAppID(app_id));
         else
-          EXPECT_FALSE(shelf_delegate()->GetShelfIDForAppID(app_id));
+          EXPECT_FALSE(shelf_model->GetShelfIDForAppID(app_id));
       }
       break;
   }
@@ -396,30 +392,31 @@
 
   const std::string app_id1 = GetTestApp1Id(kTestAppPackage);
   const std::string app_id2 = GetTestApp2Id(kTestAppPackage);
-  shelf_delegate()->PinAppWithID(app_id1);
-  shelf_delegate()->PinAppWithID(app_id2);
+  ash::ShelfModel* shelf_model = ash::Shell::Get()->shelf_model();
+  shelf_model->PinAppWithID(app_id1);
+  shelf_model->PinAppWithID(app_id2);
   const ash::ShelfID shelf_id1_before =
-      shelf_delegate()->GetShelfIDForAppID(app_id1);
+      shelf_model->GetShelfIDForAppID(app_id1);
   EXPECT_TRUE(shelf_id1_before);
-  EXPECT_TRUE(shelf_delegate()->GetShelfIDForAppID(app_id2));
+  EXPECT_TRUE(shelf_model->GetShelfIDForAppID(app_id2));
 
   // Package contains only one app. App list is not shown for updated package.
   SendPackageUpdated(kTestAppPackage, false);
   // Second pin should gone.
-  EXPECT_EQ(shelf_id1_before, shelf_delegate()->GetShelfIDForAppID(app_id1));
-  EXPECT_FALSE(shelf_delegate()->GetShelfIDForAppID(app_id2));
+  EXPECT_EQ(shelf_id1_before, shelf_model->GetShelfIDForAppID(app_id1));
+  EXPECT_FALSE(shelf_model->GetShelfIDForAppID(app_id2));
 
   // Package contains two apps. App list is not shown for updated package.
   SendPackageUpdated(kTestAppPackage, true);
   // Second pin should not appear.
-  EXPECT_EQ(shelf_id1_before, shelf_delegate()->GetShelfIDForAppID(app_id1));
-  EXPECT_FALSE(shelf_delegate()->GetShelfIDForAppID(app_id2));
+  EXPECT_EQ(shelf_id1_before, shelf_model->GetShelfIDForAppID(app_id1));
+  EXPECT_FALSE(shelf_model->GetShelfIDForAppID(app_id2));
 
   // Package removed.
   SendPackageRemoved(kTestAppPackage);
   // No pin is expected.
-  EXPECT_FALSE(shelf_delegate()->GetShelfIDForAppID(app_id1));
-  EXPECT_FALSE(shelf_delegate()->GetShelfIDForAppID(app_id2));
+  EXPECT_FALSE(shelf_model->GetShelfIDForAppID(app_id1));
+  EXPECT_FALSE(shelf_model->GetShelfIDForAppID(app_id2));
 }
 
 // This test validates that app list is shown on new package and not shown
@@ -507,48 +504,48 @@
   app_host()->OnTaskCreated(1, info->package_name, info->activity, info->name,
                             CreateIntentUriWithShelfGroup(kTestShelfGroup));
 
-  ash::ShelfItemDelegate* controller1 = GetAppItemController(shelf_id1);
-  ASSERT_TRUE(controller1);
+  ash::ShelfItemDelegate* delegate1 = GetShelfItemDelegate(shelf_id1);
+  ASSERT_TRUE(delegate1);
 
   // 2 tasks for group 2
   app_host()->OnTaskCreated(2, info->package_name, info->activity, info->name,
                             CreateIntentUriWithShelfGroup(kTestShelfGroup2));
 
-  ash::ShelfItemDelegate* controller2 = GetAppItemController(shelf_id2);
-  ASSERT_TRUE(controller2);
-  ASSERT_NE(controller1, controller2);
+  ash::ShelfItemDelegate* delegate2 = GetShelfItemDelegate(shelf_id2);
+  ASSERT_TRUE(delegate2);
+  ASSERT_NE(delegate1, delegate2);
 
   app_host()->OnTaskCreated(3, info->package_name, info->activity, info->name,
                             CreateIntentUriWithShelfGroup(kTestShelfGroup2));
 
-  ASSERT_EQ(controller2, GetAppItemController(shelf_id2));
+  ASSERT_EQ(delegate2, GetShelfItemDelegate(shelf_id2));
 
   // 2 tasks for group 3 which does not have shortcut.
   app_host()->OnTaskCreated(4, info->package_name, info->activity, info->name,
                             CreateIntentUriWithShelfGroup(kTestShelfGroup3));
 
-  ash::ShelfItemDelegate* controller3 = GetAppItemController(shelf_id3);
-  ASSERT_TRUE(controller3);
-  ASSERT_NE(controller1, controller3);
-  ASSERT_NE(controller2, controller3);
+  ash::ShelfItemDelegate* delegate3 = GetShelfItemDelegate(shelf_id3);
+  ASSERT_TRUE(delegate3);
+  ASSERT_NE(delegate1, delegate3);
+  ASSERT_NE(delegate2, delegate3);
 
   app_host()->OnTaskCreated(5, info->package_name, info->activity, info->name,
                             CreateIntentUriWithShelfGroup(kTestShelfGroup3));
 
-  ASSERT_EQ(controller3, GetAppItemController(shelf_id3));
+  ASSERT_EQ(delegate3, GetShelfItemDelegate(shelf_id3));
 
   // Destroy task #0, this kills shelf group 1
   app_host()->OnTaskDestroyed(1);
-  EXPECT_FALSE(GetAppItemController(shelf_id1));
+  EXPECT_FALSE(GetShelfItemDelegate(shelf_id1));
 
   // Destroy task #1, shelf group 2 is still alive
   app_host()->OnTaskDestroyed(2);
-  EXPECT_EQ(controller2, GetAppItemController(shelf_id2));
+  EXPECT_EQ(delegate2, GetShelfItemDelegate(shelf_id2));
   // Destroy task #2, this kills shelf group 2
   app_host()->OnTaskDestroyed(3);
-  EXPECT_FALSE(GetAppItemController(shelf_id2));
+  EXPECT_FALSE(GetShelfItemDelegate(shelf_id2));
 
   // Disable ARC, this removes app and as result kills shelf group 3.
   arc::SetArcPlayStoreEnabledForProfile(profile(), false);
-  EXPECT_FALSE(GetAppItemController(shelf_id3));
+  EXPECT_FALSE(GetShelfItemDelegate(shelf_id3));
 }
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc
index 17509cfd..bed6d5e 100644
--- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc
@@ -7,7 +7,6 @@
 
 #include "ash/display/screen_orientation_controller_chromeos.h"
 #include "ash/shared/app_types.h"
-#include "ash/shelf/shelf_delegate.h"
 #include "ash/shelf/shelf_model.h"
 #include "ash/shell.h"
 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
@@ -249,9 +248,8 @@
 };
 
 ArcAppWindowLauncherController::ArcAppWindowLauncherController(
-    ChromeLauncherController* owner,
-    ash::ShelfDelegate* shelf_delegate)
-    : AppWindowLauncherController(owner), shelf_delegate_(shelf_delegate) {
+    ChromeLauncherController* owner)
+    : AppWindowLauncherController(owner) {
   if (arc::IsArcAllowedForProfile(owner->profile())) {
     observed_profile_ = owner->profile();
     StartObserving(observed_profile_);
@@ -655,12 +653,12 @@
       base::MakeUnique<ArcAppWindowLauncherItemController>(
           app_shelf_id.ToString());
   ArcAppWindowLauncherItemController* item_controller = controller.get();
+  ash::ShelfModel* shelf_model = ash::Shell::Get()->shelf_model();
   const ash::ShelfID shelf_id =
-      shelf_delegate_->GetShelfIDForAppID(app_shelf_id.ToString());
-  if (!shelf_id) {
+      shelf_model->GetShelfIDForAppID(app_shelf_id.ToString());
+  if (shelf_id == ash::kInvalidShelfID) {
     owner()->CreateAppLauncherItem(std::move(controller), ash::STATUS_RUNNING);
   } else {
-    ash::ShelfModel* shelf_model = ash::Shell::Get()->shelf_model();
     shelf_model->SetShelfItemDelegate(shelf_id, std::move(controller));
     owner()->SetItemStatus(shelf_id, ash::STATUS_RUNNING);
   }
@@ -677,8 +675,9 @@
   DCHECK(controller);
 
   const ash::ShelfID shelf_id =
-      shelf_delegate_->GetShelfIDForAppID(controller->app_id());
-  DCHECK(shelf_id);
+      ash::Shell::Get()->shelf_model()->GetShelfIDForAppID(
+          controller->app_id());
+  DCHECK_NE(shelf_id, ash::kInvalidShelfID);
 
   controller->AddWindow(app_window);
   owner()->SetItemStatus(shelf_id, ash::STATUS_RUNNING);
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h
index b37fd95..77101b8 100644
--- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h
+++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h
@@ -18,10 +18,6 @@
 #include "ui/aura/env_observer.h"
 #include "ui/aura/window_observer.h"
 
-namespace ash {
-class ShelfDelegate;
-}
-
 namespace aura {
 class Window;
 }
@@ -37,8 +33,7 @@
                                        public ash::ShellObserver,
                                        public ArcAppListPrefs::Observer {
  public:
-  ArcAppWindowLauncherController(ChromeLauncherController* owner,
-                                 ash::ShelfDelegate* shelf_delegate);
+  explicit ArcAppWindowLauncherController(ChromeLauncherController* owner);
   ~ArcAppWindowLauncherController() override;
 
   // Returns shelf app id. Play Store app is mapped to ARC platform host app.
@@ -118,8 +113,6 @@
   AppWindowLauncherItemController* ControllerForWindow(
       aura::Window* window) override;
 
-  // Not owned
-  ash::ShelfDelegate* shelf_delegate_;
   int active_task_id_ = -1;
   TaskIdToAppWindowInfo task_id_to_app_window_info_;
   ShelfGroupToAppControllerMap app_shelf_group_to_controller_map_;
diff --git a/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc b/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc
index 0ef6011..2f47003 100644
--- a/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc
+++ b/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc
@@ -8,7 +8,6 @@
 #include <vector>
 
 #include "ash/resources/grit/ash_resources.h"
-#include "ash/shelf/shelf_delegate.h"
 #include "ash/shelf/shelf_model.h"
 #include "ash/shell.h"
 #include "ash/wm/window_properties.h"
@@ -361,9 +360,9 @@
     return false;
 
   // v1 App popup windows with a valid app id have their own icon.
-  ash::ShelfDelegate* delegate = ash::Shell::Get()->shelf_delegate();
-  if (browser->is_app() && browser->is_type_popup() && delegate &&
-      delegate->GetShelfIDForAppID(web_app::GetExtensionIdFromApplicationName(
+  ash::ShelfModel* model = ash::Shell::Get()->shelf_model();
+  if (browser->is_app() && browser->is_type_popup() &&
+      model->GetShelfIDForAppID(web_app::GetExtensionIdFromApplicationName(
           browser->app_name())) > 0) {
     return false;
   }
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.cc
index a2483e54..f4c7e83d 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.cc
@@ -253,11 +253,8 @@
         new ExtensionAppWindowLauncherController(this));
   }
   app_window_controllers_.push_back(std::move(extension_app_window_controller));
-
-  std::unique_ptr<AppWindowLauncherController> arc_app_window_controller;
-  arc_app_window_controller.reset(
-      new ArcAppWindowLauncherController(this, this));
-  app_window_controllers_.push_back(std::move(arc_app_window_controller));
+  app_window_controllers_.push_back(
+      base::MakeUnique<ArcAppWindowLauncherController>(this));
 
   // Right now ash::Shell isn't created for tests.
   // TODO(mukai): Allows it to observe display change and write tests.
@@ -747,87 +744,32 @@
   PrefServiceSyncableFromProfile(profile())->AddObserver(this);
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// ash::ShelfDelegate:
-
 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForAppID(
     const std::string& app_id) {
-  // Get shelf id for |app_id| and an empty |launch_id|.
-  return GetShelfIDForAppIDAndLaunchID(app_id, std::string());
+  return model_->GetShelfIDForAppID(app_id);
 }
 
 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForAppIDAndLaunchID(
     const std::string& app_id,
     const std::string& launch_id) {
-  // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
-  const std::string shelf_app_id =
-      ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(app_id);
-  if (shelf_app_id.empty())
-    return ash::kInvalidShelfID;
-
-  for (const ash::ShelfItem& item : model_->items()) {
-    // Ash's ShelfWindowWatcher handles app panel windows separately.
-    if (item.type != ash::TYPE_APP_PANEL &&
-        item.app_launch_id.app_id() == shelf_app_id &&
-        item.app_launch_id.launch_id() == launch_id) {
-      return item.id;
-    }
-  }
-  return ash::kInvalidShelfID;
+  return model_->GetShelfIDForAppIDAndLaunchID(app_id, launch_id);
 }
 
 const std::string& ChromeLauncherControllerImpl::GetAppIDForShelfID(
     ash::ShelfID id) {
-  ash::ShelfItems::const_iterator item = model_->ItemByID(id);
-  return item != model_->items().end() ? item->app_launch_id.app_id()
-                                       : base::EmptyString();
+  return model_->GetAppIDForShelfID(id);
 }
 
 void ChromeLauncherControllerImpl::PinAppWithID(const std::string& app_id) {
-  // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
-  const std::string shelf_app_id =
-      ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(app_id);
-
-  // Requests to pin should only be be made for apps with editable pin states.
-  DCHECK_EQ(GetPinnableForAppID(shelf_app_id, profile()),
-            AppListControllerDelegate::PIN_EDITABLE);
-
-  // If the app is already pinned, do nothing and return.
-  if (IsAppPinned(shelf_app_id))
-    return;
-
-  // Convert an existing item to be pinned, or create a new pinned item.
-  ash::ShelfID shelf_id = GetShelfIDForAppID(shelf_app_id);
-  if (shelf_id != ash::kInvalidShelfID) {
-    DCHECK_EQ(GetItem(shelf_id)->type, ash::TYPE_APP);
-    DCHECK(!GetItem(shelf_id)->pinned_by_policy);
-    SetItemType(shelf_id, ash::TYPE_PINNED_APP);
-  } else {
-    shelf_id = CreateAppShortcutLauncherItem(ash::AppLaunchId(shelf_app_id),
-                                             model_->item_count());
-  }
+  model_->PinAppWithID(app_id);
 }
 
 bool ChromeLauncherControllerImpl::IsAppPinned(const std::string& app_id) {
-  // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
-  const std::string shelf_app_id =
-      ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(app_id);
-
-  return IsPinned(GetShelfIDForAppID(shelf_app_id));
+  return model_->IsAppPinned(app_id);
 }
 
 void ChromeLauncherControllerImpl::UnpinAppWithID(const std::string& app_id) {
-  // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
-  const std::string shelf_app_id =
-      ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(app_id);
-
-  // Requests to unpin should only be be made for apps with editable pin states.
-  DCHECK_EQ(GetPinnableForAppID(shelf_app_id, profile()),
-            AppListControllerDelegate::PIN_EDITABLE);
-
-  // If the app is pinned, unpin the shelf item (and remove it if not running).
-  if (IsAppPinned(shelf_app_id))
-    UnpinShelfItemInternal(GetShelfIDForAppID(shelf_app_id));
+  model_->UnpinAppWithID(app_id);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -938,14 +880,8 @@
 }
 
 void ChromeLauncherControllerImpl::RemoveShelfItem(ash::ShelfID id) {
-  const std::string& app_id = GetAppIDForShelfID(id);
-  AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
-  if (app_icon_loader)
-    app_icon_loader->ClearImage(app_id);
   const int index = model_->ItemIndexByID(id);
-  // A "browser proxy" is not known to the model and this removal does
-  // therefore not need to be propagated to the model.
-  if (index != -1)
+  if (index >= 0 && index < model_->item_count())
     model_->RemoveItemAt(index);
 }
 
@@ -1163,29 +1099,13 @@
   CHECK(item_delegate);
   // Ash's ShelfWindowWatcher handles app panel windows separately.
   DCHECK_NE(ash::TYPE_APP_PANEL, shelf_item_type);
-
   ash::ShelfItem item;
+  item.status = status;
   item.type = shelf_item_type;
   item.app_launch_id = item_delegate->app_launch_id();
-  item.image = extensions::util::GetDefaultAppIcon();
-
-  const std::string& app_id = item_delegate->app_id();
-  item.title = LauncherControllerHelper::GetAppTitle(profile(), app_id);
-
-  ash::ShelfItemStatus new_state = GetAppState(app_id);
-  if (new_state != ash::STATUS_CLOSED)
-    status = new_state;
-
-  item.status = status;
-  model_->AddAt(index, item);
-
-  AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
-  if (app_icon_loader) {
-    app_icon_loader->FetchImage(app_id);
-    app_icon_loader->UpdateImage(app_id);
-  }
-
+  // Set the delegate first to avoid constructing one in ShelfItemAdded.
   model_->SetShelfItemDelegate(id, std::move(item_delegate));
+  model_->AddAt(index, item);
   return id;
 }
 
@@ -1202,11 +1122,12 @@
   browser_shortcut.title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
   browser_shortcut.app_launch_id = ash::AppLaunchId(kChromeAppId);
   ash::ShelfID id = model_->next_id();
-  model_->AddAt(0, browser_shortcut);
   std::unique_ptr<BrowserShortcutLauncherItemController> item_delegate =
       base::MakeUnique<BrowserShortcutLauncherItemController>(model_);
   BrowserShortcutLauncherItemController* item_controller = item_delegate.get();
+  // Set the delegate first to avoid constructing another one in ShelfItemAdded.
   model_->SetShelfItemDelegate(id, std::move(item_delegate));
+  model_->AddAt(0, browser_shortcut);
   item_controller->UpdateBrowserItemState();
 }
 
@@ -1276,24 +1197,69 @@
 
 void ChromeLauncherControllerImpl::ShelfItemAdded(int index) {
   // Update the pin position preference as needed.
-  const ash::ShelfItem& item = model_->items()[index];
+  ash::ShelfItem item = model_->items()[index];
   if (ItemTypeIsPinned(item) && should_sync_pin_changes())
     SyncPinPosition(item.id);
+
+  // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
+  const std::string shelf_app_id =
+      ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(
+          item.app_launch_id.app_id());
+
+  // Fetch and update the icon for the app's item.
+  AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(shelf_app_id);
+  if (app_icon_loader) {
+    app_icon_loader->FetchImage(shelf_app_id);
+    app_icon_loader->UpdateImage(shelf_app_id);
+  }
+
+  // Update the item with any missing Chrome-specific info.
+  if (item.type == ash::TYPE_APP || item.type == ash::TYPE_PINNED_APP) {
+    bool needs_update = false;
+    if (item.image.isNull()) {
+      needs_update = true;
+      item.image = extensions::util::GetDefaultAppIcon();
+    }
+    if (item.title.empty()) {
+      needs_update = true;
+      item.title =
+          LauncherControllerHelper::GetAppTitle(profile(), shelf_app_id);
+    }
+    ash::ShelfItemStatus status = GetAppState(shelf_app_id);
+    if (status != item.status && status != ash::STATUS_CLOSED) {
+      needs_update = true;
+      item.status = status;
+    }
+    if (needs_update)
+      model_->Set(index, item);
+  }
+
+  // Construct a ShelfItemDelegate for the item if one does not yet exist.
+  if (!model_->GetShelfItemDelegate(item.id)) {
+    model_->SetShelfItemDelegate(
+        item.id, AppShortcutLauncherItemController::Create(ash::AppLaunchId(
+                     shelf_app_id, item.app_launch_id.launch_id())));
+  }
 }
 
 void ChromeLauncherControllerImpl::ShelfItemRemoved(
     int index,
     const ash::ShelfItem& old_item) {
+  // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
+  const std::string shelf_app_id =
+      ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(
+          old_item.app_launch_id.app_id());
+
   // Remove the pin position from preferences as needed.
   if (ItemTypeIsPinned(old_item) && should_sync_pin_changes()) {
-    // TODO(khmel): Fix this Arc application id mapping. See http://b/31703859
-    const std::string shelf_app_id =
-        ArcAppWindowLauncherController::GetShelfAppIdFromArcAppId(
-            old_item.app_launch_id.app_id());
     ash::AppLaunchId app_launch_id(shelf_app_id,
                                    old_item.app_launch_id.launch_id());
     ash::launcher::RemovePinPosition(profile(), app_launch_id);
   }
+
+  AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(shelf_app_id);
+  if (app_icon_loader)
+    app_icon_loader->ClearImage(shelf_app_id);
 }
 
 void ChromeLauncherControllerImpl::ShelfItemMoved(int start_index,
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h
index e9a67927..aa870347 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h
@@ -10,7 +10,6 @@
 
 #include "ash/display/window_tree_host_manager.h"
 #include "ash/public/cpp/shelf_types.h"
-#include "ash/shelf/shelf_delegate.h"
 #include "ash/shelf/shelf_model_observer.h"
 #include "base/compiler_specific.h"
 #include "base/macros.h"
@@ -37,19 +36,12 @@
 }
 }
 
-namespace content {
-class BrowserContext;
-}
-
 class ChromeLauncherControllerUserSwitchObserver;
 
 // Implementation of ChromeLauncherController, used for classic Ash.
-// In addition to implementing ChromeLauncherController, this class performs
-// a lot of other responsibilities, such as implementing ash::ShelfDelegate,
-// updating the UI state and the shelf model when apps are uninstalled, etc.
+// This class manipulates Ash's ShelfModel to support Chrome and its apps.
 class ChromeLauncherControllerImpl
     : public ChromeLauncherController,
-      public ash::ShelfDelegate,
       public LauncherAppUpdater::Delegate,
       private ash::ShelfModelObserver,
       private ash::WindowTreeHostManager::Observer,
@@ -123,15 +115,14 @@
     return app_window_controllers_;
   }
 
-  // ash::ShelfDelegate:
-  ash::ShelfID GetShelfIDForAppID(const std::string& app_id) override;
-  ash::ShelfID GetShelfIDForAppIDAndLaunchID(
-      const std::string& app_id,
-      const std::string& launch_id) override;
-  const std::string& GetAppIDForShelfID(ash::ShelfID id) override;
-  void PinAppWithID(const std::string& app_id) override;
-  bool IsAppPinned(const std::string& app_id) override;
-  void UnpinAppWithID(const std::string& app_id) override;
+  // Helpers that call through to corresponding ShelfModel functions.
+  ash::ShelfID GetShelfIDForAppID(const std::string& app_id);
+  ash::ShelfID GetShelfIDForAppIDAndLaunchID(const std::string& app_id,
+                                             const std::string& launch_id);
+  const std::string& GetAppIDForShelfID(ash::ShelfID id);
+  void PinAppWithID(const std::string& app_id);
+  bool IsAppPinned(const std::string& app_id);
+  void UnpinAppWithID(const std::string& app_id);
 
   // LauncherAppUpdater::Delegate:
   void OnAppInstalled(content::BrowserContext* browser_context,
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc
index 1c3b07e0..9fc4dae 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc
@@ -273,6 +273,59 @@
   DISALLOW_COPY_AND_ASSIGN(TestV2AppLauncherItemController);
 };
 
+// A test ShelfController implementation that tracks alignment and auto-hide.
+class TestShelfController : public ash::mojom::ShelfController {
+ public:
+  TestShelfController() : binding_(this) {}
+  ~TestShelfController() override {}
+
+  ash::ShelfAlignment alignment() const { return alignment_; }
+  ash::ShelfAutoHideBehavior auto_hide() const { return auto_hide_; }
+
+  size_t alignment_change_count() const { return alignment_change_count_; }
+  size_t auto_hide_change_count() const { return auto_hide_change_count_; }
+
+  ash::mojom::ShelfControllerPtr CreateInterfacePtrAndBind() {
+    return binding_.CreateInterfacePtrAndBind();
+  }
+
+  // ash::mojom::ShelfController:
+  void AddObserver(
+      ash::mojom::ShelfObserverAssociatedPtrInfo observer) override {
+    observer_.Bind(std::move(observer));
+  }
+  void SetAlignment(ash::ShelfAlignment alignment,
+                    int64_t display_id) override {
+    alignment_change_count_++;
+    alignment_ = alignment;
+    observer_->OnAlignmentChanged(alignment_, display_id);
+  }
+  void SetAutoHideBehavior(ash::ShelfAutoHideBehavior auto_hide,
+                           int64_t display_id) override {
+    auto_hide_change_count_++;
+    auto_hide_ = auto_hide;
+    observer_->OnAutoHideBehaviorChanged(auto_hide_, display_id);
+  }
+  void PinItem(
+      const ash::ShelfItem& item,
+      ash::mojom::ShelfItemDelegateAssociatedPtrInfo delegate) override {}
+  void UnpinItem(const std::string& app_id) override {}
+  void SetItemImage(const std::string& app_id, const SkBitmap& image) override {
+  }
+
+ private:
+  ash::ShelfAlignment alignment_ = ash::SHELF_ALIGNMENT_BOTTOM_LOCKED;
+  ash::ShelfAutoHideBehavior auto_hide_ = ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN;
+
+  size_t alignment_change_count_ = 0;
+  size_t auto_hide_change_count_ = 0;
+
+  ash::mojom::ShelfObserverAssociatedPtr observer_;
+  mojo::Binding<ash::mojom::ShelfController> binding_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestShelfController);
+};
+
 // A callback that does nothing after shelf item selection handling.
 void NoopCallback(ash::ShelfAction action, base::Optional<ash::MenuItemList>) {}
 
@@ -287,6 +340,65 @@
 
 }  // namespace
 
+// A test ChromeLauncherControllerImpl subclass that uses TestShelfController.
+class TestChromeLauncherControllerImpl : public ChromeLauncherControllerImpl {
+ public:
+  TestChromeLauncherControllerImpl(Profile* profile, ash::ShelfModel* model)
+      : ChromeLauncherControllerImpl(profile, model) {}
+
+  // ChromeLauncherControllerImpl:
+  using ChromeLauncherControllerImpl::ReleaseProfile;
+  bool ConnectToShelfController() override {
+    // Set the shelf controller pointer to a test instance; this is run in init.
+    if (!shelf_controller_.is_bound())
+      shelf_controller_ = test_shelf_controller_.CreateInterfacePtrAndBind();
+    return true;
+  }
+
+  TestShelfController* test_shelf_controller() {
+    return &test_shelf_controller_;
+  }
+
+ private:
+  TestShelfController test_shelf_controller_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestChromeLauncherControllerImpl);
+};
+
+// A shell delegate that owns a ChromeLauncherController, like production.
+// TODO(msw): Refine ChromeLauncherControllerImpl lifetime management.
+// TODO(msw): Avoid relying on TestShellDelegate's ShelfInitializer.
+class ChromeLauncherTestShellDelegate : public ash::test::TestShellDelegate {
+ public:
+  ChromeLauncherTestShellDelegate() {}
+
+  // Create a ChromeLauncherControllerImpl instance.
+  ChromeLauncherControllerImpl* CreateLauncherController(Profile* profile) {
+    launcher_controller_ = base::MakeUnique<ChromeLauncherControllerImpl>(
+        profile, ash::Shell::Get()->shelf_model());
+    return launcher_controller_.get();
+  }
+
+  // Create a TestChromeLauncherControllerImpl instance.
+  TestChromeLauncherControllerImpl* CreateTestLauncherController(
+      Profile* profile) {
+    auto controller = base::MakeUnique<TestChromeLauncherControllerImpl>(
+        profile, ash::Shell::Get()->shelf_model());
+    TestChromeLauncherControllerImpl* controller_weak = controller.get();
+    launcher_controller_ = std::move(controller);
+    launcher_controller_->Init();
+    return controller_weak;
+  }
+
+  // ash::test::TestShellDelegate:
+  void ShelfShutdown() override { launcher_controller_.reset(); }
+
+ private:
+  std::unique_ptr<ChromeLauncherControllerImpl> launcher_controller_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeLauncherTestShellDelegate);
+};
+
 class ChromeLauncherControllerImplTest : public BrowserWithTestWindowTest {
  protected:
   ChromeLauncherControllerImplTest()
@@ -300,6 +412,9 @@
 
     app_list::AppListSyncableServiceFactory::SetUseInTesting();
 
+    shell_delegate_ = new ChromeLauncherTestShellDelegate();
+    ash_test_helper()->set_test_shell_delegate(shell_delegate_);
+
     BrowserWithTestWindowTest::SetUp();
 
     if (!profile_manager_) {
@@ -485,21 +600,14 @@
     model_->Add(app_list);
   }
 
-  // Create a launcher controller instance and register it as the ShelfDelegate.
-  // Returns a pointer to the uninitialized controller, which is owned by Shell.
+  // Create a launcher controller instance, owned by the test shell delegate.
+  // Returns a pointer to the uninitialized controller.
   ChromeLauncherControllerImpl* CreateLauncherController() {
-    // Shell owns ChromeLauncherController as its ShelfDelegate. The lifetime
-    // of this instance should match production behavior as closely as possible.
-    DCHECK(!ChromeLauncherController::instance());
-    std::unique_ptr<ChromeLauncherControllerImpl> launcher_controller =
-        base::MakeUnique<ChromeLauncherControllerImpl>(profile(), model_);
-    launcher_controller_ = launcher_controller.get();
-    ash::test::ShellTestApi().SetShelfDelegate(std::move(launcher_controller));
+    launcher_controller_ = shell_delegate_->CreateLauncherController(profile());
     return launcher_controller_;
   }
 
-  // Create and initialize the controller.
-  // Returns a pointer to the initialized controller, which is owned by Shell.
+  // Create and initialize the controller, owned by the test shell delegate.
   void InitLauncherController() { CreateLauncherController()->Init(); }
 
   // Create and initialize the controller; create a tab and show the browser.
@@ -509,14 +617,14 @@
     browser()->window()->Show();
   }
 
-  // Destroy Shell's controller instance and clear the local pointer.
+  // Destroy the launcher controller instance and clear the local pointer.
   void ResetLauncherController() {
     launcher_controller_ = nullptr;
-    ash::test::ShellTestApi().SetShelfDelegate(nullptr);
+    shell_delegate_->ShelfShutdown();
   }
 
   // Destroy and recreate the controller; clear and reinitialize the ShelfModel.
-  // Returns a pointer to the uninitialized controller, which is owned by Shell.
+  // Returns a pointer to the uninitialized controller, owned by shell delegate.
   // TODO(msw): This does not accurately represent ChromeLauncherControllerImpl
   // lifetime or usage in production, and does not accurately simulate restarts.
   ChromeLauncherControllerImpl* RecreateLauncherController() {
@@ -939,6 +1047,7 @@
   ArcAppTest arc_test_;
   bool auto_start_arc_test_ = false;
   ChromeLauncherControllerImpl* launcher_controller_ = nullptr;
+  ChromeLauncherTestShellDelegate* shell_delegate_ = nullptr;
   std::unique_ptr<TestShelfModelObserver> model_observer_;
   ash::ShelfModel* model_ = nullptr;
   std::unique_ptr<TestingProfileManager> profile_manager_;
@@ -1108,10 +1217,6 @@
 
     // Initialize the rest.
     ChromeLauncherControllerImplTest::SetUp();
-
-    // Get some base objects.
-    shell_delegate_ = static_cast<ash::test::TestShellDelegate*>(
-        ash::Shell::Get()->shell_delegate());
     shell_delegate_->set_multi_profiles_enabled(true);
   }
 
@@ -1196,8 +1301,6 @@
     return v1_app;
   }
 
-  ash::test::TestShellDelegate* shell_delegate() { return shell_delegate_; }
-
   // Override BrowserWithTestWindowTest:
   TestingProfile* CreateProfile() override {
     return CreateMultiUserProfile("user1");
@@ -1221,8 +1324,6 @@
 
   std::unique_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_;
 
-  ash::test::TestShellDelegate* shell_delegate_;
-
   ProfileToNameMap created_profiles_;
 
   DISALLOW_COPY_AND_ASSIGN(
@@ -4145,105 +4246,24 @@
   EXPECT_EQ("AppList, Chrome, App1, App2", GetPinnedAppStatus());
 }
 
-// A test ShelfController implementation that tracks alignment and auto-hide.
-class TestShelfController : public ash::mojom::ShelfController {
- public:
-  TestShelfController() : binding_(this) {}
-  ~TestShelfController() override {}
-
-  ash::ShelfAlignment alignment() const { return alignment_; }
-  ash::ShelfAutoHideBehavior auto_hide() const { return auto_hide_; }
-
-  size_t alignment_change_count() const { return alignment_change_count_; }
-  size_t auto_hide_change_count() const { return auto_hide_change_count_; }
-
-  ash::mojom::ShelfControllerPtr CreateInterfacePtrAndBind() {
-    return binding_.CreateInterfacePtrAndBind();
-  }
-
-  // ash::mojom::ShelfController:
-  void AddObserver(
-      ash::mojom::ShelfObserverAssociatedPtrInfo observer) override {
-    observer_.Bind(std::move(observer));
-  }
-  void SetAlignment(ash::ShelfAlignment alignment,
-                    int64_t display_id) override {
-    alignment_change_count_++;
-    alignment_ = alignment;
-    observer_->OnAlignmentChanged(alignment_, display_id);
-  }
-  void SetAutoHideBehavior(ash::ShelfAutoHideBehavior auto_hide,
-                           int64_t display_id) override {
-    auto_hide_change_count_++;
-    auto_hide_ = auto_hide;
-    observer_->OnAutoHideBehaviorChanged(auto_hide_, display_id);
-  }
-  void PinItem(
-      const ash::ShelfItem& item,
-      ash::mojom::ShelfItemDelegateAssociatedPtrInfo delegate) override {}
-  void UnpinItem(const std::string& app_id) override {}
-  void SetItemImage(const std::string& app_id, const SkBitmap& image) override {
-  }
-
- private:
-  ash::ShelfAlignment alignment_ = ash::SHELF_ALIGNMENT_BOTTOM_LOCKED;
-  ash::ShelfAutoHideBehavior auto_hide_ = ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN;
-
-  size_t alignment_change_count_ = 0;
-  size_t auto_hide_change_count_ = 0;
-
-  ash::mojom::ShelfObserverAssociatedPtr observer_;
-  mojo::Binding<ash::mojom::ShelfController> binding_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestShelfController);
-};
-
-// A test ChromeLauncherControllerImpl sublcass that uses TestShelfController.
-class TestChromeLauncherControllerImpl : public ChromeLauncherControllerImpl {
- public:
-  TestChromeLauncherControllerImpl(Profile* profile, ash::ShelfModel* model)
-      : ChromeLauncherControllerImpl(profile, model) {}
-
-  // ChromeLauncherControllerImpl:
-  using ChromeLauncherControllerImpl::ReleaseProfile;
-  bool ConnectToShelfController() override {
-    // Set the shelf controller pointer to a test instance; this is run in init.
-    if (!shelf_controller_.is_bound())
-      shelf_controller_ = test_shelf_controller_.CreateInterfacePtrAndBind();
-    return true;
-  }
-
-  TestShelfController* test_shelf_controller() {
-    return &test_shelf_controller_;
-  }
-
- private:
-  TestShelfController test_shelf_controller_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestChromeLauncherControllerImpl);
-};
-
-using ChromeLauncherControllerImplPrefTest = BrowserWithTestWindowTest;
-
 // Tests that shelf profile preferences are loaded on login.
-TEST_F(ChromeLauncherControllerImplPrefTest, PrefsLoadedOnLogin) {
+TEST_F(ChromeLauncherControllerImplTest, PrefsLoadedOnLogin) {
   PrefService* prefs = profile()->GetTestingPrefService();
   prefs->SetString(prefs::kShelfAlignmentLocal, "Left");
   prefs->SetString(prefs::kShelfAlignment, "Left");
   prefs->SetString(prefs::kShelfAutoHideBehaviorLocal, "Always");
   prefs->SetString(prefs::kShelfAutoHideBehavior, "Always");
 
-  ash::ShelfModel* model = ash::Shell::Get()->shelf_controller()->model();
-  TestChromeLauncherControllerImpl test_launcher_controller(profile(), model);
-  test_launcher_controller.Init();
+  TestChromeLauncherControllerImpl* test_launcher_controller =
+      shell_delegate_->CreateTestLauncherController(profile());
 
   // Simulate login for the test controller.
-  test_launcher_controller.ReleaseProfile();
-  test_launcher_controller.AttachProfile(profile());
+  test_launcher_controller->ReleaseProfile();
+  test_launcher_controller->AttachProfile(profile());
   base::RunLoop().RunUntilIdle();
 
   TestShelfController* shelf_controller =
-      test_launcher_controller.test_shelf_controller();
+      test_launcher_controller->test_shelf_controller();
   ASSERT_TRUE(shelf_controller);
   EXPECT_EQ(ash::SHELF_ALIGNMENT_LEFT, shelf_controller->alignment());
   EXPECT_EQ(1u, shelf_controller->alignment_change_count());
@@ -4253,18 +4273,17 @@
 }
 
 // Tests that the shelf controller's changes are not wastefully echoed back.
-TEST_F(ChromeLauncherControllerImplPrefTest, DoNotEchoShelfControllerChanges) {
-  ash::ShelfModel* model = ash::Shell::Get()->shelf_controller()->model();
-  TestChromeLauncherControllerImpl test_launcher_controller(profile(), model);
-  test_launcher_controller.Init();
+TEST_F(ChromeLauncherControllerImplTest, DoNotEchoShelfControllerChanges) {
+  TestChromeLauncherControllerImpl* test_launcher_controller =
+      shell_delegate_->CreateTestLauncherController(profile());
 
   // Simulate login for the test controller.
-  test_launcher_controller.ReleaseProfile();
-  test_launcher_controller.AttachProfile(profile());
+  test_launcher_controller->ReleaseProfile();
+  test_launcher_controller->AttachProfile(profile());
   base::RunLoop().RunUntilIdle();
 
   TestShelfController* shelf_controller =
-      test_launcher_controller.test_shelf_controller();
+      test_launcher_controller->test_shelf_controller();
   ASSERT_TRUE(shelf_controller);
   EXPECT_EQ(ash::SHELF_ALIGNMENT_BOTTOM, shelf_controller->alignment());
   EXPECT_EQ(1u, shelf_controller->alignment_change_count());
diff --git a/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc
index 7db9081..efca8c0 100644
--- a/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.h"
 
-#include "ash/shelf/shelf_delegate.h"
 #include "ash/shelf/shelf_model.h"
 #include "ash/shell.h"
 #include "ash/wm/window_properties.h"
@@ -131,22 +130,9 @@
 void ExtensionAppWindowLauncherController::RegisterApp(AppWindow* app_window) {
   // Windows created by IME extension should be treated the same way as the
   // virtual keyboard window, which does not register itself in launcher.
-  if (app_window->is_ime_window())
-    return;
-
   // Ash's ShelfWindowWatcher handles app panel windows separately.
-  if (app_window->window_type_is_panel()) {
-    // Load panel app icons now. ShelfWindowWatcher cannot easily trigger this,
-    // and ShelfModel::Set cannot be called in ShelfItemAdded, since ShelfView
-    // may not have added a view for the new shelf item at that point.
-    const std::string& app_id = app_window->extension_id();
-    AppIconLoader* app_icon_loader = owner()->GetAppIconLoaderForApp(app_id);
-    if (app_icon_loader) {
-      app_icon_loader->FetchImage(app_id);
-      app_icon_loader->UpdateImage(app_id);
-    }
+  if (app_window->is_ime_window() || app_window->window_type_is_panel())
     return;
-  }
 
   aura::Window* window = app_window->GetNativeWindow();
   // Get the app's shelf identifier and add an entry to the map.
@@ -182,9 +168,8 @@
     controller->AddAppWindow(app_window);
     // If there is already a shelf id mapped to this AppLaunchId (e.g. pinned),
     // use that shelf item.
-    shelf_id =
-        ash::Shell::Get()->shelf_delegate()->GetShelfIDForAppIDAndLaunchID(
-            app_id, launch_id);
+    shelf_id = ash::Shell::Get()->shelf_model()->GetShelfIDForAppIDAndLaunchID(
+        app_id, launch_id);
 
     if (shelf_id == 0) {
       shelf_id = owner()->CreateAppLauncherItem(std::move(controller), status);
diff --git a/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc b/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc
index 94429439..e0c2835 100644
--- a/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc
@@ -10,7 +10,9 @@
 #include "ash/root_window_controller.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
+#include "ash/test/ash_test_helper.h"
 #include "ash/test/shell_test_api.h"
+#include "ash/test/test_shell_delegate.h"
 #include "ash/wm_window.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
@@ -34,28 +36,47 @@
 #include "ui/display/screen.h"
 #include "ui/views/widget/widget.h"
 
+namespace {
+
+// A shell delegate that owns a ChromeLauncherController, like production.
+class ChromeLauncherTestShellDelegate : public ash::test::TestShellDelegate {
+ public:
+  explicit ChromeLauncherTestShellDelegate(Profile* profile)
+      : profile_(profile) {}
+
+  ChromeLauncherControllerImpl* controller() { return controller_.get(); }
+
+  // ash::test::TestShellDelegate:
+  void ShelfInit() override {
+    if (!controller_) {
+      controller_ = base::MakeUnique<ChromeLauncherControllerImpl>(
+          profile_, ash::Shell::Get()->shelf_model());
+      controller_->Init();
+    }
+  }
+  void ShelfShutdown() override { controller_.reset(); }
+
+ private:
+  Profile* profile_;
+  std::unique_ptr<ChromeLauncherControllerImpl> controller_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeLauncherTestShellDelegate);
+};
+
 class LauncherContextMenuTest : public ash::test::AshTestBase {
  protected:
   static bool IsItemPresentInMenu(LauncherContextMenu* menu, int command_id) {
     return menu->GetIndexOfCommandId(command_id) != -1;
   }
 
-  LauncherContextMenuTest() : profile_(new TestingProfile()) {}
+  LauncherContextMenuTest() {}
 
   void SetUp() override {
-    arc_test_.SetUp(profile_.get());
+    arc_test_.SetUp(&profile_);
     session_manager_ = base::MakeUnique<session_manager::SessionManager>();
+    shell_delegate_ = new ChromeLauncherTestShellDelegate(&profile_);
+    ash_test_helper()->set_test_shell_delegate(shell_delegate_);
     ash::test::AshTestBase::SetUp();
-    std::unique_ptr<ChromeLauncherControllerImpl> controller =
-        base::MakeUnique<ChromeLauncherControllerImpl>(
-            profile(), ash::Shell::Get()->shelf_model());
-    controller_ = controller.get();
-    controller_->Init();
-    ash::test::ShellTestApi().SetShelfDelegate(std::move(controller));
-  }
-
-  void TearDown() override {
-    ash::test::AshTestBase::TearDown();
   }
 
   ash::WmShelf* GetWmShelf(int64_t display_id) {
@@ -71,13 +92,12 @@
     ash::ShelfItem item;
     item.id = 123;  // dummy id
     item.type = shelf_item_type;
-    return LauncherContextMenu::Create(controller_, &item, wm_shelf);
+    return LauncherContextMenu::Create(controller(), &item, wm_shelf);
   }
 
   LauncherContextMenu* CreateLauncherContextMenuForDesktopShell(
       ash::WmShelf* wm_shelf) {
-    ash::ShelfItem* item = nullptr;
-    return LauncherContextMenu::Create(controller_, item, wm_shelf);
+    return LauncherContextMenu::Create(controller(), nullptr, wm_shelf);
   }
 
   // Creates app window and set optional ARC application id.
@@ -94,13 +114,15 @@
 
   ArcAppTest& arc_test() { return arc_test_; }
 
-  Profile* profile() { return profile_.get(); }
+  Profile* profile() { return &profile_; }
 
-  ChromeLauncherControllerImpl* controller() { return controller_; }
+  ChromeLauncherControllerImpl* controller() {
+    return shell_delegate_->controller();
+  }
 
  private:
-  std::unique_ptr<TestingProfile> profile_;
-  ChromeLauncherControllerImpl* controller_ = nullptr;
+  TestingProfile profile_;
+  ChromeLauncherTestShellDelegate* shell_delegate_ = nullptr;
   ArcAppTest arc_test_;
   std::unique_ptr<session_manager::SessionManager> session_manager_;
 
@@ -310,3 +332,5 @@
   EXPECT_TRUE(IsItemPresentInMenu(secondary_menu.get(),
                                   LauncherContextMenu::MENU_AUTO_HIDE));
 }
+
+}  // namespace
diff --git a/chrome/browser/ui/ash/system_tray_client.cc b/chrome/browser/ui/ash/system_tray_client.cc
index 36ef7933..aaad833 100644
--- a/chrome/browser/ui/ash/system_tray_client.cc
+++ b/chrome/browser/ui/ash/system_tray_client.cc
@@ -381,7 +381,10 @@
 void SystemTrayClient::HandleUpdateAvailable() {
   // Show an update icon for Chrome updates and Flash component updates.
   UpgradeDetector* detector = UpgradeDetector::GetInstance();
-  DCHECK(detector->notify_upgrade() || flash_update_available_);
+  bool update_available = detector->notify_upgrade() || flash_update_available_;
+  DCHECK(update_available);
+  if (!update_available)
+    return;
 
   // Get the Chrome update severity.
   ash::mojom::UpdateSeverity severity = GetUpdateSeverity(detector);
@@ -390,7 +393,14 @@
   if (flash_update_available_)
     severity = std::max(severity, ash::mojom::UpdateSeverity::LOW);
 
-  system_tray_->ShowUpdateIcon(severity, detector->is_factory_reset_required());
+  // Show a string specific to updating flash player if there is no system
+  // update.
+  ash::mojom::UpdateType update_type = detector->notify_upgrade()
+                                           ? ash::mojom::UpdateType::SYSTEM
+                                           : ash::mojom::UpdateType::FLASH;
+
+  system_tray_->ShowUpdateIcon(severity, detector->is_factory_reset_required(),
+                               update_type);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
index b176b96..edbf0cc 100644
--- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
@@ -113,6 +113,11 @@
   return session_manager::SessionManager::Get()->IsInSecondaryLoginScreen();
 }
 
+bool IsUserSupervised() {
+  user_manager::User* user = user_manager::UserManager::Get()->GetActiveUser();
+  return user && user->IsSupervised();
+}
+
 }  // namespace
 
 SystemTrayDelegateChromeOS::SystemTrayDelegateChromeOS()
@@ -234,20 +239,11 @@
     const {
   if (!IsUserSupervised())
     return base::string16();
-  if (IsUserChild())
+  if (user_manager::UserManager::Get()->IsLoggedInAsChildUser())
     return GetChildUserMessage();
   return GetLegacySupervisedUserMessage();
 }
 
-bool SystemTrayDelegateChromeOS::IsUserSupervised() const {
-  user_manager::User* user = user_manager::UserManager::Get()->GetActiveUser();
-  return user && user->IsSupervised();
-}
-
-bool SystemTrayDelegateChromeOS::IsUserChild() const {
-  return user_manager::UserManager::Get()->IsLoggedInAsChildUser();
-}
-
 void SystemTrayDelegateChromeOS::ShowEnterpriseInfo() {
   // TODO(mash): Refactor out SessionStateDelegate and move to SystemTrayClient.
   ash::LoginStatus status = GetUserLoginStatus();
@@ -695,6 +691,8 @@
 const base::string16
 SystemTrayDelegateChromeOS::GetChildUserMessage() const {
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
+  // TODO(jamescook): If supervised users are always enabled on Chrome OS then
+  // these ifdefs can be removed.
   SupervisedUserService* service =
       SupervisedUserServiceFactory::GetForProfile(user_profile_);
   base::string16 first_custodian =
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
index 035a5b9f..e7bade25 100644
--- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
+++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
@@ -58,8 +58,6 @@
   std::string GetSupervisedUserManager() const override;
   base::string16 GetSupervisedUserManagerName() const override;
   base::string16 GetSupervisedUserMessage() const override;
-  bool IsUserSupervised() const override;
-  bool IsUserChild() const override;
   void ShowEnterpriseInfo() override;
   void ShowUserLogin() override;
   void GetCurrentIME(ash::IMEInfo* info) override;
diff --git a/chrome/browser/ui/browser_dialogs.h b/chrome/browser/ui/browser_dialogs.h
index 7bcd9c4..11f6915 100644
--- a/chrome/browser/ui/browser_dialogs.h
+++ b/chrome/browser/ui/browser_dialogs.h
@@ -188,7 +188,28 @@
 // different type of dialog box.
 // These values are written to logs. New enum values can be added, but existing
 // enums must never be renumbered or deleted and reused.
-enum class DialogIdentifier { UNKNOWN = 0, TRANSLATE = 1, MAX_VALUE };
+enum class DialogIdentifier {
+  UNKNOWN = 0,
+  TRANSLATE = 1,
+  BOOKMARK = 2,
+  BOOKMARK_EDITOR = 3,
+  DESKTOP_MEDIA_PICKER = 4,
+  OUTDATED_UPGRADE = 5,
+  ONE_CLICK_SIGNIN = 6,
+  PROFILE_SIGNIN_CONFIRMATION = 7,
+  HUNG_RENDERER = 8,
+  SESSION_CRASHED = 9,
+  CONFIRM_BUBBLE = 10,
+  UPDATE_RECOMMENDED = 11,
+  CRYPTO_PASSWORD = 12,
+  SAFE_BROWSING_DOWNLOAD_FEEDBACK = 13,
+  FIRST_RUN = 14,
+  NETWORK_SHARE_PROFILE_WARNING = 15,
+  CONFLICTING_MODULE = 16,
+  CRITICAL_NOTIFICATION = 17,
+  IME_WARNING = 18,
+  MAX_VALUE
+};
 
 // Record an UMA metric counting the creation of a dialog box of this type.
 void RecordDialogCreation(DialogIdentifier identifier);
diff --git a/chrome/browser/ui/exclusive_access/flash_fullscreen_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/flash_fullscreen_interactive_browsertest.cc
index 05cc335..b26cf9f 100644
--- a/chrome/browser/ui/exclusive_access/flash_fullscreen_interactive_browsertest.cc
+++ b/chrome/browser/ui/exclusive_access/flash_fullscreen_interactive_browsertest.cc
@@ -282,7 +282,6 @@
                                       const SkBitmap& bitmap,
                                       content::ReadbackResponse response) {
     if (response == content::READBACK_SUCCESS) {
-      SkAutoLockPixels lock_pixels(bitmap);
       if (bitmap.width() > 0 && bitmap.height() > 0)
         *is_expected_color = (bitmap.getColor(0, 0) == expected_color);
     }
diff --git a/chrome/browser/ui/libgtkui/skia_utils_gtk.cc b/chrome/browser/ui/libgtkui/skia_utils_gtk.cc
index f4a2dd96..150a41d 100644
--- a/chrome/browser/ui/libgtkui/skia_utils_gtk.cc
+++ b/chrome/browser/ui/libgtkui/skia_utils_gtk.cc
@@ -88,8 +88,6 @@
   if (bitmap.isNull())
     return nullptr;
 
-  SkAutoLockPixels lock_pixels(bitmap);
-
   int width = bitmap.width();
   int height = bitmap.height();
 
diff --git a/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc b/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc
index 4ff581c..bc73e882 100644
--- a/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc
+++ b/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc
@@ -551,9 +551,6 @@
   SkBitmap default_icon_bitmap = *default_icon.ToSkBitmap();
   SkBitmap valid_icon_bitmap = *valid_icon.ToSkBitmap();
 
-  SkAutoLockPixels a(new_icon_bitmap);
-  SkAutoLockPixels b(valid_icon_bitmap);
-  SkAutoLockPixels c(default_icon_bitmap);
   // Verify we did not get the default favicon.
   EXPECT_NE(0, memcmp(default_icon_bitmap.getPixels(),
                       valid_icon_bitmap.getPixels(),
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc
index cbd7890..825c43d 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc
@@ -21,8 +21,8 @@
 #include "ui/views/widget/widget.h"
 
 #if defined(USE_ASH)
-#include "ash/shelf/shelf_delegate.h"  // nogncheck
-#include "ash/shell.h"                        // nogncheck
+#include "ash/shelf/shelf_model.h"  // nogncheck
+#include "ash/shell.h"              // nogncheck
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h"  // nogncheck
 #endif
 
@@ -89,8 +89,7 @@
 void AppInfoFooterPanel::UpdatePinButtons(bool focus_visible_button) {
 #if defined(USE_ASH)
   if (pin_to_shelf_button_ && unpin_from_shelf_button_) {
-    bool is_pinned =
-        !ash::Shell::Get()->shelf_delegate()->IsAppPinned(app_->id());
+    bool is_pinned = !ash::Shell::Get()->shelf_model()->IsAppPinned(app_->id());
     pin_to_shelf_button_->SetVisible(is_pinned);
     unpin_from_shelf_button_->SetVisible(!is_pinned);
 
@@ -152,12 +151,12 @@
 #if defined(USE_ASH)
 void AppInfoFooterPanel::SetPinnedToShelf(bool value) {
   DCHECK(CanSetPinnedToShelf());
-  ash::ShelfDelegate* shelf_delegate = ash::Shell::Get()->shelf_delegate();
-  DCHECK(shelf_delegate);
+  ash::ShelfModel* shelf_model = ash::Shell::Get()->shelf_model();
+  DCHECK(shelf_model);
   if (value)
-    shelf_delegate->PinAppWithID(app_->id());
+    shelf_model->PinAppWithID(app_->id());
   else
-    shelf_delegate->UnpinAppWithID(app_->id());
+    shelf_model->UnpinAppWithID(app_->id());
 
   UpdatePinButtons(true);
   Layout();
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
index 1c503a9..bb12026 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
@@ -303,7 +303,9 @@
       ios_promo_view_(nullptr),
       remove_bookmark_(false),
       apply_edits_(true),
-      is_showing_ios_promotion_(false) {}
+      is_showing_ios_promotion_(false) {
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::BOOKMARK);
+}
 
 base::string16 BookmarkBubbleView::GetTitle() {
   BookmarkModel* bookmark_model =
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
index 6b74d78d..220e34ba 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
@@ -73,6 +73,7 @@
   DCHECK(bb_model_);
   DCHECK(bb_model_->client()->CanBeEditedByUser(parent));
   Init();
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::BOOKMARK_EDITOR);
 }
 
 BookmarkEditorView::~BookmarkEditorView() {
diff --git a/chrome/browser/ui/views/confirm_bubble_views.cc b/chrome/browser/ui/views/confirm_bubble_views.cc
index 95bf4f0..0f86435 100644
--- a/chrome/browser/ui/views/confirm_bubble_views.cc
+++ b/chrome/browser/ui/views/confirm_bubble_views.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/confirm_bubble.h"
 #include "chrome/browser/ui/confirm_bubble_model.h"
 #include "components/constrained_window/constrained_window_views.h"
@@ -40,6 +41,8 @@
   link_ = new views::Link(model_->GetLinkText());
   link_->set_listener(this);
   link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::CONFIRM_BUBBLE);
 }
 
 ConfirmBubbleViews::~ConfirmBubbleViews() {
diff --git a/chrome/browser/ui/views/conflicting_module_view_win.cc b/chrome/browser/ui/views/conflicting_module_view_win.cc
index f4b463b..a8de551 100644
--- a/chrome/browser/ui/views/conflicting_module_view_win.cc
+++ b/chrome/browser/ui/views/conflicting_module_view_win.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/layout_constants.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/chromium_strings.h"
@@ -52,6 +53,8 @@
       GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0));
 
   observer_.Add(EnumerateModulesModel::GetInstance());
+
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::CONFLICTING_MODULE);
 }
 
 // static
diff --git a/chrome/browser/ui/views/critical_notification_bubble_view.cc b/chrome/browser/ui/views/critical_notification_bubble_view.cc
index 372e2ff..847f889 100644
--- a/chrome/browser/ui/views/critical_notification_bubble_view.cc
+++ b/chrome/browser/ui/views/critical_notification_bubble_view.cc
@@ -8,6 +8,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/upgrade_detector.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/chromium_strings.h"
@@ -44,6 +45,7 @@
     views::View* anchor_view)
     : BubbleDialogDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT) {
   set_close_on_deactivate(false);
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::CRITICAL_NOTIFICATION);
 }
 
 CriticalNotificationBubbleView::~CriticalNotificationBubbleView() {
diff --git a/chrome/browser/ui/views/crypto_module_password_dialog_view.cc b/chrome/browser/ui/views/crypto_module_password_dialog_view.cc
index 03087a4..aaf7ce3 100644
--- a/chrome/browser/ui/views/crypto_module_password_dialog_view.cc
+++ b/chrome/browser/ui/views/crypto_module_password_dialog_view.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/views/crypto_module_password_dialog_view.h"
 
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/strings/grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -27,6 +28,7 @@
     const CryptoModulePasswordCallback& callback)
     : callback_(callback) {
   Init(hostname, slot_name, reason);
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::CRYPTO_PASSWORD);
 }
 
 CryptoModulePasswordDialogView::~CryptoModulePasswordDialogView() {
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
index d66e7cc4..8d806db 100644
--- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
+++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
@@ -6,6 +6,7 @@
 
 #include "base/callback.h"
 #include "chrome/browser/media/webrtc/desktop_media_list.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/views/desktop_capture/desktop_media_list_view.h"
@@ -217,6 +218,7 @@
     widget = DialogDelegate::CreateDialogWidget(this, context, nullptr);
     widget->Show();
   }
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::DESKTOP_MEDIA_PICKER);
 
   // If the picker is not modal to the calling web contents then it is displayed
   // in its own top-level window, so in that case it needs to be filtered out of
diff --git a/chrome/browser/ui/views/download/download_feedback_dialog_view.cc b/chrome/browser/ui/views/download/download_feedback_dialog_view.cc
index 188b7e5..6064eae 100644
--- a/chrome/browser/ui/views/download/download_feedback_dialog_view.cc
+++ b/chrome/browser/ui/views/download/download_feedback_dialog_view.cc
@@ -8,6 +8,7 @@
 #include "base/supports_user_data.h"
 #include "chrome/browser/platform_util.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
@@ -92,6 +93,8 @@
       cancel_button_text_(l10n_util::GetStringUTF16(
           IDS_FEEDBACK_SERVICE_DIALOG_CANCEL_BUTTON_LABEL)) {
   link_view_->set_listener(this);
+  chrome::RecordDialogCreation(
+      chrome::DialogIdentifier::SAFE_BROWSING_DOWNLOAD_FEEDBACK);
 }
 
 DownloadFeedbackDialogView::~DownloadFeedbackDialogView() {}
diff --git a/chrome/browser/ui/views/first_run_bubble.cc b/chrome/browser/ui/views/first_run_bubble.cc
index 55271479..4b047648 100644
--- a/chrome/browser/ui/views/first_run_bubble.cc
+++ b/chrome/browser/ui/views/first_run_bubble.cc
@@ -7,6 +7,7 @@
 #include "chrome/browser/first_run/first_run.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/layout_constants.h"
 #include "chrome/grit/generated_resources.h"
@@ -88,6 +89,7 @@
   // Compensate for built-in vertical padding in the anchor view's image.
   set_anchor_view_insets(gfx::Insets(
       GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0));
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::FIRST_RUN);
 }
 
 int FirstRunBubble::GetDialogButtons() const {
diff --git a/chrome/browser/ui/views/hung_renderer_view.cc b/chrome/browser/ui/views/hung_renderer_view.cc
index d08f1e8a..acbad1da 100644
--- a/chrome/browser/ui/views/hung_renderer_view.cc
+++ b/chrome/browser/ui/views/hung_renderer_view.cc
@@ -10,6 +10,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/browser/platform_util.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
@@ -230,6 +231,7 @@
 HungRendererDialogView::HungRendererDialogView()
     : info_label_(nullptr), hung_pages_table_(nullptr), initialized_(false) {
   InitClass();
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::HUNG_RENDERER);
 }
 
 HungRendererDialogView::~HungRendererDialogView() {
diff --git a/chrome/browser/ui/views/ime/ime_warning_bubble_view.cc b/chrome/browser/ui/views/ime/ime_warning_bubble_view.cc
index 4a471c5..24c019c 100644
--- a/chrome/browser/ui/views/ime/ime_warning_bubble_view.cc
+++ b/chrome/browser/ui/views/ime/ime_warning_bubble_view.cc
@@ -9,6 +9,7 @@
 #include "base/callback_helpers.h"
 #include "chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.h"
 #include "chrome/browser/platform_util.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/harmony/chrome_typography.h"
@@ -119,6 +120,7 @@
   }
   views::BubbleDialogDelegateView::CreateBubble(this)->Show();
   bubble_has_shown_ = true;
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::IME_WARNING);
 }
 
 ImeWarningBubbleView::~ImeWarningBubbleView() {
diff --git a/chrome/browser/ui/views/network_profile_bubble_view.cc b/chrome/browser/ui/views/network_profile_bubble_view.cc
index 7edb714..fa94d7d 100644
--- a/chrome/browser/ui/views/network_profile_bubble_view.cc
+++ b/chrome/browser/ui/views/network_profile_bubble_view.cc
@@ -5,6 +5,7 @@
 #include "base/macros.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/network_profile_bubble.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
@@ -66,6 +67,8 @@
   // Compensate for built-in vertical padding in the anchor view's image.
   set_anchor_view_insets(gfx::Insets(
       GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0));
+  chrome::RecordDialogCreation(
+      chrome::DialogIdentifier::NETWORK_SHARE_PROFILE_WARNING);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc b/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc
index c296c1b..dce918de 100644
--- a/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc
+++ b/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc
@@ -9,6 +9,7 @@
 #include "base/task_scheduler/post_task.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/views/elevation_icon_setter.h"
 #include "chrome/browser/upgrade_detector.h"
@@ -186,4 +187,5 @@
   // Compensate for built-in vertical padding in the anchor view's image.
   set_anchor_view_insets(gfx::Insets(
       GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0));
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::OUTDATED_UPGRADE);
 }
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc
index 5fd54eb1..441c54b 100644
--- a/chrome/browser/ui/views/session_crashed_bubble_view.cc
+++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/metrics/metrics_reporting_state.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/sessions/session_restore.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_list_observer.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -172,6 +173,7 @@
       offer_uma_optin_(offer_uma_optin),
       ignored_(true) {
   set_close_on_deactivate(false);
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::SESSION_CRASHED);
 }
 
 SessionCrashedBubbleView::~SessionCrashedBubbleView() {
diff --git a/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc b/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc
index 9848c03a..7a181e6 100644
--- a/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc
+++ b/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc
@@ -9,6 +9,7 @@
 #include "base/callback_helpers.h"
 #include "base/logging.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
@@ -74,6 +75,7 @@
       advanced_link_(nullptr),
       learn_more_link_(nullptr) {
   DCHECK(!start_sync_callback_.is_null());
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::ONE_CLICK_SIGNIN);
 }
 
 OneClickSigninDialogView::~OneClickSigninDialogView() {
diff --git a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
index 18ea2fa..703f547 100644
--- a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
+++ b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
@@ -10,6 +10,7 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/browser_navigator_params.h"
 #include "chrome/browser/ui/browser_window.h"
@@ -48,7 +49,10 @@
     : browser_(browser),
       username_(username),
       delegate_(std::move(delegate)),
-      prompt_for_new_profile_(true) {}
+      prompt_for_new_profile_(true) {
+  chrome::RecordDialogCreation(
+      chrome::DialogIdentifier::PROFILE_SIGNIN_CONFIRMATION);
+}
 
 ProfileSigninConfirmationDialogViews::~ProfileSigninConfirmationDialogViews() {}
 
diff --git a/chrome/browser/ui/views/toolbar/app_menu.cc b/chrome/browser/ui/views/toolbar/app_menu.cc
index 9b6ffe26..cc9f443 100644
--- a/chrome/browser/ui/views/toolbar/app_menu.cc
+++ b/chrome/browser/ui/views/toolbar/app_menu.cc
@@ -387,7 +387,6 @@
     SkBitmap white;
     white.allocN32Pixels(bitmap.width(), bitmap.height());
     white.eraseARGB(0, 0, 0, 0);
-    bitmap.lockPixels();
     for (int y = 0; y < bitmap.height(); ++y) {
       uint32_t* image_row = bitmap.getAddr32(0, y);
       uint32_t* dst_row = white.getAddr32(0, y);
@@ -397,7 +396,6 @@
         dst_row[x] = (image_pixel & 0xFF000000) == 0x0 ? 0x0 : color_;
       }
     }
-    bitmap.unlockPixels();
     return gfx::ImageSkiaRep(white, scale);
   }
 
@@ -1049,6 +1047,16 @@
     selected_menu_model_->ActivatedAt(selected_index_);
 }
 
+bool AppMenu::ShouldExecuteCommandWithoutClosingMenu(int command_id,
+                                                     const ui::Event& event) {
+  if (IsRecentTabsCommand(command_id) && event.IsMouseEvent()) {
+    const auto disposition = ui::DispositionFromEventFlags(event.flags());
+    if (disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB)
+      return true;
+  }
+  return false;
+}
+
 void AppMenu::BookmarkModelChanged() {
   DCHECK(bookmark_menu_delegate_.get());
   if (!bookmark_menu_delegate_->is_mutating_model())
diff --git a/chrome/browser/ui/views/toolbar/app_menu.h b/chrome/browser/ui/views/toolbar/app_menu.h
index 46e44c8..10bb303 100644
--- a/chrome/browser/ui/views/toolbar/app_menu.h
+++ b/chrome/browser/ui/views/toolbar/app_menu.h
@@ -98,6 +98,8 @@
   bool ShouldCloseOnDragComplete() override;
   void OnMenuClosed(views::MenuItemView* menu,
                     views::MenuRunner::RunResult result) override;
+  bool ShouldExecuteCommandWithoutClosingMenu(int command_id,
+                                              const ui::Event& event) override;
 
   // bookmarks::BaseBookmarkModelObserver overrides:
   void BookmarkModelChanged() override;
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc
index 58295dc..7c6d8c65 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.cc
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -366,7 +366,7 @@
   translate_bubble_view_ = this;
   if (web_contents)  // web_contents can be null in unit_tests.
     mouse_handler_.reset(new WebContentMouseHandler(this, web_contents));
-  RecordDialogCreation(chrome::DialogIdentifier::TRANSLATE);
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::TRANSLATE);
 }
 
 views::View* TranslateBubbleView::GetCurrentView() const {
diff --git a/chrome/browser/ui/views/update_recommended_message_box.cc b/chrome/browser/ui/views/update_recommended_message_box.cc
index 87048360..03c7e183 100644
--- a/chrome/browser/ui/views/update_recommended_message_box.cc
+++ b/chrome/browser/ui/views/update_recommended_message_box.cc
@@ -6,6 +6,7 @@
 
 #include "build/build_config.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/grit/chromium_strings.h"
 #include "components/constrained_window/constrained_window_views.h"
 #include "components/strings/grit/components_strings.h"
@@ -38,6 +39,7 @@
   params.message_width = kDialogWidth;
   // Also deleted when the window closes.
   message_box_view_ = new views::MessageBoxView(params);
+  chrome::RecordDialogCreation(chrome::DialogIdentifier::UPDATE_RECOMMENDED);
 }
 
 UpdateRecommendedMessageBox::~UpdateRecommendedMessageBox() {
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui_browsertest.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui_browsertest.cc
index 2e9a958..070051e 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui_browsertest.cc
@@ -37,9 +37,9 @@
 
 namespace {
 
-class PrintPreviewTest : public InProcessBrowserTest {
+class PrintPreviewBrowserTest : public InProcessBrowserTest {
  public:
-  PrintPreviewTest() {}
+  PrintPreviewBrowserTest() {}
 
   void Print() {
     content::TestNavigationObserver nav_observer(NULL);
@@ -50,7 +50,7 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(PrintPreviewTest, PrintCommands) {
+IN_PROC_BROWSER_TEST_F(PrintPreviewBrowserTest, PrintCommands) {
   // We start off at about:blank page.
   // Make sure there is 1 tab and print is enabled.
   ASSERT_EQ(1, browser()->tab_strip_model()->count());
@@ -93,7 +93,8 @@
 #else
 #define MAYBE_TaskManagerNewPrintPreview TaskManagerNewPrintPreview
 #endif
-IN_PROC_BROWSER_TEST_F(PrintPreviewTest, MAYBE_TaskManagerNewPrintPreview) {
+IN_PROC_BROWSER_TEST_F(PrintPreviewBrowserTest,
+                       MAYBE_TaskManagerNewPrintPreview) {
   chrome::ShowTaskManager(browser());  // Show task manager BEFORE print dialog.
 
   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
@@ -111,7 +112,7 @@
 }
 
 // http://crbug/367665.
-IN_PROC_BROWSER_TEST_F(PrintPreviewTest,
+IN_PROC_BROWSER_TEST_F(PrintPreviewBrowserTest,
                        DISABLED_TaskManagerExistingPrintPreview) {
   // Create the print preview dialog.
   Print();
@@ -127,7 +128,8 @@
 
 #if defined(OS_WIN)
 // http://crbug.com/396360
-IN_PROC_BROWSER_TEST_F(PrintPreviewTest, DISABLED_NoCrashOnCloseWithOtherTabs) {
+IN_PROC_BROWSER_TEST_F(PrintPreviewBrowserTest,
+                       DISABLED_NoCrashOnCloseWithOtherTabs) {
   // Now print preview.
   Print();
 
diff --git a/chrome/browser/web_applications/web_app_win.cc b/chrome/browser/web_applications/web_app_win.cc
index 98137b2..fe26bca 100644
--- a/chrome/browser/web_applications/web_app_win.cc
+++ b/chrome/browser/web_applications/web_app_win.cc
@@ -53,7 +53,6 @@
        ++it) {
     SkBitmap bitmap = it->AsBitmap();
 
-    SkAutoLockPixels image_lock(bitmap);
     base::StringPiece image_data(
         reinterpret_cast<const char*>(bitmap.getPixels()), bitmap.getSize());
     base::MD5Update(&md5_context, image_data);
diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc
index 366b3941..5fbbb79 100644
--- a/chrome/renderer/chrome_render_frame_observer.cc
+++ b/chrome/renderer/chrome_render_frame_observer.cc
@@ -209,7 +209,6 @@
     thumbnail.copyTo(&bitmap, kN32_SkColorType);
 
   std::vector<uint8_t> thumbnail_data;
-  SkAutoLockPixels lock(bitmap);
   if (bitmap.getPixels()) {
     const int kDefaultQuality = 90;
     std::vector<unsigned char> data;
diff --git a/chrome/test/base/browser_with_test_window_test.cc b/chrome/test/base/browser_with_test_window_test.cc
index ecbed8e..8ac0ca74 100644
--- a/chrome/test/base/browser_with_test_window_test.cc
+++ b/chrome/test/base/browser_with_test_window_test.cc
@@ -47,20 +47,19 @@
 
 BrowserWithTestWindowTest::BrowserWithTestWindowTest(Browser::Type browser_type,
                                                      bool hosted_app)
-    : browser_type_(browser_type), hosted_app_(hosted_app) {}
-
-BrowserWithTestWindowTest::~BrowserWithTestWindowTest() {
+    : browser_type_(browser_type), hosted_app_(hosted_app) {
+#if defined(OS_CHROMEOS)
+  ash_test_environment_ = base::MakeUnique<AshTestEnvironmentChrome>();
+  ash_test_helper_ =
+      base::MakeUnique<ash::test::AshTestHelper>(ash_test_environment_.get());
+#endif
 }
 
+BrowserWithTestWindowTest::~BrowserWithTestWindowTest() {}
+
 void BrowserWithTestWindowTest::SetUp() {
   testing::Test::SetUp();
 #if defined(OS_CHROMEOS)
-  // TODO(jamescook): Windows Ash support. This will require refactoring
-  // AshTestHelper and AuraTestHelper so they can be used at the same time,
-  // perhaps by AshTestHelper owning an AuraTestHelper.
-  ash_test_environment_ = base::MakeUnique<AshTestEnvironmentChrome>();
-  ash_test_helper_.reset(
-      new ash::test::AshTestHelper(ash_test_environment_.get()));
   ash_test_helper_->SetUp(true);
 #elif defined(TOOLKIT_VIEWS)
   views_test_helper_.reset(new views::ScopedViewsTestHelper());
diff --git a/chrome/test/base/browser_with_test_window_test.h b/chrome/test/base/browser_with_test_window_test.h
index 2917789..40a3624 100644
--- a/chrome/test/base/browser_with_test_window_test.h
+++ b/chrome/test/base/browser_with_test_window_test.h
@@ -107,6 +107,10 @@
     return window_.release();
   }
 
+#if defined(OS_CHROMEOS)
+  ash::test::AshTestHelper* ash_test_helper() { return ash_test_helper_.get(); }
+#endif
+
   // The context to help determine desktop type when creating new Widgets.
   gfx::NativeWindow GetContext();
 
diff --git a/chrome/test/data/extensions/api_test/native_bindings/extension/background.js b/chrome/test/data/extensions/api_test/native_bindings/extension/background.js
index 2c2d19e..041fa87b 100644
--- a/chrome/test/data/extensions/api_test/native_bindings/extension/background.js
+++ b/chrome/test/data/extensions/api_test/native_bindings/extension/background.js
@@ -192,7 +192,7 @@
       cookiePolicy.get({}, (details) => {
         chrome.test.assertTrue(!!details, 'get details');
         chrome.test.assertTrue(details.value, 'details value true');
-        cookiePolicy.set({value: false}, () => {
+        cookiePolicy.set({value: false, scope: 'regular'}, () => {
           cookiePolicy.get({}, (details) => {
             chrome.test.assertTrue(!!details, 'get details');
             chrome.test.assertFalse(details.value, 'details value false');
diff --git a/components/cryptauth/ble/BUILD.gn b/components/cryptauth/ble/BUILD.gn
index a1de6a07..3b241a8b 100644
--- a/components/cryptauth/ble/BUILD.gn
+++ b/components/cryptauth/ble/BUILD.gn
@@ -54,6 +54,7 @@
     "//components/cryptauth",
     "//components/cryptauth:test_support",
     "//components/prefs:test_support",
+    "//components/proximity_auth/logging",
     "//device/bluetooth:mocks",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
index cf84e960..2c7601d 100644
--- a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
+++ b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
@@ -20,6 +20,7 @@
 #include "components/cryptauth/cryptauth_test_util.h"
 #include "components/cryptauth/remote_device.h"
 #include "components/cryptauth/wire_message.h"
+#include "components/proximity_auth/logging/logging.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
 #include "device/bluetooth/test/mock_bluetooth_device.h"
@@ -638,6 +639,8 @@
   base::Closure write_remote_characteristic_success_callback_;
   device::BluetoothRemoteGattCharacteristic::ErrorCallback
       write_remote_characteristic_error_callback_;
+
+  proximity_auth::ScopedDisableLoggingForTesting disable_logging_;
 };
 
 TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
index f232e945..3e79f4a6 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
@@ -19,6 +19,7 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h"
 #include "components/data_reduction_proxy/core/browser/data_use_group.h"
 #include "components/data_reduction_proxy/core/browser/data_use_group_provider.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_util.h"
 #include "components/data_reduction_proxy/core/common/lofi_decider.h"
@@ -26,6 +27,7 @@
 #include "net/base/mime_util.h"
 #include "net/http/http_request_headers.h"
 #include "net/http/http_response_headers.h"
+#include "net/nqe/effective_connection_type.h"
 #include "net/nqe/network_quality_estimator.h"
 #include "net/proxy/proxy_info.h"
 #include "net/proxy/proxy_server.h"
@@ -136,9 +138,11 @@
                               const net::HttpRequestHeaders& headers) {
   if (via_chrome_proxy) {
     DCHECK(headers.HasHeader(chrome_proxy_header()));
+    DCHECK(headers.HasHeader(chrome_proxy_ect_header()));
   } else {
     DCHECK(!headers.HasHeader(chrome_proxy_header()));
     DCHECK(!headers.HasHeader(chrome_proxy_accept_transform_header()));
+    DCHECK(!headers.HasHeader(chrome_proxy_ect_header()));
   }
 }
 
@@ -223,6 +227,8 @@
         ->MaybeSetAcceptTransformHeader(
             *request, data_reduction_proxy_config_->lofi_off(), headers);
   }
+
+  MaybeAddChromeProxyECTHeader(headers, *request);
 }
 
 void DataReductionProxyNetworkDelegate::OnBeforeSendHeadersInternal(
@@ -281,6 +287,7 @@
       // Chrome-Proxy-Accept-Transform header.
       lofi_decider->RemoveAcceptTransformHeader(headers);
     }
+    RemoveChromeProxyECTHeader(headers);
     VerifyHttpRequestHeaders(false, *headers);
     return;
   }
@@ -574,4 +581,48 @@
                              header_value);
 }
 
+void DataReductionProxyNetworkDelegate::MaybeAddChromeProxyECTHeader(
+    net::HttpRequestHeaders* request_headers,
+    const net::URLRequest& request) const {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  // This method should be called only when the resolved proxy was a data
+  // saver proxy.
+  DCHECK(request.url().is_valid());
+  DCHECK(!request.url().SchemeIsCryptographic());
+  DCHECK(request.url().SchemeIsHTTPOrHTTPS());
+
+  if (request_headers->HasHeader(chrome_proxy_ect_header()))
+    request_headers->RemoveHeader(chrome_proxy_ect_header());
+
+  if (request.context()->network_quality_estimator()) {
+    net::EffectiveConnectionType type = request.context()
+                                            ->network_quality_estimator()
+                                            ->GetEffectiveConnectionType();
+    if (type > net::EFFECTIVE_CONNECTION_TYPE_OFFLINE) {
+      DCHECK_NE(net::EFFECTIVE_CONNECTION_TYPE_LAST, type);
+      request_headers->SetHeader(chrome_proxy_ect_header(),
+                                 net::GetNameForEffectiveConnectionType(type));
+      return;
+    }
+  }
+  request_headers->SetHeader(chrome_proxy_ect_header(),
+                             net::GetNameForEffectiveConnectionType(
+                                 net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN));
+
+  static_assert(net::EFFECTIVE_CONNECTION_TYPE_OFFLINE + 1 ==
+                    net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
+                "ECT enum value is not handled.");
+  static_assert(net::EFFECTIVE_CONNECTION_TYPE_4G + 1 ==
+                    net::EFFECTIVE_CONNECTION_TYPE_LAST,
+                "ECT enum value is not handled.");
+}
+
+void DataReductionProxyNetworkDelegate::RemoveChromeProxyECTHeader(
+    net::HttpRequestHeaders* request_headers) const {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  request_headers->RemoveHeader(chrome_proxy_ect_header());
+}
+
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
index f36cea45..f32107b 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
@@ -157,6 +157,17 @@
       net::HttpRequestHeaders* request_headers,
       const net::URLRequest& request) const;
 
+  // May add chrome-proxy-ect header to |request_headers| if adding of
+  // chrome-proxy-ect is enabled via field trial and a valid estimate of
+  // network quality is available. This method should be called only when the
+  // resolved proxy for |request| is a data saver proxy.
+  void MaybeAddChromeProxyECTHeader(net::HttpRequestHeaders* request_headers,
+                                    const net::URLRequest& request) const;
+
+  // Removes the chrome-proxy-ect header from |request_headers|.
+  void RemoveChromeProxyECTHeader(
+      net::HttpRequestHeaders* request_headers) const;
+
   // All raw Data Reduction Proxy pointers must outlive |this|.
   DataReductionProxyConfig* data_reduction_proxy_config_;
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
index 00a4da1f..8609191 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
@@ -274,6 +274,79 @@
     test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess();
   }
 
+  // Build the sockets by adding appropriate mock data for
+  // |effective_connection_types.size()| number of requests. Data for
+  // chrome-Proxy-ect header is added to the mock data if |expect_ect_header|
+  // is true. |reads_list|, |mock_writes| and |writes_list| should be empty, and
+  // are owned by the caller.
+  void BuildSocket(const std::string& response_headers,
+                   const std::string& response_body,
+                   bool expect_ect_header,
+                   const std::vector<net::EffectiveConnectionType>&
+                       effective_connection_types,
+                   std::vector<net::MockRead>* reads_list,
+                   std::vector<std::string>* mock_writes,
+                   std::vector<net::MockWrite>* writes_list) {
+    EXPECT_LT(0u, effective_connection_types.size());
+    EXPECT_TRUE(reads_list->empty());
+    EXPECT_TRUE(mock_writes->empty());
+    EXPECT_TRUE(writes_list->empty());
+
+    for (size_t i = 0; i < effective_connection_types.size(); ++i) {
+      reads_list->push_back(net::MockRead(response_headers.c_str()));
+      reads_list->push_back(net::MockRead(response_body.c_str()));
+    }
+    reads_list->push_back(net::MockRead(net::SYNCHRONOUS, net::OK));
+
+    std::string prefix = std::string("GET ")
+                             .append(kTestURL)
+                             .append(" HTTP/1.1\r\n")
+                             .append("Host: ")
+                             .append(GURL(kTestURL).host())
+                             .append(
+                                 "\r\n"
+                                 "Proxy-Connection: keep-alive\r\n"
+                                 "User-Agent:\r\n"
+                                 "Accept-Encoding: gzip, deflate\r\n"
+                                 "Accept-Language: en-us,fr\r\n");
+
+    if (io_data()->test_request_options()->GetHeaderValueForTesting().empty()) {
+      // Force regeneration of Chrome-Proxy header.
+      io_data()->test_request_options()->SetSecureSession("123");
+    }
+
+    EXPECT_FALSE(
+        io_data()->test_request_options()->GetHeaderValueForTesting().empty());
+
+    std::string suffix =
+        std::string("Chrome-Proxy: ") +
+        io_data()->test_request_options()->GetHeaderValueForTesting() +
+        std::string("\r\n\r\n");
+
+    mock_socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider_);
+
+    for (net::EffectiveConnectionType effective_connection_type :
+         effective_connection_types) {
+      std::string ect_header;
+      if (expect_ect_header) {
+        ect_header = "chrome-proxy-ect: " +
+                     std::string(net::GetNameForEffectiveConnectionType(
+                         effective_connection_type)) +
+                     "\r\n";
+      }
+
+      std::string mock_write = prefix + ect_header + suffix;
+      mock_writes->push_back(mock_write);
+      writes_list->push_back(net::MockWrite(mock_writes->back().c_str()));
+    }
+
+    EXPECT_FALSE(socket_);
+    socket_ = base::MakeUnique<net::StaticSocketDataProvider>(
+        reads_list->data(), reads_list->size(), writes_list->data(),
+        writes_list->size());
+    mock_socket_factory_.AddSocketDataProvider(socket_.get());
+  }
+
   static void VerifyHeaders(bool expected_data_reduction_proxy_used,
                             bool expected_lofi_used,
                             const net::HttpRequestHeaders& headers) {
@@ -400,6 +473,10 @@
                                          "User-Agent:\r\n");
 
     std::string accept_language_header("Accept-Language: en-us,fr\r\n");
+    std::string ect_header = "chrome-proxy-ect: " +
+                             std::string(net::GetNameForEffectiveConnectionType(
+                                 net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN)) +
+                             "\r\n";
 
     // Brotli is included in accept-encoding header only if the request went
     // to the network (i.e., it was not a cached response), and if data
@@ -415,13 +492,14 @@
         std::string("\r\n\r\n");
 
     std::string mock_write = prefix_headers + accept_language_header +
-                             accept_encoding_header + suffix_headers;
+                             ect_header + accept_encoding_header +
+                             suffix_headers;
 
     if (expect_cached || !expect_brotli) {
       // Order of headers is different if the headers were modified by data
       // reduction proxy network delegate.
       mock_write = prefix_headers + accept_encoding_header +
-                   accept_language_header + suffix_headers;
+                   accept_language_header + ect_header + suffix_headers;
     }
 
     net::MockWrite writes[] = {net::MockWrite(mock_write.c_str())};
@@ -517,6 +595,7 @@
         "www.google.com\r\nProxy-Connection: "
         "keep-alive\r\nUser-Agent:\r\nAccept-Encoding: gzip, "
         "deflate\r\nAccept-Language: en-us,fr\r\n"
+        "chrome-proxy-ect: 4G\r\n"
         "Chrome-Proxy: " +
         io_data()->test_request_options()->GetHeaderValueForTesting() +
         (page_id_value.empty() ? "" : (", " + page_id_value)) + "\r\n\r\n";
@@ -550,6 +629,51 @@
     base::RunLoop().RunUntilIdle();
   }
 
+  // Fetches a request while the effective connection type is set to
+  // |effective_connection_type|. Verifies that the request headers include the
+  // chrome-proxy-ect header only if |expect_ect_header| is true. The response
+  // must be served from the cache if |expect_cached| is true.
+  void FetchURLRequestAndVerifyECTHeader(
+      net::EffectiveConnectionType effective_connection_type,
+      bool expect_ect_header,
+      bool expect_cached) {
+    test_network_quality_estimator()->set_effective_connection_type(
+        effective_connection_type);
+
+    net::TestDelegate delegate;
+    std::unique_ptr<net::URLRequest> request =
+        context_.CreateRequest(GURL(kTestURL), net::IDLE, &delegate);
+
+    request->Start();
+    base::RunLoop().RunUntilIdle();
+
+    EXPECT_EQ(140, request->received_response_content_length());
+    EXPECT_EQ(expect_cached, request->was_cached());
+    EXPECT_EQ(expect_cached, request->GetTotalSentBytes() == 0);
+    EXPECT_EQ(expect_cached, request->GetTotalReceivedBytes() == 0);
+
+    net::HttpRequestHeaders sent_request_headers;
+    EXPECT_NE(expect_cached,
+              request->GetFullRequestHeaders(&sent_request_headers));
+
+    if (expect_cached) {
+      // Request headers are missing. Return since there is nothing left to
+      // check.
+      return;
+    }
+
+    // Verify that chrome-proxy-ect header is present in the request headers
+    // only if |expect_ect_header| is true.
+    std::string ect_value;
+    EXPECT_EQ(expect_ect_header, sent_request_headers.GetHeader(
+                                     chrome_proxy_ect_header(), &ect_value));
+
+    if (!expect_ect_header)
+      return;
+    EXPECT_EQ(net::GetNameForEffectiveConnectionType(effective_connection_type),
+              ect_value);
+  }
+
   void DelegateStageDone(int result) {}
 
   void NotifyNetworkDelegate(net::URLRequest* request,
@@ -1380,6 +1504,11 @@
   net::ProxyRetryInfoMap proxy_retry_info;
 
   // Send a request and verify the page ID is 1.
+  network_delegate()->NotifyBeforeStartTransaction(
+      request.get(),
+      base::Bind(&DataReductionProxyNetworkDelegateTest::DelegateStageDone,
+                 base::Unretained(this)),
+      &headers);
   network_delegate()->NotifyBeforeSendHeaders(
       request.get(), data_reduction_proxy_info, proxy_retry_info, &headers);
   DataReductionProxyData* data =
@@ -1392,6 +1521,11 @@
                                      nullptr);
   request->SetLoadFlags(net::LOAD_MAIN_FRAME_DEPRECATED);
 
+  network_delegate()->NotifyBeforeStartTransaction(
+      request.get(),
+      base::Bind(&DataReductionProxyNetworkDelegateTest::DelegateStageDone,
+                 base::Unretained(this)),
+      &headers);
   network_delegate()->NotifyBeforeSendHeaders(
       request.get(), data_reduction_proxy_info, proxy_retry_info, &headers);
   data = DataReductionProxyData::GetData(*request.get());
@@ -1413,6 +1547,89 @@
   EXPECT_EQ(1u, data->page_id().value());
 }
 
+// Test that effective connection type is correctly added to the request
+// headers when it is enabled using field trial. The server is varying on the
+// effective connection type (ECT).
+TEST_F(DataReductionProxyNetworkDelegateTest, ECTHeaderEnabledWithVary) {
+  Init(USE_SECURE_PROXY, false /* enable_brotli_globally */);
+
+  std::string response_headers =
+      "HTTP/1.1 200 OK\r\n"
+      "Content-Length: 140\r\n"
+      "Via: 1.1 Chrome-Compression-Proxy\r\n"
+      "Cache-Control: max-age=1200\r\n"
+      "Vary: chrome-proxy-ect\r\n"
+      "x-original-content-length: 200\r\n\r\n";
+
+  int response_body_size = 140;
+  std::string response_body(base::checked_cast<size_t>(response_body_size),
+                            ' ');
+
+  std::vector<net::MockRead> reads_list;
+  std::vector<std::string> mock_writes;
+  std::vector<net::MockWrite> writes_list;
+
+  std::vector<net::EffectiveConnectionType> effective_connection_types;
+  effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
+  effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_2G);
+
+  BuildSocket(response_headers, response_body, true, effective_connection_types,
+              &reads_list, &mock_writes, &writes_list);
+
+  // Add 2 socket providers since 2 requests in this test are fetched from the
+  // network.
+  FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, false);
+
+  // When the ECT is set to the same value, fetching the same resource should
+  // result in a cache hit.
+  FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, true);
+
+  // When the ECT is set to a different value, the response should not be
+  // served from the cache.
+  FetchURLRequestAndVerifyECTHeader(effective_connection_types[1], true, false);
+}
+
+// Test that effective connection type is correctly added to the request
+// headers when it is enabled using field trial. The server is not varying on
+// the effective connection type (ECT).
+TEST_F(DataReductionProxyNetworkDelegateTest, ECTHeaderEnabledWithoutVary) {
+  Init(USE_SECURE_PROXY, false /* enable_brotli_globally */);
+
+  std::string response_headers =
+      "HTTP/1.1 200 OK\r\n"
+      "Content-Length: 140\r\n"
+      "Via: 1.1 Chrome-Compression-Proxy\r\n"
+      "Cache-Control: max-age=1200\r\n"
+      "x-original-content-length: 200\r\n\r\n";
+
+  int response_body_size = 140;
+  std::string response_body(base::checked_cast<size_t>(response_body_size),
+                            ' ');
+
+  std::vector<net::MockRead> reads_list;
+  std::vector<std::string> mock_writes;
+  std::vector<net::MockWrite> writes_list;
+
+  std::vector<net::EffectiveConnectionType> effective_connection_types;
+  effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
+  effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_2G);
+
+  BuildSocket(response_headers, response_body, true, effective_connection_types,
+              &reads_list, &mock_writes, &writes_list);
+
+  // Add 1 socket provider since 1 request in this test is fetched from the
+  // network.
+  FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, false);
+
+  // When the ECT is set to the same value, fetching the same resource should
+  // result in a cache hit.
+  FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, true);
+
+  // When the ECT is set to a different value, the response should still be
+  // served from the cache.
+  FetchURLRequestAndVerifyECTHeader(effective_connection_types[1], true, true);
+}
+
 }  // namespace
 
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
index 3a697ae..d8a0219 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
@@ -29,6 +29,7 @@
 namespace {
 
 const char kChromeProxyHeader[] = "chrome-proxy";
+const char kChromeProxyECTHeader[] = "chrome-proxy-ect";
 const char kChromeProxyAcceptTransformHeader[] =
     "chrome-proxy-accept-transform";
 const char kChromeProxyContentTransformHeader[] =
@@ -126,6 +127,10 @@
   return kChromeProxyHeader;
 }
 
+const char* chrome_proxy_ect_header() {
+  return kChromeProxyECTHeader;
+}
+
 const char* chrome_proxy_accept_transform_header() {
   return kChromeProxyAcceptTransformHeader;
 }
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
index e059d64..360914e 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
@@ -68,6 +68,10 @@
 // Gets the header used for data reduction proxy requests and responses.
 const char* chrome_proxy_header();
 
+// Gets the chrome-proxy-ect request header that includes the effective
+// connection type.
+const char* chrome_proxy_ect_header();
+
 // Gets the ChromeProxyAcceptTransform header name.
 const char* chrome_proxy_accept_transform_header();
 
diff --git a/components/display_compositor/gl_helper_unittest.cc b/components/display_compositor/gl_helper_unittest.cc
index 73a837d..0cc4c73f 100644
--- a/components/display_compositor/gl_helper_unittest.cc
+++ b/components/display_compositor/gl_helper_unittest.cc
@@ -736,7 +736,6 @@
     }
 
     // Now compare the results.
-    SkAutoLockPixels lock_input(truth_pixels);
     const std::vector<GLHelperScaling::ScalerStage> dummy_stages;
     Compare(&truth_pixels, &output_pixels, 2, input_pixels.get(), dummy_stages,
             message + " comparing against transformed/scaled");
@@ -961,8 +960,6 @@
     if (bmp1.colorType() != bmp2.colorType())
       return false;
 
-    SkAutoLockPixels lock1(bmp1);
-    SkAutoLockPixels lock2(bmp2);
     if (!bmp1.getPixels() || !bmp2.getPixels()) {
       LOG(ERROR) << "Empty Bitmap!";
       return false;
diff --git a/components/favicon_base/select_favicon_frames_unittest.cc b/components/favicon_base/select_favicon_frames_unittest.cc
index 4fe4044..f2a6f542 100644
--- a/components/favicon_base/select_favicon_frames_unittest.cc
+++ b/components/favicon_base/select_favicon_frames_unittest.cc
@@ -59,9 +59,7 @@
     x = bitmap.width() / 2;
   if (y == -1)
     y = bitmap.width() / 2;
-  bitmap.lockPixels();
   SkColor color = bitmap.getColor(x, y);
-  bitmap.unlockPixels();
   return color;
 }
 
diff --git a/components/feature_engagement_tracker/internal/BUILD.gn b/components/feature_engagement_tracker/internal/BUILD.gn
index 00badef3..ce65095 100644
--- a/components/feature_engagement_tracker/internal/BUILD.gn
+++ b/components/feature_engagement_tracker/internal/BUILD.gn
@@ -14,6 +14,8 @@
   ]
 
   sources = [
+    "chrome_variations_configuration.cc",
+    "chrome_variations_configuration.h",
     "condition_validator.h",
     "configuration.cc",
     "configuration.h",
@@ -65,6 +67,7 @@
   visibility = [ "//components/feature_engagement_tracker:unit_tests" ]
 
   sources = [
+    "chrome_variations_configuration_unittest.cc",
     "editable_configuration_unittest.cc",
     "feature_engagement_tracker_impl_unittest.cc",
     "in_memory_store_unittest.cc",
diff --git a/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc b/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc
new file mode 100644
index 0000000..e388ec2
--- /dev/null
+++ b/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc
@@ -0,0 +1,274 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/feature_engagement_tracker/internal/chrome_variations_configuration.h"
+
+#include <map>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "components/feature_engagement_tracker/internal/configuration.h"
+#include "components/feature_engagement_tracker/internal/feature_list.h"
+
+namespace {
+
+const char kComparatorTypeAny[] = "any";
+const char kComparatorTypeLessThan[] = "<";
+const char kComparatorTypeGreaterThan[] = ">";
+const char kComparatorTypeLessThanOrEqual[] = "<=";
+const char kComparatorTypeGreaterThanOrEqual[] = ">=";
+const char kComparatorTypeEqual[] = "==";
+const char kComparatorTypeNotEqual[] = "!=";
+
+const char kEventConfigUsedKey[] = "event_used";
+const char kEventConfigTriggerKey[] = "event_trigger";
+const char kEventConfigKeyPrefix[] = "event_";
+const char kSessionRateKey[] = "session_rate";
+const char kAvailabilityKey[] = "availability";
+
+const char kEventConfigDataNameKey[] = "name";
+const char kEventConfigDataComparatorKey[] = "comparator";
+const char kEventConfigDataWindowKey[] = "window";
+const char kEventConfigDataStorageKey[] = "storage";
+
+}  // namespace
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+bool ParseComparatorSubstring(base::StringPiece definition,
+                              Comparator* comparator,
+                              ComparatorType type,
+                              uint32_t type_len) {
+  base::StringPiece number_string =
+      base::TrimWhitespaceASCII(definition.substr(type_len), base::TRIM_ALL);
+  uint32_t value;
+  if (!base::StringToUint(number_string, &value))
+    return false;
+
+  comparator->type = type;
+  comparator->value = value;
+  return true;
+}
+
+bool ParseComparator(base::StringPiece definition, Comparator* comparator) {
+  if (base::LowerCaseEqualsASCII(definition, kComparatorTypeAny)) {
+    comparator->type = ANY;
+    comparator->value = 0;
+    return true;
+  }
+
+  if (base::StartsWith(definition, kComparatorTypeLessThanOrEqual,
+                       base::CompareCase::INSENSITIVE_ASCII)) {
+    return ParseComparatorSubstring(definition, comparator, LESS_THAN_OR_EQUAL,
+                                    2);
+  }
+
+  if (base::StartsWith(definition, kComparatorTypeGreaterThanOrEqual,
+                       base::CompareCase::INSENSITIVE_ASCII)) {
+    return ParseComparatorSubstring(definition, comparator,
+                                    GREATER_THAN_OR_EQUAL, 2);
+  }
+
+  if (base::StartsWith(definition, kComparatorTypeEqual,
+                       base::CompareCase::INSENSITIVE_ASCII)) {
+    return ParseComparatorSubstring(definition, comparator, EQUAL, 2);
+  }
+
+  if (base::StartsWith(definition, kComparatorTypeNotEqual,
+                       base::CompareCase::INSENSITIVE_ASCII)) {
+    return ParseComparatorSubstring(definition, comparator, NOT_EQUAL, 2);
+  }
+
+  if (base::StartsWith(definition, kComparatorTypeLessThan,
+                       base::CompareCase::INSENSITIVE_ASCII)) {
+    return ParseComparatorSubstring(definition, comparator, LESS_THAN, 1);
+  }
+
+  if (base::StartsWith(definition, kComparatorTypeGreaterThan,
+                       base::CompareCase::INSENSITIVE_ASCII)) {
+    return ParseComparatorSubstring(definition, comparator, GREATER_THAN, 1);
+  }
+
+  return false;
+}
+
+bool ParseEventConfig(base::StringPiece definition, EventConfig* event_config) {
+  // Support definitions with at least 4 tokens.
+  auto tokens = base::SplitStringPiece(definition, ";", base::TRIM_WHITESPACE,
+                                       base::SPLIT_WANT_ALL);
+  if (tokens.size() < 4) {
+    *event_config = EventConfig();
+    return false;
+  }
+
+  // Parse tokens in any order.
+  bool has_name = false;
+  bool has_comparator = false;
+  bool has_window = false;
+  bool has_storage = false;
+  for (const auto& token : tokens) {
+    auto pair = base::SplitStringPiece(token, ":", base::TRIM_WHITESPACE,
+                                       base::SPLIT_WANT_ALL);
+    if (pair.size() != 2) {
+      *event_config = EventConfig();
+      return false;
+    }
+
+    const base::StringPiece& key = pair[0];
+    const base::StringPiece& value = pair[1];
+    // TODO(nyquist): Ensure that key matches regex /^[a-zA-Z0-9-_]+$/.
+
+    if (base::LowerCaseEqualsASCII(key, kEventConfigDataNameKey)) {
+      if (has_name) {
+        *event_config = EventConfig();
+        return false;
+      }
+      has_name = true;
+
+      event_config->name = value.as_string();
+    } else if (base::LowerCaseEqualsASCII(key, kEventConfigDataComparatorKey)) {
+      if (has_comparator) {
+        *event_config = EventConfig();
+        return false;
+      }
+      has_comparator = true;
+
+      Comparator comparator;
+      if (!ParseComparator(value, &comparator)) {
+        *event_config = EventConfig();
+        return false;
+      }
+
+      event_config->comparator = comparator;
+    } else if (base::LowerCaseEqualsASCII(key, kEventConfigDataWindowKey)) {
+      if (has_window) {
+        *event_config = EventConfig();
+        return false;
+      }
+      has_window = true;
+
+      uint32_t parsed_value;
+      if (!base::StringToUint(value, &parsed_value)) {
+        *event_config = EventConfig();
+        return false;
+      }
+
+      event_config->window = parsed_value;
+    } else if (base::LowerCaseEqualsASCII(key, kEventConfigDataStorageKey)) {
+      if (has_storage) {
+        *event_config = EventConfig();
+        return false;
+      }
+      has_storage = true;
+
+      uint32_t parsed_value;
+      if (!base::StringToUint(value, &parsed_value)) {
+        *event_config = EventConfig();
+        return false;
+      }
+
+      event_config->storage = parsed_value;
+    }
+  }
+
+  return has_name && has_comparator && has_window && has_storage;
+}
+
+}  // namespace
+
+ChromeVariationsConfiguration::ChromeVariationsConfiguration() = default;
+
+ChromeVariationsConfiguration::~ChromeVariationsConfiguration() = default;
+
+void ChromeVariationsConfiguration::ParseFeatureConfigs(
+    FeatureVector features) {
+  for (auto* feature : features) {
+    ParseFeatureConfig(feature);
+  }
+}
+
+void ChromeVariationsConfiguration::ParseFeatureConfig(
+    const base::Feature* feature) {
+  DCHECK(feature);
+  DCHECK(configs_.find(feature) == configs_.end());
+
+  // Initially all new configurations are considered invalid.
+  FeatureConfig& config = configs_[feature];
+  config.valid = false;
+  uint32_t parse_errors = 0;
+
+  std::map<std::string, std::string> params;
+  bool result = base::GetFieldTrialParamsByFeature(*feature, &params);
+  if (!result)
+    return;
+
+  for (const auto& it : params) {
+    const std::string& key = it.first;
+    if (key == kEventConfigUsedKey) {
+      EventConfig event_config;
+      if (!ParseEventConfig(params[key], &event_config)) {
+        ++parse_errors;
+        continue;
+      }
+      config.used = event_config;
+    } else if (key == kEventConfigTriggerKey) {
+      EventConfig event_config;
+      if (!ParseEventConfig(params[key], &event_config)) {
+        ++parse_errors;
+        continue;
+      }
+      config.trigger = event_config;
+    } else if (key == kSessionRateKey) {
+      Comparator comparator;
+      if (!ParseComparator(params[key], &comparator)) {
+        ++parse_errors;
+        continue;
+      }
+      config.session_rate = comparator;
+    } else if (key == kAvailabilityKey) {
+      Comparator comparator;
+      if (!ParseComparator(params[key], &comparator)) {
+        ++parse_errors;
+        continue;
+      }
+      config.availability = comparator;
+    } else if (base::StartsWith(key, kEventConfigKeyPrefix,
+                                base::CompareCase::INSENSITIVE_ASCII)) {
+      EventConfig event_config;
+      if (!ParseEventConfig(params[key], &event_config)) {
+        ++parse_errors;
+        continue;
+      }
+      config.event_configs.insert(event_config);
+    } else {
+      DVLOG(1) << "Ignoring unknown key when parsing config for feature "
+               << feature->name << ": " << key;
+    }
+  }
+
+  // The |used| and |trigger| members are required, so should not be the
+  // default values.
+  config.valid = config.used != EventConfig() &&
+                 config.trigger != EventConfig() && parse_errors == 0;
+}
+
+const FeatureConfig& ChromeVariationsConfiguration::GetFeatureConfig(
+    const base::Feature& feature) const {
+  auto it = configs_.find(&feature);
+  DCHECK(it != configs_.end());
+  return it->second;
+}
+
+}  // namespace feature_engagement_tracker
diff --git a/components/feature_engagement_tracker/internal/chrome_variations_configuration.h b/components/feature_engagement_tracker/internal/chrome_variations_configuration.h
new file mode 100644
index 0000000..e140d13f
--- /dev/null
+++ b/components/feature_engagement_tracker/internal/chrome_variations_configuration.h
@@ -0,0 +1,45 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_CHROME_VARIATIONS_CONFIGURATION_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_CHROME_VARIATIONS_CONFIGURATION_H_
+
+#include "base/macros.h"
+#include "components/feature_engagement_tracker/internal/configuration.h"
+#include "components/feature_engagement_tracker/internal/feature_list.h"
+
+namespace base {
+struct Feature;
+}  // namespace base
+
+namespace feature_engagement_tracker {
+
+// A ChromeVariationsConfiguration provides a configuration that is parsed from
+// Chrome variations feature params. It is required to call
+// ParseFeatureConfigs(...) with all the features that should be parsed.
+class ChromeVariationsConfiguration : public Configuration {
+ public:
+  ChromeVariationsConfiguration();
+  ~ChromeVariationsConfiguration() override;
+
+  // Configuration implementation.
+  const FeatureConfig& GetFeatureConfig(
+      const base::Feature& feature) const override;
+
+  // Parses the variations configuration for all of the given |features| and
+  // stores the result. It is only valid to call ParseFeatureConfig once.
+  void ParseFeatureConfigs(FeatureVector features);
+
+ private:
+  void ParseFeatureConfig(const base::Feature* feature);
+
+  // The current configurations.
+  ConfigMap configs_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeVariationsConfiguration);
+};
+
+}  // namespace feature_engagement_tracker
+
+#endif  // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_CHROME_VARIATIONS_CONFIGURATION_H_
diff --git a/components/feature_engagement_tracker/internal/chrome_variations_configuration_unittest.cc b/components/feature_engagement_tracker/internal/chrome_variations_configuration_unittest.cc
new file mode 100644
index 0000000..8676b6b
--- /dev/null
+++ b/components/feature_engagement_tracker/internal/chrome_variations_configuration_unittest.cc
@@ -0,0 +1,541 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/feature_engagement_tracker/internal/chrome_variations_configuration.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/feature_list.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/field_trial_param_associator.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/test/scoped_feature_list.h"
+#include "components/feature_engagement_tracker/internal/configuration.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+const base::Feature kTestFeatureFoo{"test_foo",
+                                    base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTestFeatureBar{"test_bar",
+                                    base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTestFeatureQux{"test_qux",
+                                    base::FEATURE_DISABLED_BY_DEFAULT};
+
+const char kFooTrialName[] = "FooTrial";
+const char kBarTrialName[] = "BarTrial";
+const char kQuxTrialName[] = "QuxTrial";
+const char kGroupName[] = "Group1";
+
+class ChromeVariationsConfigurationTest : public ::testing::Test {
+ public:
+  ChromeVariationsConfigurationTest() : field_trials_(nullptr) {
+    base::FieldTrial* foo_trial =
+        base::FieldTrialList::CreateFieldTrial(kFooTrialName, kGroupName);
+    base::FieldTrial* bar_trial =
+        base::FieldTrialList::CreateFieldTrial(kBarTrialName, kGroupName);
+    base::FieldTrial* qux_trial =
+        base::FieldTrialList::CreateFieldTrial(kQuxTrialName, kGroupName);
+    trials_[&kTestFeatureFoo] = foo_trial;
+    trials_[&kTestFeatureBar] = bar_trial;
+    trials_[&kTestFeatureQux] = qux_trial;
+
+    std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
+    feature_list->RegisterFieldTrialOverride(
+        kTestFeatureFoo.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
+        foo_trial);
+    feature_list->RegisterFieldTrialOverride(
+        kTestFeatureBar.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
+        bar_trial);
+    feature_list->RegisterFieldTrialOverride(
+        kTestFeatureQux.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
+        qux_trial);
+
+    scoped_feature_list.InitWithFeatureList(std::move(feature_list));
+    EXPECT_EQ(foo_trial, base::FeatureList::GetFieldTrial(kTestFeatureFoo));
+    EXPECT_EQ(bar_trial, base::FeatureList::GetFieldTrial(kTestFeatureBar));
+    EXPECT_EQ(qux_trial, base::FeatureList::GetFieldTrial(kTestFeatureQux));
+  }
+
+  void TearDown() override {
+    // This is required to ensure each test can define its own params.
+    base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
+  }
+
+ protected:
+  void SetFeatureParams(const base::Feature& feature,
+                        std::map<std::string, std::string> params) {
+    ASSERT_TRUE(base::FieldTrialParamAssociator::GetInstance()
+                    ->AssociateFieldTrialParams(trials_[&feature]->trial_name(),
+                                                kGroupName, params));
+
+    std::map<std::string, std::string> actualParams;
+    EXPECT_TRUE(base::GetFieldTrialParamsByFeature(feature, &actualParams));
+    EXPECT_EQ(params, actualParams);
+  }
+
+  void VerifyInvalid(const std::string& event_config) {
+    std::map<std::string, std::string> foo_params;
+    foo_params["event_used"] = "name:u;comparator:any;window:0;storage:1";
+    foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+    foo_params["event_0"] = event_config;
+    SetFeatureParams(kTestFeatureFoo, foo_params);
+
+    std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+    configuration_.ParseFeatureConfigs(features);
+
+    FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+    EXPECT_FALSE(foo.valid);
+  }
+
+  ChromeVariationsConfiguration configuration_;
+
+ private:
+  base::FieldTrialList field_trials_;
+  std::map<const base::Feature*, base::FieldTrial*> trials_;
+  base::test::ScopedFeatureList scoped_feature_list;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeVariationsConfigurationTest);
+};
+
+}  // namespace
+
+TEST_F(ChromeVariationsConfigurationTest,
+       DisabledFeatureShouldHaveInvalidConfig) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitWithFeatures({}, {kTestFeatureFoo});
+
+  FeatureVector features;
+  features.push_back(&kTestFeatureFoo);
+
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo_config = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_FALSE(foo_config.valid);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, ParseSingleFeature) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] =
+      "name:page_download_started;comparator:any;window:0;storage:360";
+  foo_params["event_trigger"] =
+      "name:opened_chrome_home;comparator:any;window:0;storage:360";
+  foo_params["event_1"] =
+      "name:user_has_seen_dino;comparator:>=1;window:120;storage:180";
+  foo_params["event_2"] =
+      "name:user_opened_app_menu;comparator:<=0;window:120;storage:180";
+  foo_params["event_3"] =
+      "name:user_opened_downloads_home;comparator:any;window:0;storage:360";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_TRUE(foo.valid);
+
+  FeatureConfig expected_foo;
+  expected_foo.valid = true;
+  expected_foo.used =
+      EventConfig("page_download_started", Comparator(ANY, 0), 0, 360);
+  expected_foo.trigger =
+      EventConfig("opened_chrome_home", Comparator(ANY, 0), 0, 360);
+  expected_foo.event_configs.insert(EventConfig(
+      "user_has_seen_dino", Comparator(GREATER_THAN_OR_EQUAL, 1), 120, 180));
+  expected_foo.event_configs.insert(EventConfig(
+      "user_opened_app_menu", Comparator(LESS_THAN_OR_EQUAL, 0), 120, 180));
+  expected_foo.event_configs.insert(
+      EventConfig("user_opened_downloads_home", Comparator(ANY, 0), 0, 360));
+  EXPECT_EQ(expected_foo, foo);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, MissingUsedIsInvalid) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_FALSE(foo.valid);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, MissingTriggerIsInvalid) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_FALSE(foo.valid);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, OnlyTriggerAndUsedIsValid) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
+  foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_TRUE(foo.valid);
+
+  FeatureConfig expected_foo;
+  expected_foo.valid = true;
+  expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
+  expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
+  EXPECT_EQ(expected_foo, foo);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, WhitespaceIsValid) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] =
+      " name : eu ; comparator : any ; window : 1 ; storage : 320 ";
+  foo_params["event_trigger"] =
+      " name:et;comparator : any ;window: 2;storage:330 ";
+  foo_params["event_0"] = "name:e0;comparator: <1 ;window:3\n;storage:340";
+  foo_params["event_1"] = "name:e1;comparator:  > 2 ;window:4;\rstorage:350";
+  foo_params["event_2"] = "name:e2;comparator: <= 3 ;window:5;\tstorage:360";
+  foo_params["event_3"] = "name:e3;comparator: <\n4 ;window:6;storage:370";
+  foo_params["event_4"] = "name:e4;comparator:  >\t5 ;window:7;storage:380";
+  foo_params["event_5"] = "name:e5;comparator: <=\r6 ;window:8;storage:390";
+  foo_params["event_6"] = "name:e6;comparator:\n<=7;window:9;storage:400";
+  foo_params["event_7"] = "name:e7;comparator:<=8\n;window:10;storage:410";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_TRUE(foo.valid);
+
+  FeatureConfig expected_foo;
+  expected_foo.valid = true;
+  expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 1, 320);
+  expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 2, 330);
+  expected_foo.event_configs.insert(
+      EventConfig("e0", Comparator(LESS_THAN, 1), 3, 340));
+  expected_foo.event_configs.insert(
+      EventConfig("e1", Comparator(GREATER_THAN, 2), 4, 350));
+  expected_foo.event_configs.insert(
+      EventConfig("e2", Comparator(LESS_THAN_OR_EQUAL, 3), 5, 360));
+  expected_foo.event_configs.insert(
+      EventConfig("e3", Comparator(LESS_THAN, 4), 6, 370));
+  expected_foo.event_configs.insert(
+      EventConfig("e4", Comparator(GREATER_THAN, 5), 7, 380));
+  expected_foo.event_configs.insert(
+      EventConfig("e5", Comparator(LESS_THAN_OR_EQUAL, 6), 8, 390));
+  expected_foo.event_configs.insert(
+      EventConfig("e6", Comparator(LESS_THAN_OR_EQUAL, 7), 9, 400));
+  expected_foo.event_configs.insert(
+      EventConfig("e7", Comparator(LESS_THAN_OR_EQUAL, 8), 10, 410));
+  EXPECT_EQ(expected_foo, foo);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, IgnoresInvalidConfigKeys) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
+  foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+  foo_params["not_there_yet"] = "bogus value";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_TRUE(foo.valid);
+
+  FeatureConfig expected_foo;
+  expected_foo.valid = true;
+  expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
+  expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
+  EXPECT_EQ(expected_foo, foo);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, IgnoresInvalidEventConfigTokens) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] =
+      "name:eu;comparator:any;window:0;storage:360;somethingelse:1";
+  foo_params["event_trigger"] =
+      "yesway:0;noway:1;name:et;comparator:any;window:0;storage:360";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_TRUE(foo.valid);
+
+  FeatureConfig expected_foo;
+  expected_foo.valid = true;
+  expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
+  expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
+  EXPECT_EQ(expected_foo, foo);
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+       MissingAllEventConfigParamsIsInvalid) {
+  VerifyInvalid("a:1;b:2;c:3;d:4");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+       MissingEventEventConfigParamIsInvalid) {
+  VerifyInvalid("foobar:eu;comparator:any;window:1;storage:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+       MissingComparatorEventConfigParamIsInvalid) {
+  VerifyInvalid("name:eu;foobar:any;window:1;storage:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+       MissingWindowEventConfigParamIsInvalid) {
+  VerifyInvalid("name:eu;comparator:any;foobar:1;storage:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+       MissingStorageEventConfigParamIsInvalid) {
+  VerifyInvalid("name:eu;comparator:any;window:1;foobar:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+       EventSpecifiedMultipleTimesIsInvalid) {
+  VerifyInvalid("name:eu;name:eu;comparator:any;window:1;storage:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+       ComparatorSpecifiedMultipleTimesIsInvalid) {
+  VerifyInvalid("name:eu;comparator:any;comparator:any;window:1;storage:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+       WindowSpecifiedMultipleTimesIsInvalid) {
+  VerifyInvalid("name:eu;comparator:any;window:1;window:2;storage:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+       StorageSpecifiedMultipleTimesIsInvalid) {
+  VerifyInvalid("name:eu;comparator:any;window:1;storage:360;storage:10");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+       InvalidSessionRateCausesInvalidConfig) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] = "name:eu;comparator:any;window:1;storage:360";
+  foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+  foo_params["session_rate"] = "bogus value";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_FALSE(foo.valid);
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+       InvalidAvailabilityCausesInvalidConfig) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
+  foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+  foo_params["availability"] = "bogus value";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_FALSE(foo.valid);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, InvalidUsedCausesInvalidConfig) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] = "bogus value";
+  foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_FALSE(foo.valid);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, InvalidTriggerCausesInvalidConfig) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
+  foo_params["event_trigger"] = "bogus value";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_FALSE(foo.valid);
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+       InvalidEventConfigCausesInvalidConfig) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
+  foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+  foo_params["event_used_0"] = "bogus value";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_FALSE(foo.valid);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, AllComparatorTypesWork) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] = "name:e0;comparator:any;window:20;storage:30";
+  foo_params["event_trigger"] = "name:e1;comparator:<1;window:21;storage:31";
+  foo_params["event_2"] = "name:e2;comparator:>2;window:22;storage:32";
+  foo_params["event_3"] = "name:e3;comparator:<=3;window:23;storage:33";
+  foo_params["event_4"] = "name:e4;comparator:>=4;window:24;storage:34";
+  foo_params["event_5"] = "name:e5;comparator:==5;window:25;storage:35";
+  foo_params["event_6"] = "name:e6;comparator:!=6;window:26;storage:36";
+  foo_params["session_rate"] = "!=6";
+  foo_params["availability"] = ">=1";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_TRUE(foo.valid);
+
+  FeatureConfig expected_foo;
+  expected_foo.valid = true;
+  expected_foo.used = EventConfig("e0", Comparator(ANY, 0), 20, 30);
+  expected_foo.trigger = EventConfig("e1", Comparator(LESS_THAN, 1), 21, 31);
+  expected_foo.event_configs.insert(
+      EventConfig("e2", Comparator(GREATER_THAN, 2), 22, 32));
+  expected_foo.event_configs.insert(
+      EventConfig("e3", Comparator(LESS_THAN_OR_EQUAL, 3), 23, 33));
+  expected_foo.event_configs.insert(
+      EventConfig("e4", Comparator(GREATER_THAN_OR_EQUAL, 4), 24, 34));
+  expected_foo.event_configs.insert(
+      EventConfig("e5", Comparator(EQUAL, 5), 25, 35));
+  expected_foo.event_configs.insert(
+      EventConfig("e6", Comparator(NOT_EQUAL, 6), 26, 36));
+  expected_foo.session_rate = Comparator(NOT_EQUAL, 6);
+  expected_foo.availability = Comparator(GREATER_THAN_OR_EQUAL, 1);
+  EXPECT_EQ(expected_foo, foo);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, MultipleEventsWithSameName) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] = "name:foo;comparator:any;window:20;storage:30";
+  foo_params["event_trigger"] = "name:foo;comparator:<1;window:21;storage:31";
+  foo_params["event_2"] = "name:foo;comparator:>2;window:22;storage:32";
+  foo_params["event_3"] = "name:foo;comparator:<=3;window:23;storage:33";
+  foo_params["session_rate"] = "any";
+  foo_params["availability"] = ">1";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_TRUE(foo.valid);
+
+  FeatureConfig expected_foo;
+  expected_foo.valid = true;
+  expected_foo.used = EventConfig("foo", Comparator(ANY, 0), 20, 30);
+  expected_foo.trigger = EventConfig("foo", Comparator(LESS_THAN, 1), 21, 31);
+  expected_foo.event_configs.insert(
+      EventConfig("foo", Comparator(GREATER_THAN, 2), 22, 32));
+  expected_foo.event_configs.insert(
+      EventConfig("foo", Comparator(LESS_THAN_OR_EQUAL, 3), 23, 33));
+  expected_foo.session_rate = Comparator(ANY, 0);
+  expected_foo.availability = Comparator(GREATER_THAN, 1);
+  EXPECT_EQ(expected_foo, foo);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, ParseMultipleFeatures) {
+  std::map<std::string, std::string> foo_params;
+  foo_params["event_used"] =
+      "name:foo_used;comparator:any;window:20;storage:30";
+  foo_params["event_trigger"] =
+      "name:foo_trigger;comparator:<1;window:21;storage:31";
+  foo_params["session_rate"] = "==10";
+  foo_params["availability"] = "<0";
+  SetFeatureParams(kTestFeatureFoo, foo_params);
+
+  std::map<std::string, std::string> bar_params;
+  bar_params["event_used"] = "name:bar_used;comparator:ANY;window:0;storage:0";
+  SetFeatureParams(kTestFeatureBar, bar_params);
+
+  std::map<std::string, std::string> qux_params;
+  qux_params["event_used"] =
+      "name:qux_used;comparator:>=2;window:99;storage:42";
+  qux_params["event_trigger"] =
+      "name:qux_trigger;comparator:ANY;window:103;storage:104";
+  qux_params["event_0"] = "name:q0;comparator:<10;window:20;storage:30";
+  qux_params["event_1"] = "name:q1;comparator:>11;window:21;storage:31";
+  qux_params["event_2"] = "name:q2;comparator:<=12;window:22;storage:32";
+  qux_params["event_3"] = "name:q3;comparator:>=13;window:23;storage:33";
+  qux_params["event_4"] = "name:q4;comparator:==14;window:24;storage:34";
+  qux_params["event_5"] = "name:q5;comparator:!=15;window:25;storage:35";
+  qux_params["session_rate"] = "!=13";
+  qux_params["availability"] = "==0";
+  SetFeatureParams(kTestFeatureQux, qux_params);
+
+  std::vector<const base::Feature*> features = {
+      &kTestFeatureFoo, &kTestFeatureBar, &kTestFeatureQux};
+  configuration_.ParseFeatureConfigs(features);
+
+  FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+  EXPECT_TRUE(foo.valid);
+  FeatureConfig expected_foo;
+  expected_foo.valid = true;
+  expected_foo.used = EventConfig("foo_used", Comparator(ANY, 0), 20, 30);
+  expected_foo.trigger =
+      EventConfig("foo_trigger", Comparator(LESS_THAN, 1), 21, 31);
+  expected_foo.session_rate = Comparator(EQUAL, 10);
+  expected_foo.availability = Comparator(LESS_THAN, 0);
+  EXPECT_EQ(expected_foo, foo);
+
+  FeatureConfig bar = configuration_.GetFeatureConfig(kTestFeatureBar);
+  EXPECT_FALSE(bar.valid);
+
+  FeatureConfig qux = configuration_.GetFeatureConfig(kTestFeatureQux);
+  EXPECT_TRUE(qux.valid);
+  FeatureConfig expected_qux;
+  expected_qux.valid = true;
+  expected_qux.used =
+      EventConfig("qux_used", Comparator(GREATER_THAN_OR_EQUAL, 2), 99, 42);
+  expected_qux.trigger =
+      EventConfig("qux_trigger", Comparator(ANY, 0), 103, 104);
+  expected_qux.event_configs.insert(
+      EventConfig("q0", Comparator(LESS_THAN, 10), 20, 30));
+  expected_qux.event_configs.insert(
+      EventConfig("q1", Comparator(GREATER_THAN, 11), 21, 31));
+  expected_qux.event_configs.insert(
+      EventConfig("q2", Comparator(LESS_THAN_OR_EQUAL, 12), 22, 32));
+  expected_qux.event_configs.insert(
+      EventConfig("q3", Comparator(GREATER_THAN_OR_EQUAL, 13), 23, 33));
+  expected_qux.event_configs.insert(
+      EventConfig("q4", Comparator(EQUAL, 14), 24, 34));
+  expected_qux.event_configs.insert(
+      EventConfig("q5", Comparator(NOT_EQUAL, 15), 25, 35));
+  expected_qux.session_rate = Comparator(NOT_EQUAL, 13);
+  expected_qux.availability = Comparator(EQUAL, 0);
+  EXPECT_EQ(expected_qux, qux);
+}
+
+}  // namespace feature_engagement_tracker
diff --git a/components/feature_engagement_tracker/internal/configuration.cc b/components/feature_engagement_tracker/internal/configuration.cc
index 6e7b904..17d1841 100644
--- a/components/feature_engagement_tracker/internal/configuration.cc
+++ b/components/feature_engagement_tracker/internal/configuration.cc
@@ -8,13 +8,56 @@
 
 namespace feature_engagement_tracker {
 
+Comparator::Comparator() : type(ANY), value(0) {}
+
+Comparator::Comparator(ComparatorType type, uint32_t value)
+    : type(type), value(value) {}
+
+Comparator::~Comparator() = default;
+
+EventConfig::EventConfig() : window(0), storage(0) {}
+
+EventConfig::EventConfig(const std::string& name,
+                         Comparator comparator,
+                         uint32_t window,
+                         uint32_t storage)
+    : name(name), comparator(comparator), window(window), storage(storage) {}
+
+EventConfig::~EventConfig() = default;
+
 FeatureConfig::FeatureConfig() : valid(false) {}
 
+FeatureConfig::FeatureConfig(const FeatureConfig& other) = default;
+
 FeatureConfig::~FeatureConfig() = default;
 
+bool operator==(const Comparator& lhs, const Comparator& rhs) {
+  return std::tie(lhs.type, lhs.value) == std::tie(rhs.type, rhs.value);
+}
+
+bool operator<(const Comparator& lhs, const Comparator& rhs) {
+  return std::tie(lhs.type, lhs.value) < std::tie(rhs.type, rhs.value);
+}
+
+bool operator==(const EventConfig& lhs, const EventConfig& rhs) {
+  return std::tie(lhs.name, lhs.comparator, lhs.window, lhs.storage) ==
+         std::tie(rhs.name, rhs.comparator, rhs.window, rhs.storage);
+}
+
+bool operator!=(const EventConfig& lhs, const EventConfig& rhs) {
+  return !(lhs == rhs);
+}
+
+bool operator<(const EventConfig& lhs, const EventConfig& rhs) {
+  return std::tie(lhs.name, lhs.comparator, lhs.window, lhs.storage) <
+         std::tie(rhs.name, rhs.comparator, rhs.window, rhs.storage);
+}
+
 bool operator==(const FeatureConfig& lhs, const FeatureConfig& rhs) {
-  return lhs.valid == rhs.valid &&
-         lhs.feature_used_event == rhs.feature_used_event;
+  return std::tie(lhs.valid, lhs.used, lhs.trigger, lhs.event_configs,
+                  lhs.session_rate, lhs.availability) ==
+         std::tie(rhs.valid, rhs.used, rhs.trigger, rhs.event_configs,
+                  rhs.session_rate, rhs.availability);
 }
 
 }  // namespace feature_engagement_tracker
diff --git a/components/feature_engagement_tracker/internal/configuration.h b/components/feature_engagement_tracker/internal/configuration.h
index 2e470cb7..f4e285a 100644
--- a/components/feature_engagement_tracker/internal/configuration.h
+++ b/components/feature_engagement_tracker/internal/configuration.h
@@ -6,7 +6,9 @@
 #define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_CONFIGURATION_H_
 
 #include <map>
+#include <set>
 #include <string>
+#include <vector>
 
 #include "base/macros.h"
 
@@ -16,28 +18,99 @@
 
 namespace feature_engagement_tracker {
 
+// A ComparatorType describes the relationship between two numbers.
+enum ComparatorType {
+  ANY = 0,  // Will always yield true.
+  LESS_THAN = 1,
+  GREATER_THAN = 2,
+  LESS_THAN_OR_EQUAL = 3,
+  GREATER_THAN_OR_EQUAL = 4,
+  EQUAL = 5,
+  NOT_EQUAL = 6,
+};
+
+// A Comparator provides a way of comparing a uint32_t another uint32_t and
+// verifying their relationship.
+struct Comparator {
+ public:
+  Comparator();
+  Comparator(ComparatorType type, uint32_t value);
+  ~Comparator();
+
+  ComparatorType type;
+  uint32_t value;
+};
+
+bool operator==(const Comparator& lhs, const Comparator& rhs);
+bool operator<(const Comparator& lhs, const Comparator& rhs);
+
+// A EventConfig contains all the information about how many times
+// a particular event should or should not have triggered, for which window
+// to search in and for how long to store it.
+struct EventConfig {
+ public:
+  EventConfig();
+  EventConfig(const std::string& name,
+              Comparator comparator,
+              uint32_t window,
+              uint32_t storage);
+  ~EventConfig();
+
+  // The identifier of the event.
+  std::string name;
+
+  // The number of events it is required to find within the search window.
+  Comparator comparator;
+
+  // Search for this event within this window.
+  uint32_t window;
+
+  // Store client side data related to events for this minimum this long.
+  uint32_t storage;
+};
+
+bool operator==(const EventConfig& lhs, const EventConfig& rhs);
+bool operator!=(const EventConfig& lhs, const EventConfig& rhs);
+bool operator<(const EventConfig& lhs, const EventConfig& rhs);
+
 // A FeatureConfig contains all the configuration for a given feature.
 struct FeatureConfig {
  public:
   FeatureConfig();
+  FeatureConfig(const FeatureConfig& other);
   ~FeatureConfig();
 
   // Whether the configuration has been successfully parsed.
   bool valid;
 
-  // The identifier for a particular event that will be searched for when
+  // The configuration for a particular event that will be searched for when
   // counting how many times a particular feature has been used.
-  std::string feature_used_event;
+  EventConfig used;
+
+  // The configuration for a particular event that will be searched for when
+  // counting how many times in-product help has been triggered for a particular
+  // feature.
+  EventConfig trigger;
+
+  // A set of all event configurations.
+  std::set<EventConfig> event_configs;
+
+  // Number of in-product help triggered within this session must fit this
+  // comparison.
+  Comparator session_rate;
+
+  // Number of days the in-product help has been available must fit this
+  // comparison.
+  Comparator availability;
 };
 
 bool operator==(const FeatureConfig& lhs, const FeatureConfig& rhs);
-
 // A Configuration contains the current set of runtime configurations.
 // It is up to each implementation of Configuration to provide a way to
 // register features and their configurations.
 class Configuration {
  public:
-  // Convenience alias for typical implementatinos of Configuration.
+  // Convenience alias for typical implementations of Configuration.
   using ConfigMap = std::map<const base::Feature*, FeatureConfig>;
 
   virtual ~Configuration() = default;
diff --git a/components/feature_engagement_tracker/internal/editable_configuration_unittest.cc b/components/feature_engagement_tracker/internal/editable_configuration_unittest.cc
index 896e0381..da2c6e2 100644
--- a/components/feature_engagement_tracker/internal/editable_configuration_unittest.cc
+++ b/components/feature_engagement_tracker/internal/editable_configuration_unittest.cc
@@ -27,7 +27,7 @@
                                     bool valid) {
     FeatureConfig feature_config;
     feature_config.valid = valid;
-    feature_config.feature_used_event = feature_used_event;
+    feature_config.used.name = feature_used_event;
     return feature_config;
   }
 
diff --git a/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc b/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc
index daa58c3..c410c0da 100644
--- a/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc
+++ b/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc
@@ -32,7 +32,7 @@
                            bool valid) {
   FeatureConfig config;
   config.valid = valid;
-  config.feature_used_event = feature.name;
+  config.used.name = feature.name;
   configuration->SetConfiguration(&feature, config);
 }
 
diff --git a/components/feature_engagement_tracker/internal/model_impl_unittest.cc b/components/feature_engagement_tracker/internal/model_impl_unittest.cc
index ef57d2a..070b52d 100644
--- a/components/feature_engagement_tracker/internal/model_impl_unittest.cc
+++ b/components/feature_engagement_tracker/internal/model_impl_unittest.cc
@@ -32,7 +32,7 @@
                            bool valid) {
   FeatureConfig config;
   config.valid = valid;
-  config.feature_used_event = feature.name;
+  config.used.name = feature.name;
   configuration->SetConfiguration(&feature, config);
 }
 
diff --git a/components/feature_engagement_tracker/internal/never_condition_validator_unittest.cc b/components/feature_engagement_tracker/internal/never_condition_validator_unittest.cc
index d39f122..bb437d7 100644
--- a/components/feature_engagement_tracker/internal/never_condition_validator_unittest.cc
+++ b/components/feature_engagement_tracker/internal/never_condition_validator_unittest.cc
@@ -25,7 +25,7 @@
  public:
   TestModel() {
     feature_config_.valid = true;
-    feature_config_.feature_used_event = "foobar";
+    feature_config_.used.name = "foobar";
   }
 
   void Initialize(const OnModelInitializationFinished& callback) override {}
diff --git a/components/feature_engagement_tracker/internal/single_invalid_configuration.cc b/components/feature_engagement_tracker/internal/single_invalid_configuration.cc
index ed20e661..ad8d956 100644
--- a/components/feature_engagement_tracker/internal/single_invalid_configuration.cc
+++ b/components/feature_engagement_tracker/internal/single_invalid_configuration.cc
@@ -10,7 +10,7 @@
 
 SingleInvalidConfiguration::SingleInvalidConfiguration() {
   invalid_feature_config_.valid = false;
-  invalid_feature_config_.feature_used_event = "nothing_to_see_here";
+  invalid_feature_config_.used.name = "nothing_to_see_here";
 };
 
 SingleInvalidConfiguration::~SingleInvalidConfiguration() = default;
diff --git a/components/history/core/browser/history_backend_unittest.cc b/components/history/core/browser/history_backend_unittest.cc
index 16455290..f1b00e3 100644
--- a/components/history/core/browser/history_backend_unittest.cc
+++ b/components/history/core/browser/history_backend_unittest.cc
@@ -485,7 +485,6 @@
     if (!gfx::PNGCodec::Decode(bitmap_data->front(), bitmap_data->size(),
                                &bitmap))
       return false;
-    SkAutoLockPixels bitmap_lock(bitmap);
     return expected_color == bitmap.getColor(0, 0);
   }
 
diff --git a/components/suggestions/image_encoder.cc b/components/suggestions/image_encoder.cc
index 73283cf5..8b0fa09 100644
--- a/components/suggestions/image_encoder.cc
+++ b/components/suggestions/image_encoder.cc
@@ -17,7 +17,6 @@
 
 bool EncodeSkBitmapToJPEG(const SkBitmap& bitmap,
                           std::vector<unsigned char>* dest) {
-  SkAutoLockPixels bitmap_lock(bitmap);
   if (!bitmap.readyToDraw() || bitmap.isNull()) {
     return false;
   }
diff --git a/components/sync/driver/generic_change_processor.cc b/components/sync/driver/generic_change_processor.cc
index 1dee59f..54ab6b26 100644
--- a/components/sync/driver/generic_change_processor.cc
+++ b/components/sync/driver/generic_change_processor.cc
@@ -277,10 +277,10 @@
   std::vector<int64_t> child_ids;
   root.GetChildIds(&child_ids);
 
-  for (std::vector<int64_t>::iterator it = child_ids.begin();
-       it != child_ids.end(); ++it) {
+  current_sync_data->reserve(current_sync_data->size() + child_ids.size());
+  for (int64_t child_id : child_ids) {
     ReadNode sync_child_node(&trans);
-    if (sync_child_node.InitByIdLookup(*it) != BaseNode::INIT_OK) {
+    if (sync_child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK) {
       SyncError error(FROM_HERE, SyncError::DATATYPE_ERROR,
                       "Failed to fetch child node for type " + type_name + ".",
                       type_);
diff --git a/components/sync/syncable/directory.cc b/components/sync/syncable/directory.cc
index 981e2e4..93732b5 100644
--- a/components/sync/syncable/directory.cc
+++ b/components/sync/syncable/directory.cc
@@ -1560,9 +1560,9 @@
   if (!children)
     return;
 
-  for (OrderedChildSet::const_iterator i = children->begin();
-       i != children->end(); ++i) {
-    result->push_back((*i)->ref(META_HANDLE));
+  result->reserve(result->size() + children->size());
+  for (const EntryKernel* entry : *children) {
+    result->push_back(entry->ref(META_HANDLE));
   }
 }
 
diff --git a/components/user_manager/user_image/user_image.cc b/components/user_manager/user_image/user_image.cc
index 23c763f..db293d5 100644
--- a/components/user_manager/user_image/user_image.cc
+++ b/components/user_manager/user_image/user_image.cc
@@ -26,7 +26,6 @@
     ImageFormat image_format) {
   TRACE_EVENT2("oobe", "UserImage::Encode",
                "width", bitmap.width(), "height", bitmap.height());
-  SkAutoLockPixels lock_bitmap(bitmap);
   std::vector<unsigned char> output;
   auto* bitmap_data = reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0));
   if (image_format == FORMAT_JPEG) {
diff --git a/components/user_manager/user_manager_base.cc b/components/user_manager/user_manager_base.cc
index 182024c..00d6b5bf 100644
--- a/components/user_manager/user_manager_base.cc
+++ b/components/user_manager/user_manager_base.cc
@@ -294,8 +294,8 @@
                                                  RemoveUserDelegate* delegate) {
   if (delegate)
     delegate->OnBeforeUserRemoved(account_id);
-  RemoveUserFromList(account_id);
   AsyncRemoveCryptohome(account_id);
+  RemoveUserFromList(account_id);
 
   if (delegate)
     delegate->OnUserRemoved(account_id);
diff --git a/components/wallpaper/wallpaper_manager_base.cc b/components/wallpaper/wallpaper_manager_base.cc
index 188580d..5edfbc5c 100644
--- a/components/wallpaper/wallpaper_manager_base.cc
+++ b/components/wallpaper/wallpaper_manager_base.cc
@@ -431,7 +431,6 @@
       gfx::Size(resized_width, resized_height));
 
   SkBitmap bitmap = *(resized_image.bitmap());
-  SkAutoLockPixels lock_input(bitmap);
   gfx::JPEGCodec::Encode(
       reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
       gfx::JPEGCodec::FORMAT_SkBitmap, bitmap.width(), bitmap.height(),
diff --git a/components/wallpaper/wallpaper_resizer_unittest.cc b/components/wallpaper/wallpaper_resizer_unittest.cc
index fadf11c..553f54d 100644
--- a/components/wallpaper/wallpaper_resizer_unittest.cc
+++ b/components/wallpaper/wallpaper_resizer_unittest.cc
@@ -50,9 +50,7 @@
 bool IsColor(const gfx::ImageSkia& image, const uint32_t expect) {
   EXPECT_EQ(image.width(), kTargetWidth);
   EXPECT_EQ(image.height(), kTargetHeight);
-  const SkBitmap* image_bitmap = image.bitmap();
-  SkAutoLockPixels image_lock(*image_bitmap);
-  return *image_bitmap->getAddr32(0, 0) == expect;
+  return *image.bitmap()->getAddr32(0, 0) == expect;
 }
 
 }  // namespace
diff --git a/content/browser/compositor/surface_utils.cc b/content/browser/compositor/surface_utils.cc
index f741a4c1..673a9d39 100644
--- a/content/browser/compositor/surface_utils.cc
+++ b/content/browser/compositor/surface_utils.cc
@@ -33,10 +33,7 @@
     const content::ReadbackRequestCallback& callback,
     std::unique_ptr<cc::SingleReleaseCallback> release_callback,
     std::unique_ptr<SkBitmap> bitmap,
-    std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock,
     bool result) {
-  bitmap_pixels_lock.reset();
-
   gpu::SyncToken sync_token;
   if (result) {
     display_compositor::GLHelper* gl_helper =
@@ -88,8 +85,6 @@
   if (!gl_helper)
     return;
 
-  std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock(
-      new SkAutoLockPixels(*bitmap));
   uint8_t* pixels = static_cast<uint8_t*>(bitmap->getPixels());
 
   cc::TextureMailbox texture_mailbox;
@@ -103,8 +98,7 @@
       texture_mailbox.mailbox(), texture_mailbox.sync_token(), result->size(),
       gfx::Rect(result->size()), dst_size_in_pixel, pixels, color_type,
       base::Bind(&CopyFromCompositingSurfaceFinished, callback,
-                 base::Passed(&release_callback), base::Passed(&bitmap),
-                 base::Passed(&bitmap_pixels_lock)),
+                 base::Passed(&release_callback), base::Passed(&bitmap)),
       display_compositor::GLHelper::SCALER_QUALITY_GOOD);
 #endif
 }
diff --git a/content/browser/devtools/devtools_frame_trace_recorder.cc b/content/browser/devtools/devtools_frame_trace_recorder.cc
index d0977b7..06b3dc07 100644
--- a/content/browser/devtools/devtools_frame_trace_recorder.cc
+++ b/content/browser/devtools/devtools_frame_trace_recorder.cc
@@ -40,7 +40,6 @@
     out->append("\"");
     if (!frame_.drawsNothing()) {
       std::vector<unsigned char> data;
-      SkAutoLockPixels lock_image(frame_);
       bool encoded = gfx::JPEGCodec::Encode(
           reinterpret_cast<unsigned char*>(frame_.getAddr32(0, 0)),
           gfx::JPEGCodec::FORMAT_SkBitmap,
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
index 1152b669..0e41996 100644
--- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
+++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -579,9 +579,6 @@
     return false;
   }
 
-  SkAutoLockPixels lock_actual_bmp(actual_bmp);
-  SkAutoLockPixels lock_expected_bmp(expected_bmp);
-
   DCHECK(gfx::SkIRectToRect(actual_bmp.bounds()).Contains(matching_mask));
 
   for (int x = matching_mask.x(); x < matching_mask.right(); ++x) {
diff --git a/content/browser/devtools/protocol/schema_handler.cc b/content/browser/devtools/protocol/schema_handler.cc
index 6cf5b21d..f4f862c 100644
--- a/content/browser/devtools/protocol/schema_handler.cc
+++ b/content/browser/devtools/protocol/schema_handler.cc
@@ -22,14 +22,37 @@
     std::unique_ptr<protocol::Array<Schema::Domain>>* domains) {
   // TODO(kozyatisnkiy): get this from the target instead of hardcoding a list.
   static const char kVersion[] = "1.2";
-  static const char* kDomains[] = {
-    "Inspector", "Memory", "Page", "Rendering", "Emulation", "Security",
-    "Network", "Database", "IndexedDB", "CacheStorage", "DOMStorage", "CSS",
-    "ApplicationCache", "DOM", "IO", "DOMDebugger", "ServiceWorker",
-    "Input", "LayerTree", "DeviceOrientation", "Tracing", "Animation",
-    "Accessibility", "Storage", "Log", "Runtime", "Debugger",
-    "Profiler", "HeapProfiler", "Schema", "Target"
-  };
+  static const char* kDomains[] = {"Inspector",
+                                   "Memory",
+                                   "Page",
+                                   "Emulation",
+                                   "Security",
+                                   "Network",
+                                   "Database",
+                                   "IndexedDB",
+                                   "CacheStorage",
+                                   "DOMStorage",
+                                   "CSS",
+                                   "ApplicationCache",
+                                   "DOM",
+                                   "IO",
+                                   "DOMDebugger",
+                                   "ServiceWorker",
+                                   "Input",
+                                   "LayerTree",
+                                   "DeviceOrientation",
+                                   "Tracing",
+                                   "Animation",
+                                   "Accessibility",
+                                   "Storage",
+                                   "Log",
+                                   "Runtime",
+                                   "Debugger",
+                                   "Profiler",
+                                   "HeapProfiler",
+                                   "Schema",
+                                   "Target",
+                                   "Overlay"};
   *domains = protocol::Array<Schema::Domain>::create();
   for (size_t i = 0; i < arraysize(kDomains); ++i) {
     (*domains)->addItem(Schema::Domain::Create()
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc
index 0f5e006..6d478e4f 100644
--- a/content/browser/frame_host/navigation_controller_impl_unittest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -76,8 +76,6 @@
       a_bitmap.height() != b_bitmap.height()) {
     return false;
   }
-  SkAutoLockPixels a_bitmap_lock(a_bitmap);
-  SkAutoLockPixels b_bitmap_lock(b_bitmap);
   return memcmp(a_bitmap.getPixels(),
                 b_bitmap.getPixels(),
                 a_bitmap.getSize()) == 0;
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc
index bfd807a..5e16a9328 100644
--- a/content/browser/loader/navigation_url_loader_network_service.cc
+++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -34,8 +34,6 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // TODO(scottmg): Maybe some of this setup should be done only once, instead
   // of every time.
-  url_loader_factory_request_ = mojo::MakeRequest(&url_loader_factory_);
-
   ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
       mojom::kNetworkServiceName, &url_loader_factory_);
 
@@ -113,6 +111,11 @@
 }
 
 void NavigationURLLoaderNetworkService::OnComplete(
-    const ResourceRequestCompletionStatus& completion_status) {}
+    const ResourceRequestCompletionStatus& completion_status) {
+  if (completion_status.error_code != net::OK) {
+    delegate_->OnRequestFailed(completion_status.exists_in_cache,
+                               completion_status.error_code);
+  }
+}
 
 }  // namespace content
diff --git a/content/browser/loader/navigation_url_loader_network_service.h b/content/browser/loader/navigation_url_loader_network_service.h
index af7f432..bb574b1 100644
--- a/content/browser/loader/navigation_url_loader_network_service.h
+++ b/content/browser/loader/navigation_url_loader_network_service.h
@@ -64,7 +64,6 @@
 
   NavigationURLLoaderDelegate* delegate_;
 
-  mojom::URLLoaderFactoryRequest url_loader_factory_request_;
   mojom::URLLoaderFactoryPtr url_loader_factory_;
   mojo::Binding<mojom::URLLoaderClient> binding_;
   mojom::URLLoaderAssociatedPtr url_loader_associated_ptr_;
diff --git a/content/browser/media/capture/cursor_renderer.cc b/content/browser/media/capture/cursor_renderer.cc
index c92645ff..f59fc25 100644
--- a/content/browser/media/capture/cursor_renderer.cc
+++ b/content/browser/media/capture/cursor_renderer.cc
@@ -146,7 +146,6 @@
                         cursor_position_in_frame_.y()),
       target->visible_rect());
 
-  scaled_cursor_bitmap_.lockPixels();
   for (int y = rect.y(); y < rect.bottom(); ++y) {
     int cursor_y = y - cursor_position_in_frame_.y();
     uint8_t* yplane = target->data(media::VideoFrame::kYPlane) +
@@ -177,7 +176,6 @@
       }
     }
   }
-  scaled_cursor_bitmap_.unlockPixels();
 }
 
 void CursorRenderer::OnMouseMoved(const gfx::Point& location,
diff --git a/content/browser/renderer_host/clipboard_message_filter_unittest.cc b/content/browser/renderer_host/clipboard_message_filter_unittest.cc
index 89909e5..4bc506ed 100644
--- a/content/browser/renderer_host/clipboard_message_filter_unittest.cc
+++ b/content/browser/renderer_host/clipboard_message_filter_unittest.cc
@@ -103,7 +103,6 @@
       ui::Clipboard::GetBitmapFormatType(), ui::CLIPBOARD_TYPE_COPY_PASTE));
 
   SkBitmap actual = clipboard()->ReadImage(ui::CLIPBOARD_TYPE_COPY_PASTE);
-  SkAutoLockPixels locked(actual);
   EXPECT_EQ(sizeof(bitmap_data), actual.getSize());
   EXPECT_EQ(0,
             memcmp(bitmap_data, actual.getAddr32(0, 0), sizeof(bitmap_data)));
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index f572bb6..efbd3eb8 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -451,6 +451,10 @@
   GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_);
 }
 
+bool CompositorImpl::IsForSubframe() {
+  return false;
+}
+
 ui::UIResourceProvider& CompositorImpl::GetUIResourceProvider() {
   return *this;
 }
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h
index 19160a8c..6acdf23 100644
--- a/content/browser/renderer_host/compositor_impl_android.h
+++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -101,6 +101,7 @@
   void DidCommitAndDrawFrame() override {}
   void DidReceiveCompositorFrameAck() override;
   void DidCompletePageScaleAnimation() override {}
+  bool IsForSubframe() override;
 
   // LayerTreeHostSingleThreadClient implementation.
   void DidSubmitCompositorFrame() override;
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc
index 95c2da7..2db8134 100644
--- a/content/browser/renderer_host/delegated_frame_host.cc
+++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -618,13 +618,10 @@
       scaled_bitmap = *bitmap.get();
     }
 
-    {
-      SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap);
+    media::CopyRGBToVideoFrame(
+        reinterpret_cast<uint8_t*>(scaled_bitmap.getPixels()),
+        scaled_bitmap.rowBytes(), region_in_frame, video_frame.get());
 
-      media::CopyRGBToVideoFrame(
-          reinterpret_cast<uint8_t*>(scaled_bitmap.getPixels()),
-          scaled_bitmap.rowBytes(), region_in_frame, video_frame.get());
-    }
     ignore_result(scoped_callback_runner.Release());
     callback.Run(region_in_frame, true);
     return;
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index b752011..4c3471f 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -284,12 +284,10 @@
     std::unique_ptr<cc::SingleReleaseCallback> release_callback,
     std::unique_ptr<SkBitmap> bitmap,
     const base::TimeTicks& start_time,
-    std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock,
     scoped_refptr<PendingReadbackLock> readback_lock,
     bool result) {
   TRACE_EVENT0(
       "cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceFinished");
-  bitmap_pixels_lock.reset();
   gpu::SyncToken sync_token;
   if (result) {
     display_compositor::GLHelper* gl_helper = GetPostReadbackGLHelper();
@@ -383,8 +381,6 @@
     return;
   }
 
-  std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock(
-      new SkAutoLockPixels(*bitmap));
   uint8_t* pixels = static_cast<uint8_t*>(bitmap->getPixels());
 
   ignore_result(scoped_callback_runner.Release());
@@ -394,7 +390,7 @@
       gfx::Rect(result->size()), output_size_in_pixel, pixels, color_type,
       base::Bind(&CopyFromCompositingSurfaceFinished, callback,
                  base::Passed(&release_callback), base::Passed(&bitmap),
-                 start_time, base::Passed(&bitmap_pixels_lock), readback_lock),
+                 start_time, readback_lock),
       display_compositor::GLHelper::SCALER_QUALITY_GOOD);
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
index 25a2ba5a..3183991 100644
--- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -469,8 +469,6 @@
       return;
     }
 
-    SkAutoLockPixels bitmap_lock(bitmap);
-
     // Check that the |bitmap| contains cyan and/or yellow pixels.  This is
     // needed because the compositor will read back "blank" frames until the
     // first frame from the renderer is composited.  See comments in
@@ -509,7 +507,6 @@
     EXPECT_EQ(expected_bitmap.width(), bitmap.width());
     EXPECT_EQ(expected_bitmap.height(), bitmap.height());
     EXPECT_EQ(expected_bitmap.colorType(), bitmap.colorType());
-    SkAutoLockPixels expected_bitmap_lock(expected_bitmap);
     int fails = 0;
     for (int i = 0; i < bitmap.width() && fails < 10; ++i) {
       for (int j = 0; j < bitmap.height() && fails < 10; ++j) {
@@ -727,13 +724,10 @@
     // Left half is #0ff.
     bitmap->eraseARGB(255, 0, 255, 255);
     // Right half is #ff0.
-    {
-      SkAutoLockPixels lock(*bitmap);
-      for (int i = 0; i < copy_size.width() / 2; ++i) {
-        for (int j = 0; j < copy_size.height(); ++j) {
-          *(bitmap->getAddr32(copy_size.width() / 2 + i, j)) =
-              SkColorSetARGB(255, 255, 255, 0);
-        }
+    for (int i = 0; i < copy_size.width() / 2; ++i) {
+      for (int j = 0; j < copy_size.height(); ++j) {
+        *(bitmap->getAddr32(copy_size.width() / 2 + i, j)) =
+            SkColorSetARGB(255, 255, 255, 0);
       }
     }
   }
diff --git a/content/common/cursors/webcursor_unittest.cc b/content/common/cursors/webcursor_unittest.cc
index 7af1eb56..6d4afe0 100644
--- a/content/common/cursors/webcursor_unittest.cc
+++ b/content/common/cursors/webcursor_unittest.cc
@@ -222,7 +222,6 @@
   SkBitmap bitmap;
   SkPMColor testColor = SkPreMultiplyARGB(10, 255, 255, 255);
   bitmap.allocN32Pixels(1,1);
-  SkAutoLockPixels bitmap_lock(bitmap);
   *bitmap.getAddr32(0, 0) = testColor;
   CursorInfo cursor_info;
   cursor_info.type = WebCursorInfo::kTypeCustom;
@@ -233,35 +232,26 @@
   // This round trip will convert the cursor to unpremultiplied form.
   custom_cursor.InitFromCursorInfo(cursor_info);
   custom_cursor.GetCursorInfo(&cursor_info);
-  {
-    SkAutoLockPixels lock(cursor_info.custom_image);
-    EXPECT_EQ(kUnpremul_SkAlphaType, cursor_info.custom_image.alphaType());
-    EXPECT_EQ(testColor,
-              SkPreMultiplyColor(*cursor_info.custom_image.getAddr32(0,0)));
-  }
+  EXPECT_EQ(kUnpremul_SkAlphaType, cursor_info.custom_image.alphaType());
+  EXPECT_EQ(testColor,
+            SkPreMultiplyColor(*cursor_info.custom_image.getAddr32(0, 0)));
 
   // Second round trip should not do any conversion because data is already
   // unpremultiplied.
   custom_cursor.InitFromCursorInfo(cursor_info);
   custom_cursor.GetCursorInfo(&cursor_info);
-  {
-    SkAutoLockPixels lock(cursor_info.custom_image);
-    EXPECT_EQ(kUnpremul_SkAlphaType, cursor_info.custom_image.alphaType());
-    EXPECT_EQ(testColor,
-              SkPreMultiplyColor(*cursor_info.custom_image.getAddr32(0,0)));
-  }
+  EXPECT_EQ(kUnpremul_SkAlphaType, cursor_info.custom_image.alphaType());
+  EXPECT_EQ(testColor,
+            SkPreMultiplyColor(*cursor_info.custom_image.getAddr32(0, 0)));
 
 #if defined(OS_MACOSX)
   // On MacOS, test roundtrip through NSCursor conversion.
   WebCursor custom_cursor_copy;
   custom_cursor_copy.InitFromNSCursor(custom_cursor.GetNativeCursor());
   custom_cursor_copy.GetCursorInfo(&cursor_info);
-  {
-    SkAutoLockPixels lock(cursor_info.custom_image);
-    EXPECT_EQ(kUnpremul_SkAlphaType, cursor_info.custom_image.alphaType());
-    EXPECT_EQ(testColor,
-              SkPreMultiplyColor(*cursor_info.custom_image.getAddr32(0,0)));
-  }
+  EXPECT_EQ(kUnpremul_SkAlphaType, cursor_info.custom_image.alphaType());
+  EXPECT_EQ(testColor,
+            SkPreMultiplyColor(*cursor_info.custom_image.getAddr32(0, 0)));
 #endif
 }
 
diff --git a/content/common/resource_messages.cc b/content/common/resource_messages.cc
index f9fd7bb0..451eb08b 100644
--- a/content/common/resource_messages.cc
+++ b/content/common/resource_messages.cc
@@ -47,18 +47,31 @@
 }
 
 namespace {
+
 void GetCertSize(base::PickleSizer* s, net::X509Certificate* cert) {
-  base::Pickle temp;
-  cert->Persist(&temp);
-  s->AddBytes(temp.payload_size());
+  GetParamSize(s, !!cert);
+  if (cert) {
+    base::Pickle temp;
+    cert->Persist(&temp);
+    s->AddBytes(temp.payload_size());
+  }
 }
 
 void WriteCert(base::Pickle* m, net::X509Certificate* cert) {
-  cert->Persist(m);
+  WriteParam(m, !!cert);
+  if (cert)
+    cert->Persist(m);
 }
 
-bool ReadCert(base::PickleIterator* iter,
+bool ReadCert(const base::Pickle* m,
+              base::PickleIterator* iter,
               scoped_refptr<net::X509Certificate>* cert) {
+  DCHECK(!*cert);
+  bool has_object;
+  if (!ReadParam(m, iter, &has_object))
+    return false;
+  if (!has_object)
+    return true;
   *cert = net::X509Certificate::CreateFromPickle(
       iter, net::X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V3);
   return !!cert->get();
@@ -129,8 +142,8 @@
     return false;
   if (!is_valid)
     return true;
-  return ReadCert(iter, &r->cert) &&
-         ReadCert(iter, &r->unverified_cert) &&
+  return ReadCert(m, iter, &r->cert) &&
+         ReadCert(m, iter, &r->unverified_cert) &&
          ReadParam(m, iter, &r->cert_status) &&
          ReadParam(m, iter, &r->security_bits) &&
          ReadParam(m, iter, &r->key_exchange_group) &&
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index 1cf1b53..9ada1963 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -229,8 +229,8 @@
     float device_scale_factor,
     const ScreenInfo& screen_info) {
   base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
-  cc::LayerTreeSettings settings =
-      GenerateLayerTreeSettings(*cmd, deps, device_scale_factor, screen_info);
+  cc::LayerTreeSettings settings = GenerateLayerTreeSettings(
+      *cmd, deps, device_scale_factor, client->IsForSubframe(), screen_info);
 
   const bool is_threaded = !!deps->GetCompositorImplThreadTaskRunner();
 
@@ -270,9 +270,12 @@
     const base::CommandLine& cmd,
     CompositorDependencies* compositor_deps,
     float device_scale_factor,
+    bool is_for_subframe,
     const ScreenInfo& screen_info) {
   cc::LayerTreeSettings settings;
 
+  settings.is_layer_tree_for_subframe = is_for_subframe;
+
   // For web contents, layer transforms should scale up the contents of layers
   // to keep content always crisp when possible.
   settings.layer_transforms_should_scale_layer_contents = true;
@@ -1120,6 +1123,10 @@
   delegate_->DidCompletePageScaleAnimation();
 }
 
+bool RenderWidgetCompositor::IsForSubframe() {
+  return is_for_oopif_;
+}
+
 void RenderWidgetCompositor::RequestScheduleAnimation() {
   delegate_->RequestScheduleAnimation();
 }
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h
index 45bab300..a36b5f02 100644
--- a/content/renderer/gpu/render_widget_compositor.h
+++ b/content/renderer/gpu/render_widget_compositor.h
@@ -66,6 +66,7 @@
       const base::CommandLine& cmd,
       CompositorDependencies* compositor_deps,
       float device_scale_factor,
+      bool is_for_subframe,
       const ScreenInfo& screen_info);
   static std::unique_ptr<cc::LayerTreeHost> CreateLayerTreeHost(
       cc::LayerTreeHostClient* client,
@@ -197,6 +198,7 @@
   void DidCommitAndDrawFrame() override;
   void DidReceiveCompositorFrameAck() override;
   void DidCompletePageScaleAnimation() override;
+  bool IsForSubframe() override;
 
   // cc::LayerTreeHostSingleThreadClient implementation.
   void RequestScheduleAnimation() override;
diff --git a/content/renderer/media/pepper_to_video_track_adapter.cc b/content/renderer/media/pepper_to_video_track_adapter.cc
index c1f31cf..7893276e 100644
--- a/content/renderer/media/pepper_to_video_track_adapter.cc
+++ b/content/renderer/media/pepper_to_video_track_adapter.cc
@@ -168,7 +168,6 @@
     return;
   }
 
-  SkAutoLockPixels src_lock(bitmap);
   const uint8_t* src_data = static_cast<uint8_t*>(bitmap.getPixels());
   const int src_stride = static_cast<int>(bitmap.rowBytes());
   const int width = bitmap.width();
diff --git a/content/renderer/pepper/pepper_graphics_2d_host.cc b/content/renderer/pepper/pepper_graphics_2d_host.cc
index c2f625f..6b6959e 100644
--- a/content/renderer/pepper/pepper_graphics_2d_host.cc
+++ b/content/renderer/pepper/pepper_graphics_2d_host.cc
@@ -106,8 +106,6 @@
 
   SkBitmap src_bitmap(src_image->GetMappedBitmap());
   SkBitmap dest_bitmap(dest_image->GetMappedBitmap());
-  SkAutoLockPixels src_lock(src_bitmap);
-  SkAutoLockPixels dest_lock(dest_bitmap);
   if (src_rect.width() == src_image->width() &&
       dest_rect.width() == dest_image->width()) {
     // Fast path if the full frame can be converted at once.
diff --git a/content/renderer/pepper/pepper_video_source_host.cc b/content/renderer/pepper/pepper_video_source_host.cc
index 0a14c03..0e564b3b 100644
--- a/content/renderer/pepper/pepper_video_source_host.cc
+++ b/content/renderer/pepper/pepper_video_source_host.cc
@@ -221,7 +221,6 @@
     return;
   }
 
-  SkAutoLockPixels lock(bitmap);
   uint8_t* bitmap_pixels = static_cast<uint8_t*>(bitmap.getPixels());
   if (!bitmap_pixels) {
     SendGetFrameErrorReply(PP_ERROR_FAILED);
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index ff49586..704fc23 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -1280,13 +1280,14 @@
   compositor_ = RenderWidgetCompositor::Create(this, compositor_deps_);
   auto animation_host = cc::AnimationHost::CreateMainInstance();
 
+  // Oopif status must be set before the LayerTreeHost is created.
+  compositor_->SetIsForOopif(for_oopif_);
   auto layer_tree_host = RenderWidgetCompositor::CreateLayerTreeHost(
       compositor_.get(), compositor_.get(), animation_host.get(),
       compositor_deps_, device_scale_factor_, screen_info_);
   compositor_->Initialize(std::move(layer_tree_host),
                           std::move(animation_host));
 
-  compositor_->SetIsForOopif(for_oopif_);
   compositor_->SetViewportSize(physical_backing_size_);
   OnDeviceScaleFactorChanged();
   compositor_->SetRasterColorSpace(screen_info_.icc_profile.GetColorSpace());
diff --git a/content/renderer/renderer_clipboard_delegate.cc b/content/renderer/renderer_clipboard_delegate.cc
index 1fb70de..ec5e4ff 100644
--- a/content/renderer/renderer_clipboard_delegate.cc
+++ b/content/renderer/renderer_clipboard_delegate.cc
@@ -123,8 +123,8 @@
 
   const gfx::Size size(bitmap.width(), bitmap.height());
   std::unique_ptr<base::SharedMemory> shared_buf;
+
   {
-    SkAutoLockPixels locked(bitmap);
     void* pixels = bitmap.getPixels();
     // TODO(piman): this should not be NULL, but it is. crbug.com/369621
     if (!pixels)
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc
index 5ccc498f..8924eba1 100644
--- a/content/shell/browser/layout_test/blink_test_controller.cc
+++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -693,8 +693,6 @@
 
 void BlinkTestController::OnImageDump(const std::string& actual_pixel_hash,
                                       const SkBitmap& image) {
-  SkAutoLockPixels image_lock(image);
-
   printer_->PrintImageHeader(actual_pixel_hash, expected_pixel_hash_);
 
   // Only encode and dump the png if the hashes don't match. Encoding the
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc
index 442b2b8..d2171e6 100644
--- a/content/shell/renderer/layout_test/blink_test_runner.cc
+++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -937,7 +937,6 @@
   DCHECK_NE(0, snapshot.info().width());
   DCHECK_NE(0, snapshot.info().height());
 
-  SkAutoLockPixels snapshot_lock(snapshot);
   // The snapshot arrives from the GPU process via shared memory. Because MSan
   // can't track initializedness across processes, we must assure it that the
   // pixels are in fact initialized.
diff --git a/content/shell/test_runner/pixel_dump.cc b/content/shell/test_runner/pixel_dump.cc
index 6252a44..123030f 100644
--- a/content/shell/test_runner/pixel_dump.cc
+++ b/content/shell/test_runner/pixel_dump.cc
@@ -204,9 +204,7 @@
   blink::WebImage image = static_cast<blink::WebMockClipboard*>(
                               blink::Platform::Current()->Clipboard())
                               ->ReadRawImage(blink::WebClipboard::Buffer());
-  const SkBitmap& bitmap = image.GetSkBitmap();
-  SkAutoLockPixels autoLock(bitmap);
-  callback.Run(bitmap);
+  callback.Run(image.GetSkBitmap());
 }
 
 }  // namespace test_runner
diff --git a/content/shell/test_runner/test_runner.cc b/content/shell/test_runner/test_runner.cc
index b2201f4..3feadb7 100644
--- a/content/shell/test_runner/test_runner.cc
+++ b/content/shell/test_runner/test_runner.cc
@@ -1800,10 +1800,7 @@
       // Return a blank image so that the test fails.
       SkBitmap bitmap;
       bitmap.allocN32Pixels(1, 1);
-      {
-        SkAutoLockPixels lock(bitmap);
-        bitmap.eraseColor(0);
-      }
+      bitmap.eraseColor(0);
       callback.Run(bitmap);
       return;
     }
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 a2f28395..cbd139b 100644
--- a/content/shell/test_runner/test_runner_for_specific_view.cc
+++ b/content/shell/test_runner/test_runner_for_specific_view.cc
@@ -255,7 +255,6 @@
 
   v8::Context::Scope context_scope(context);
   v8::Local<v8::Value> argv[3];
-  SkAutoLockPixels snapshot_lock(snapshot);
 
   // Size can be 0 for cases where copyImageAt was called on position
   // that doesn't have an image.
diff --git a/content/test/image_decoder_test.cc b/content/test/image_decoder_test.cc
index 1ff6b7b..ff682f4 100644
--- a/content/test/image_decoder_test.cc
+++ b/content/test/image_decoder_test.cc
@@ -61,7 +61,6 @@
 void SaveMD5Sum(const base::FilePath& path, const blink::WebImage& web_image) {
   // Calculate MD5 sum.
   base::MD5Digest digest;
-  web_image.getSkBitmap().lockPixels();
   base::MD5Sum(web_image.getSkBitmap().getPixels(),
                web_image.getSkBitmap().width() *
                    web_image.getSkBitmap().height() * sizeof(uint32_t),
@@ -71,7 +70,6 @@
   int bytes_written = base::WriteFile(
       path, reinterpret_cast<const char*>(&digest), sizeof digest);
   ASSERT_EQ(sizeof digest, bytes_written);
-  web_image.getSkBitmap().unlockPixels();
 }
 #endif
 
@@ -89,7 +87,6 @@
   // Calculate MD5 sum.
   base::MD5Digest actual_digest;
   blink::WebImage web_image = decoder.GetFrameAtIndex(frame_index);
-  web_image.GetSkBitmap().lockPixels();
   base::MD5Sum(web_image.GetSkBitmap().getPixels(),
                web_image.GetSkBitmap().width() *
                    web_image.GetSkBitmap().height() * sizeof(uint32_t),
@@ -105,7 +102,6 @@
   // Verify that the sums are the same.
   EXPECT_EQ(0, memcmp(&expected_digest, &actual_digest, sizeof actual_digest))
       << path.value();
-  web_image.GetSkBitmap().unlockPixels();
 }
 #endif
 
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc
index 8d6a109..9c19b34 100644
--- a/content/test/layouttest_support.cc
+++ b/content/test/layouttest_support.cc
@@ -347,7 +347,7 @@
     ScreenInfo dummy_screen_info;
     cc::LayerTreeSettings settings =
         RenderWidgetCompositor::GenerateLayerTreeSettings(
-            *base::CommandLine::ForCurrentProcess(), deps, 1.f,
+            *base::CommandLine::ForCurrentProcess(), deps, 1.f, false,
             dummy_screen_info);
 
     auto compositor_frame_sink = base::MakeUnique<cc::TestCompositorFrameSink>(
diff --git a/extensions/browser/api/web_contents_capture_client.cc b/extensions/browser/api/web_contents_capture_client.cc
index 78ee2851..98eb667 100644
--- a/extensions/browser/api/web_contents_capture_client.cc
+++ b/extensions/browser/api/web_contents_capture_client.cc
@@ -91,7 +91,6 @@
                                             std::string* base64_result) {
   DCHECK(base64_result);
   std::vector<unsigned char> data;
-  SkAutoLockPixels screen_capture_lock(bitmap);
   const bool should_discard_alpha = !ClientAllowsTransparency();
   bool encoded = false;
   std::string mime_type;
diff --git a/extensions/renderer/api_binding.cc b/extensions/renderer/api_binding.cc
index fc4da0c..39d5dea 100644
--- a/extensions/renderer/api_binding.cc
+++ b/extensions/renderer/api_binding.cc
@@ -139,9 +139,11 @@
 struct APIBinding::CustomPropertyData {
   CustomPropertyData(const std::string& type_name,
                      const std::string& property_name,
+                     const base::ListValue* property_values,
                      const CreateCustomType& create_custom_type)
       : type_name(type_name),
         property_name(property_name),
+        property_values(property_values),
         create_custom_type(create_custom_type) {}
 
   // The type of the property, e.g. 'storage.StorageArea'.
@@ -149,6 +151,8 @@
   // The name of the property on the object, e.g. 'local' for
   // chrome.storage.local.
   std::string property_name;
+  // Values curried into this particular type from the schema.
+  const base::ListValue* property_values;
 
   CreateCustomType create_custom_type;
 };
@@ -387,8 +391,10 @@
     v8::Local<v8::String> v8_key = gin::StringToSymbol(isolate, iter.key());
     std::string ref;
     if (dict->GetString("$ref", &ref)) {
+      const base::ListValue* property_values = nullptr;
+      CHECK(dict->GetList("value", &property_values));
       auto property_data = base::MakeUnique<CustomPropertyData>(
-          ref, iter.key(), create_custom_type_);
+          ref, iter.key(), property_values, create_custom_type_);
       object_template->SetLazyDataProperty(
           v8_key, &APIBinding::GetCustomPropertyObject,
           v8::External::New(isolate, property_data.get()));
@@ -473,7 +479,8 @@
       static_cast<CustomPropertyData*>(info.Data().As<v8::External>()->Value());
 
   v8::Local<v8::Object> property = property_data->create_custom_type.Run(
-      context, property_data->type_name, property_data->property_name);
+      context, property_data->type_name, property_data->property_name,
+      property_data->property_values);
   if (property.IsEmpty())
     return;
 
diff --git a/extensions/renderer/api_binding.h b/extensions/renderer/api_binding.h
index 0fffaee..7728e3f 100644
--- a/extensions/renderer/api_binding.h
+++ b/extensions/renderer/api_binding.h
@@ -41,10 +41,11 @@
 // contexts.
 class APIBinding {
  public:
-  using CreateCustomType =
-      base::Callback<v8::Local<v8::Object>(v8::Local<v8::Context> context,
-                                           const std::string& type_name,
-                                           const std::string& property_name)>;
+  using CreateCustomType = base::Callback<v8::Local<v8::Object>(
+      v8::Local<v8::Context> context,
+      const std::string& type_name,
+      const std::string& property_name,
+      const base::ListValue* property_values)>;
 
   // The callback for determining if a given API method (specified by |name|)
   // is available.
diff --git a/extensions/renderer/api_binding_unittest.cc b/extensions/renderer/api_binding_unittest.cc
index d5cbea7..c589d08 100644
--- a/extensions/renderer/api_binding_unittest.cc
+++ b/extensions/renderer/api_binding_unittest.cc
@@ -623,25 +623,30 @@
   SetProperties(
       "{"
       "  'alpha': {"
-      "    '$ref': 'AlphaRef'"
+      "    '$ref': 'AlphaRef',"
+      "    'value': ['a']"
       "  },"
       "  'beta': {"
-      "    '$ref': 'BetaRef'"
+      "    '$ref': 'BetaRef',"
+      "    'value': ['b']"
       "  }"
       "}");
   auto create_custom_type = [](v8::Local<v8::Context> context,
                                const std::string& type_name,
-                               const std::string& property_name) {
+                               const std::string& property_name,
+                               const base::ListValue* property_values) {
     v8::Isolate* isolate = context->GetIsolate();
     v8::Local<v8::Object> result = v8::Object::New(isolate);
     if (type_name == "AlphaRef") {
       EXPECT_EQ("alpha", property_name);
+      EXPECT_EQ("[\"a\"]", ValueToString(*property_values));
       result
           ->Set(context, gin::StringToSymbol(isolate, "alphaProp"),
                 gin::StringToV8(isolate, "alphaVal"))
           .ToChecked();
     } else if (type_name == "BetaRef") {
       EXPECT_EQ("beta", property_name);
+      EXPECT_EQ("[\"b\"]", ValueToString(*property_values));
       result
           ->Set(context, gin::StringToSymbol(isolate, "betaProp"),
                 gin::StringToV8(isolate, "betaVal"))
diff --git a/extensions/renderer/api_bindings_system.cc b/extensions/renderer/api_bindings_system.cc
index 706b1e2e..344041f 100644
--- a/extensions/renderer/api_bindings_system.cc
+++ b/extensions/renderer/api_bindings_system.cc
@@ -133,11 +133,13 @@
 v8::Local<v8::Object> APIBindingsSystem::CreateCustomType(
     v8::Local<v8::Context> context,
     const std::string& type_name,
-    const std::string& property_name) {
+    const std::string& property_name,
+    const base::ListValue* property_values) {
   auto iter = custom_types_.find(type_name);
   DCHECK(iter != custom_types_.end()) << "Custom type not found: " << type_name;
-  return iter->second.Run(context, property_name, &request_handler_,
-                          &event_handler_, &type_reference_map_);
+  return iter->second.Run(context, property_name, property_values,
+                          &request_handler_, &event_handler_,
+                          &type_reference_map_);
 }
 
 }  // namespace extensions
diff --git a/extensions/renderer/api_bindings_system.h b/extensions/renderer/api_bindings_system.h
index 8b9e86d5..9f96dbb 100644
--- a/extensions/renderer/api_bindings_system.h
+++ b/extensions/renderer/api_bindings_system.h
@@ -33,12 +33,13 @@
  public:
   using GetAPISchemaMethod =
       base::Callback<const base::DictionaryValue&(const std::string&)>;
-  using CustomTypeHandler =
-      base::Callback<v8::Local<v8::Object>(v8::Local<v8::Context> context,
-                                           const std::string& property_name,
-                                           APIRequestHandler* request_handler,
-                                           APIEventHandler* event_handler,
-                                           APITypeReferenceMap* type_refs)>;
+  using CustomTypeHandler = base::Callback<v8::Local<v8::Object>(
+      v8::Local<v8::Context> context,
+      const std::string& property_name,
+      const base::ListValue* property_values,
+      APIRequestHandler* request_handler,
+      APIEventHandler* event_handler,
+      APITypeReferenceMap* type_refs)>;
 
   APIBindingsSystem(const binding::RunJSFunction& call_js,
                     const binding::RunJSFunctionSync& call_js_sync,
@@ -101,9 +102,11 @@
   void InitializeType(const std::string& name);
 
   // Handles creating the type for the specified property.
-  v8::Local<v8::Object> CreateCustomType(v8::Local<v8::Context> context,
-                                         const std::string& type_name,
-                                         const std::string& property_name);
+  v8::Local<v8::Object> CreateCustomType(
+      v8::Local<v8::Context> context,
+      const std::string& type_name,
+      const std::string& property_name,
+      const base::ListValue* property_values);
 
   // The map of cached API reference types.
   APITypeReferenceMap type_reference_map_;
diff --git a/extensions/renderer/chrome_setting.cc b/extensions/renderer/chrome_setting.cc
index 16f273e6..43dad58 100644
--- a/extensions/renderer/chrome_setting.cc
+++ b/extensions/renderer/chrome_setting.cc
@@ -17,59 +17,22 @@
 
 namespace extensions {
 
-v8::Local<v8::Object> ChromeSetting::Create(v8::Local<v8::Context> context,
-                                            const std::string& property_name,
-                                            APIRequestHandler* request_handler,
-                                            APIEventHandler* event_handler,
-                                            APITypeReferenceMap* type_refs) {
-  auto value_spec = base::MakeUnique<base::DictionaryValue>();
-  // Most ChromeSettings have a pref that matches the property name and are of
-  // type boolean.
-  base::StringPiece pref_name = property_name;
-  base::StringPiece type = "boolean";
+v8::Local<v8::Object> ChromeSetting::Create(
+    v8::Local<v8::Context> context,
+    const std::string& property_name,
+    const base::ListValue* property_values,
+    APIRequestHandler* request_handler,
+    APIEventHandler* event_handler,
+    APITypeReferenceMap* type_refs) {
+  std::string pref_name;
+  CHECK(property_values->GetString(0u, &pref_name));
+  const base::DictionaryValue* value_spec = nullptr;
+  CHECK(property_values->GetDictionary(1u, &value_spec));
 
-  // A few of ChromeSettings are special, and have different arguments.
-  base::StringPiece ref;
-  if (property_name == "animationPolicy") {
-    type = "string";
-    auto enum_list = base::MakeUnique<base::ListValue>();
-    enum_list->AppendString("allowed");
-    enum_list->AppendString("once");
-    enum_list->AppendString("none");
-    value_spec->Set("enum", std::move(enum_list));
-  } else if (property_name == "webRTCIPHandlingPolicy") {
-    ref = "IPHandlingPolicy";
-  } else if (property_name == "spdyProxyEnabled") {
-    pref_name = "spdy_proxy.enabled";
-  } else if (property_name == "dataReductionDailyContentLength") {
-    type = "array";
-    pref_name = "data_reduction.daily_original_length";
-  } else if (property_name == "dataReductionDailyReceivedLength") {
-    type = "array";
-    pref_name = "data_reduction.daily_received_length";
-  } else if (property_name == "dataUsageReportingEnabled") {
-    pref_name = "data_usage_reporting.enabled";
-  } else if (property_name == "proxy") {
-    ref = "ProxyConfig";
-  }
-
-  if (!ref.empty())
-    value_spec->SetString("$ref", ref);
-  else
-    value_spec->SetString("type", type);
-
-  // The set() call takes an object { value: { type: <t> }, ... }, where <t>
-  // is the custom set() argument specified above by value_spec.
-  base::DictionaryValue set_spec;
-  set_spec.SetString("type", "object");
-  auto properties = base::MakeUnique<base::DictionaryValue>();
-  properties->Set("value", std::move(value_spec));
-  set_spec.Set("properties", std::move(properties));
-
-  gin::Handle<ChromeSetting> handle = gin::CreateHandle(
-      context->GetIsolate(),
-      new ChromeSetting(request_handler, event_handler, type_refs,
-                        pref_name.as_string(), set_spec));
+  gin::Handle<ChromeSetting> handle =
+      gin::CreateHandle(context->GetIsolate(),
+                        new ChromeSetting(request_handler, event_handler,
+                                          type_refs, pref_name, *value_spec));
   return handle.ToV8().As<v8::Object>();
 }
 
@@ -77,12 +40,24 @@
                              APIEventHandler* event_handler,
                              const APITypeReferenceMap* type_refs,
                              const std::string& pref_name,
-                             const base::DictionaryValue& argument_spec)
+                             const base::DictionaryValue& set_value_spec)
     : request_handler_(request_handler),
       event_handler_(event_handler),
       type_refs_(type_refs),
       pref_name_(pref_name),
-      argument_spec_(argument_spec) {}
+      argument_spec_(ArgumentType::OBJECT) {
+  // The set() call takes an object { value: { type: <t> }, ... }, where <t>
+  // is the custom set() argument specified above by value_spec.
+  ArgumentSpec::PropertiesMap properties;
+  {
+    auto scope_spec = base::MakeUnique<ArgumentSpec>(ArgumentType::REF);
+    scope_spec->set_ref("types.ChromeSettingScope");
+    scope_spec->set_optional(true);
+    properties["scope"] = std::move(scope_spec);
+  }
+  properties["value"] = base::MakeUnique<ArgumentSpec>(set_value_spec);
+  argument_spec_.set_properties(std::move(properties));
+}
 
 ChromeSetting::~ChromeSetting() = default;
 
diff --git a/extensions/renderer/chrome_setting.h b/extensions/renderer/chrome_setting.h
index 5bb38b17..d5bbba27 100644
--- a/extensions/renderer/chrome_setting.h
+++ b/extensions/renderer/chrome_setting.h
@@ -14,6 +14,7 @@
 
 namespace base {
 class DictionaryValue;
+class ListValue;
 }
 
 namespace gin {
@@ -32,6 +33,7 @@
   // Creates a ChromeSetting object for the given property.
   static v8::Local<v8::Object> Create(v8::Local<v8::Context> context,
                                       const std::string& property_name,
+                                      const base::ListValue* property_values,
                                       APIRequestHandler* request_handler,
                                       APIEventHandler* event_handler,
                                       APITypeReferenceMap* type_refs);
diff --git a/extensions/renderer/storage_area.cc b/extensions/renderer/storage_area.cc
index 837c725..d3017399 100644
--- a/extensions/renderer/storage_area.cc
+++ b/extensions/renderer/storage_area.cc
@@ -152,6 +152,7 @@
 v8::Local<v8::Object> StorageArea::CreateStorageArea(
     v8::Local<v8::Context> context,
     const std::string& property_name,
+    const base::ListValue* property_values,
     APIRequestHandler* request_handler,
     APIEventHandler* event_handler,
     APITypeReferenceMap* type_refs) {
diff --git a/extensions/renderer/storage_area.h b/extensions/renderer/storage_area.h
index 5906da2..40aa1094 100644
--- a/extensions/renderer/storage_area.h
+++ b/extensions/renderer/storage_area.h
@@ -11,6 +11,10 @@
 #include "base/strings/string_piece.h"
 #include "v8/include/v8.h"
 
+namespace base {
+class ListValue;
+}
+
 namespace gin {
 class Arguments;
 }
@@ -33,6 +37,7 @@
   static v8::Local<v8::Object> CreateStorageArea(
       v8::Local<v8::Context> context,
       const std::string& property_name,
+      const base::ListValue* property_values,
       APIRequestHandler* request_handler,
       APIEventHandler* event_handler,
       APITypeReferenceMap* type_refs);
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index 55afe1f..ec030d5c 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -146,7 +146,6 @@
   "network",
   "page",
   "profiler",
-  "rendering",
   "runtime",
   "security",
   "service_worker",
diff --git a/headless/lib/browser/headless_devtools_client_impl.cc b/headless/lib/browser/headless_devtools_client_impl.cc
index 9cb9de77..0b6cc969 100644
--- a/headless/lib/browser/headless_devtools_client_impl.cc
+++ b/headless/lib/browser/headless_devtools_client_impl.cc
@@ -59,7 +59,6 @@
       network_domain_(this),
       page_domain_(this),
       profiler_domain_(this),
-      rendering_domain_(this),
       runtime_domain_(this),
       security_domain_(this),
       service_worker_domain_(this),
@@ -329,10 +328,6 @@
   return &profiler_domain_;
 }
 
-rendering::Domain* HeadlessDevToolsClientImpl::GetRendering() {
-  return &rendering_domain_;
-}
-
 runtime::Domain* HeadlessDevToolsClientImpl::GetRuntime() {
   return &runtime_domain_;
 }
diff --git a/headless/lib/browser/headless_devtools_client_impl.h b/headless/lib/browser/headless_devtools_client_impl.h
index 1b17967..3accb438 100644
--- a/headless/lib/browser/headless_devtools_client_impl.h
+++ b/headless/lib/browser/headless_devtools_client_impl.h
@@ -34,7 +34,6 @@
 #include "headless/public/devtools/domains/network.h"
 #include "headless/public/devtools/domains/page.h"
 #include "headless/public/devtools/domains/profiler.h"
-#include "headless/public/devtools/domains/rendering.h"
 #include "headless/public/devtools/domains/runtime.h"
 #include "headless/public/devtools/domains/security.h"
 #include "headless/public/devtools/domains/service_worker.h"
@@ -87,7 +86,6 @@
   network::Domain* GetNetwork() override;
   page::Domain* GetPage() override;
   profiler::Domain* GetProfiler() override;
-  rendering::Domain* GetRendering() override;
   runtime::Domain* GetRuntime() override;
   security::Domain* GetSecurity() override;
   service_worker::Domain* GetServiceWorker() override;
@@ -190,7 +188,6 @@
   network::ExperimentalDomain network_domain_;
   page::ExperimentalDomain page_domain_;
   profiler::ExperimentalDomain profiler_domain_;
-  rendering::ExperimentalDomain rendering_domain_;
   runtime::ExperimentalDomain runtime_domain_;
   security::ExperimentalDomain security_domain_;
   service_worker::ExperimentalDomain service_worker_domain_;
diff --git a/headless/public/headless_devtools_client.h b/headless/public/headless_devtools_client.h
index 7e7d979..b3cea9482 100644
--- a/headless/public/headless_devtools_client.h
+++ b/headless/public/headless_devtools_client.h
@@ -84,9 +84,6 @@
 namespace profiler {
 class Domain;
 }
-namespace rendering {
-class Domain;
-}
 namespace runtime {
 class Domain;
 }
@@ -139,7 +136,6 @@
   virtual network::Domain* GetNetwork() = 0;
   virtual page::Domain* GetPage() = 0;
   virtual profiler::Domain* GetProfiler() = 0;
-  virtual rendering::Domain* GetRendering() = 0;
   virtual runtime::Domain* GetRuntime() = 0;
   virtual security::Domain* GetSecurity() = 0;
   virtual service_worker::Domain* GetServiceWorker() = 0;
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.mm b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
index 9286a2ed..970abc0b 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
@@ -155,9 +155,9 @@
 }
 
 + (void)waitForErrorPage {
-  NSString* const kInternetDisconnectedError =
+  NSString* const kErrorPageText =
       l10n_util::GetNSString(IDS_ERRORPAGES_HEADING_NOT_AVAILABLE);
-  [self waitForStaticHTMLViewContainingText:kInternetDisconnectedError];
+  [self waitForStaticHTMLViewContainingText:kErrorPageText];
 }
 
 + (void)waitForStaticHTMLViewContainingText:(NSString*)text {
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn
index 7885519..66c2e2e 100644
--- a/ios/web/BUILD.gn
+++ b/ios/web/BUILD.gn
@@ -694,7 +694,6 @@
     "web_state/js/resources/common.js",
     "web_state/js/resources/console.js",
     "web_state/js/resources/context_menu.js",
-    "web_state/js/resources/dialog_overrides.js",
     "web_state/js/resources/error.js",
     "web_state/js/resources/form.js",
     "web_state/js/resources/legacy.js",
diff --git a/ios/web/public/web_state/web_state.h b/ios/web/public/web_state/web_state.h
index 79701369..62d860e 100644
--- a/ios/web/public/web_state/web_state.h
+++ b/ios/web/public/web_state/web_state.h
@@ -110,7 +110,7 @@
   virtual bool IsWebUsageEnabled() const = 0;
   virtual void SetWebUsageEnabled(bool enabled) = 0;
 
-  // Whether or not dialogs (JavaScript, geolocation) and window open requests
+  // Whether or not JavaScript dialogs and window open requests
   // should be suppressed. Default is false. When dialog is suppressed
   // |WebStateObserver::DidSuppressDialog| will be called.
   virtual bool ShouldSuppressDialogs() const = 0;
diff --git a/ios/web/public/web_state/web_state_observer.h b/ios/web/public/web_state/web_state_observer.h
index 2d84681c7..52fdb1ed 100644
--- a/ios/web/public/web_state/web_state_observer.h
+++ b/ios/web/public/web_state/web_state_observer.h
@@ -91,8 +91,7 @@
   // Called when the visible security state of the page changes.
   virtual void DidChangeVisibleSecurityState() {}
 
-  // Called when a dialog (JavaScript, geolocation) or window open request was
-  // suppressed.
+  // Called when a JavaScript dialog or window open request was suppressed.
   // NOTE: Called only if WebState::SetShouldSuppressDialogs() was called with
   // false.
   virtual void DidSuppressDialog() {}
diff --git a/ios/web/shell/test/page_state_egtest.mm b/ios/web/shell/test/page_state_egtest.mm
index ab9a244f..08ffddd7 100644
--- a/ios/web/shell/test/page_state_egtest.mm
+++ b/ios/web/shell/test/page_state_egtest.mm
@@ -53,6 +53,17 @@
   GREYAssert([condition waitWithTimeout:10], error_text);
 }
 
+// Loads the long page at |url|, scrolls to the top, and waits for the offset to
+// be {0, 0} before returning.
+void ScrollLongPageToTop(const GURL& url) {
+  // Load the page and swipe down.
+  [ShellEarlGrey loadURL:url];
+  [[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
+      performAction:grey_scrollToContentEdge(kGREYContentEdgeTop)];
+  // Waits for the {0, 0} offset.
+  WaitForOffset(0.0);
+}
+
 }  // namespace
 
 using web::test::HttpServer;
@@ -65,24 +76,18 @@
 
 // Tests that page scroll position of a page is restored upon returning to the
 // page via the back/forward buttons.
-// TODO(crbug.com/702410): This test flakily fails when it scrolls too far down
-// the page.
-- (void)FLAKY_testScrollPositionRestoring {
+- (void)testScrollPositionRestoring {
   web::test::SetUpFileBasedHttpServer();
 
-  // Load first URL which is a long page.
-  [ShellEarlGrey loadURL:HttpServer::MakeUrl(kLongPage1)];
-
   // Scroll the first page and verify the offset.
+  ScrollLongPageToTop(HttpServer::MakeUrl(kLongPage1));
   [[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
       performAction:grey_scrollInDirection(kGREYDirectionDown, kOffset1)];
   [[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
       assertWithMatcher:grey_scrollViewContentOffset(CGPointMake(0, kOffset1))];
 
-  // Load second URL, which is also a long page.
-  [ShellEarlGrey loadURL:HttpServer::MakeUrl(kLongPage2)];
-
   // Scroll the second page and verify the offset.
+  ScrollLongPageToTop(HttpServer::MakeUrl(kLongPage2));
   [[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
       performAction:grey_scrollInDirection(kGREYDirectionDown, kOffset2)];
   [[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
diff --git a/ios/web/web_state/js/resources/dialog_overrides.js b/ios/web/web_state/js/resources/dialog_overrides.js
deleted file mode 100644
index e90c158..0000000
--- a/ios/web/web_state/js/resources/dialog_overrides.js
+++ /dev/null
@@ -1,100 +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.
-
-goog.provide('__crWeb.dialogOverrides');
-
-goog.require('__crWeb.message');
-
-__gCrWeb.dialogOverrides = {};
-
-(function() {
-  /*
-   * Installs a wrapper around geolocation functions displaying dialogs in order
-   * to control their suppression.
-   *
-   * Since the Javascript on the page may cache the value of those functions
-   * and invoke them later, we must only install the wrapper once and change
-   * their behaviour when required.
-   *
-   * Returns a function that allows changing the value of
-   * |suppressGeolocationDialogs| that is tested by the wrappers.
-   */
-  var installGeolocationDialogOverridesMethods = function() {
-    var suppressGeolocationDialogs = false;
-
-    // Returns a wrapper function around original dialog function. The wrapper
-    // may suppress the dialog and notify host.
-    var makeDialogWrapper = function(originalDialogGetter) {
-      return function() {
-        if (suppressGeolocationDialogs) {
-          __gCrWeb.message.invokeOnHost({
-              'command': 'geolocationDialog.suppressed'
-          });
-        } else {
-          return originalDialogGetter().apply(null, arguments);
-        }
-      };
-    };
-
-    // Reading or writing to the property 'geolocation' too early breaks
-    // the API. Make a copy of navigator and stub in the required methods
-    // without touching the property. See crbug.com/280818 for more
-    // details.
-    var stubNavigator = {};
-
-    // Copy all properties and functions without touching 'geolocation'.
-    var oldNavigator = navigator;
-    for (var keyName in navigator) {
-      if (keyName !== 'geolocation') {
-        var value = navigator[keyName];
-        if (typeof(value) == 'function') {
-          // Forward functions calls to real navigator.
-          stubNavigator[keyName] = function() {
-            return value.apply(oldNavigator, arguments);
-          }
-        } else {
-          Object['defineProperty'](stubNavigator, keyName, {
-            value: value,
-            configurable: false,
-            writable: false,
-            enumerable: true
-          });
-        }
-      }
-    }
-
-    // Stub in 'geolocation' if necessary, using delayed accessor for the
-    // 'geolocation' property of the original |navigator|.
-    if ('geolocation' in navigator) {
-      var geolocation = {};
-      var geoPropNames = ['getCurrentPosition', 'watchPosition', 'clearWatch'];
-      var len = geoPropNames.length;
-      for (var i = 0; i < len; i++) {
-        (function(geoPropName) {
-          geolocation[geoPropName] = makeDialogWrapper(function() {
-             return function() {
-               return oldNavigator.geolocation[geoPropName].apply(
-                   oldNavigator.geolocation, arguments);
-             };
-          });
-        })(geoPropNames[i]);
-      }
-      stubNavigator.geolocation = geolocation;
-    }
-
-    // Install |stubNavigator| as |navigator|.
-    /** @suppress {const} */
-    navigator = stubNavigator;
-
-    // Returns the closure allowing to change |suppressGeolocationDialogs|.
-    return function(setEnabled) {
-      suppressGeolocationDialogs = setEnabled;
-    };
-  };
-
-  // Override geolocation methods that produce dialogs.
-  __gCrWeb['setSuppressGeolocationDialogs'] =
-      installGeolocationDialogOverridesMethods();
-
-}());  // End of anonymous object
diff --git a/ios/web/web_state/js/resources/web_bundle.js b/ios/web/web_state/js/resources/web_bundle.js
index a1d197b6..a1da8a49 100644
--- a/ios/web/web_state/js/resources/web_bundle.js
+++ b/ios/web/web_state/js/resources/web_bundle.js
@@ -7,7 +7,6 @@
 
 goog.require('__crWeb.console');
 goog.require('__crWeb.contextMenu');
-goog.require('__crWeb.dialogOverrides');
 goog.require('__crWeb.error');
 goog.require('__crWeb.form');
 goog.require('__crWeb.legacy');
diff --git a/ios/web/web_state/ui/crw_web_controller.h b/ios/web/web_state/ui/crw_web_controller.h
index 0b227410..b484d3d 100644
--- a/ios/web/web_state/ui/crw_web_controller.h
+++ b/ios/web/web_state/ui/crw_web_controller.h
@@ -96,8 +96,8 @@
 // Returns whether the top of the content is visible.
 @property(nonatomic, readonly) BOOL atTop;
 
-// YES if JavaScript dialogs, HTTP authentication dialogs and window.open
-// calls should be suppressed. Default is NO. When dialog is suppressed
+// YES if JavaScript dialogs and window open requests should be suppressed.
+// Default is NO. When dialog is suppressed
 // |WebStateObserver::DidSuppressDialog| will be called.
 @property(nonatomic, assign) BOOL shouldSuppressDialogs;
 
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index 703e210..d9b33a7 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -347,9 +347,6 @@
   GURL _defaultURL;
   // Show overlay view, don't reload web page.
   BOOL _overlayPreviewMode;
-  // If |YES|, calls |setShouldSuppressDialogs:YES| when window id is injected
-  // into the web view.
-  BOOL _shouldSuppressDialogsOnWindowIDInjection;
   // The URL of an expected future recreation of the |webView|. Valid
   // only if the web view was discarded for non-user-visible reasons, such that
   // if the next load request is for that URL, it should be treated as a
@@ -732,9 +729,6 @@
 // Returns whether the given navigation is triggered by a user link click.
 - (BOOL)isLinkNavigation:(WKNavigationType)navigationType;
 
-// Inject windowID if not yet injected.
-- (void)injectWindowID;
-
 // Returns YES if the given WKBackForwardListItem is valid to use for
 // navigation.
 - (BOOL)isBackForwardListItemValid:(WKBackForwardListItem*)item;
@@ -1258,19 +1252,6 @@
   return scrollView.contentOffset.y == -scrollView.contentInset.top;
 }
 
-- (void)setShouldSuppressDialogs:(BOOL)shouldSuppressDialogs {
-  _shouldSuppressDialogs = shouldSuppressDialogs;
-  if (_webView) {
-    NSString* const kSetSuppressDialogs = [NSString
-        stringWithFormat:@"__gCrWeb.setSuppressGeolocationDialogs(%d);",
-                         shouldSuppressDialogs];
-    [self executeJavaScript:kSetSuppressDialogs completionHandler:nil];
-    _shouldSuppressDialogsOnWindowIDInjection = NO;
-  } else {
-    _shouldSuppressDialogsOnWindowIDInjection = shouldSuppressDialogs;
-  }
-}
-
 - (GURL)currentURLWithTrustLevel:(web::URLVerificationTrustLevel*)trustLevel {
   DCHECK(trustLevel) << "Verification of the trustLevel state is mandatory";
   if (_webView) {
@@ -1424,17 +1405,6 @@
          [list.backList indexOfObject:item] != NSNotFound;
 }
 
-- (void)injectWindowID {
-  // Default value for shouldSuppressDialogs is NO, so updating them only
-  // when necessary is a good optimization.
-  if (_shouldSuppressDialogsOnWindowIDInjection) {
-    self.shouldSuppressDialogs = YES;
-    _shouldSuppressDialogsOnWindowIDInjection = NO;
-  }
-
-  [_windowIDJSManager inject];
-}
-
 - (BOOL)canUseViewForGeneratingOverlayPlaceholderView {
   return _containerView != nil;
 }
@@ -4612,7 +4582,7 @@
     // In unit tests MIME type will be empty, because loadHTML:forURL: does not
     // notify web view delegate about received response, so web controller does
     // not get a chance to properly update MIME type.
-    [self injectWindowID];
+    [_windowIDJSManager inject];
   }
 
   if (isLastNavigation) {
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 6b548101..bbac203 100644
--- a/ios/web/web_state/ui/crw_web_controller_unittest.mm
+++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -363,23 +363,6 @@
   ASSERT_FALSE(observer.did_suppress_dialog_info());
 }
 
-// Tests that geolocation dialog is suppressed.
-TEST_F(DialogsSuppressionTest, SuppressGeolocation) {
-  // The geolocation APIs require HTTPS on iOS 10, which can not be simulated
-  // even using |loadHTMLString:baseURL:| WKWebView API.
-  if (base::ios::IsRunningOnIOS10OrLater()) {
-    return;
-  }
-  web::TestWebStateObserver observer(web_state());
-  ASSERT_FALSE(observer.did_suppress_dialog_info());
-  ASSERT_TRUE(requested_dialogs().empty());
-
-  web_state()->SetShouldSuppressDialogs(true);
-  ExecuteJavaScript(@"navigator.geolocation.getCurrentPosition()");
-  ASSERT_TRUE(observer.did_suppress_dialog_info());
-  EXPECT_EQ(web_state(), observer.did_suppress_dialog_info()->web_state);
-}
-
 // Tests that window.open is suppressed.
 TEST_F(DialogsSuppressionTest, SuppressWindowOpen) {
   web::TestWebStateObserver observer(web_state());
diff --git a/media/blink/webmediaplayer_cast_android.cc b/media/blink/webmediaplayer_cast_android.cc
index 0642951..20df504d 100644
--- a/media/blink/webmediaplayer_cast_android.cc
+++ b/media/blink/webmediaplayer_cast_android.cc
@@ -124,13 +124,10 @@
   gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
-  {
-    SkAutoLockPixels lock(bitmap);
-    gl->TexImage2D(texture_target, 0 /* level */, GL_RGBA /* internalformat */,
-                   bitmap.width(), bitmap.height(), 0 /* border */,
-                   GL_RGBA /* format */, GL_UNSIGNED_BYTE /* type */,
-                   bitmap.getPixels());
-  }
+  gl->TexImage2D(texture_target, 0 /* level */, GL_RGBA /* internalformat */,
+                 bitmap.width(), bitmap.height(), 0 /* border */,
+                 GL_RGBA /* format */, GL_UNSIGNED_BYTE /* type */,
+                 bitmap.getPixels());
 
   gpu::Mailbox texture_mailbox;
   gl->GenMailboxCHROMIUM(texture_mailbox.name);
diff --git a/media/renderers/skcanvas_video_renderer_unittest.cc b/media/renderers/skcanvas_video_renderer_unittest.cc
index 7034b89..a72c0be 100644
--- a/media/renderers/skcanvas_video_renderer_unittest.cc
+++ b/media/renderers/skcanvas_video_renderer_unittest.cc
@@ -554,7 +554,6 @@
   renderer_.Paint(video_frame, &canvas,
                   gfx::RectF(bitmap.width(), bitmap.height()), flags,
                   VIDEO_ROTATION_0, Context3D());
-  SkAutoLockPixels lock(bitmap);
   for (int j = 0; j < bitmap.height(); j++) {
     for (int i = 0; i < bitmap.width(); i++) {
       const int value = i + j * bitmap.width();
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 0c33989d..b2e1f4d7 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -559,6 +559,8 @@
       "cert/ev_root_ca_metadata.h",
       "cert/internal/cert_issuer_source_nss.cc",
       "cert/internal/cert_issuer_source_nss.h",
+      "cert/internal/system_trust_store.cc",
+      "cert/internal/system_trust_store.h",
       "cert/internal/trust_store_mac.cc",
       "cert/internal/trust_store_mac.h",
       "cert/internal/trust_store_nss.cc",
diff --git a/net/cert/cert_verify_proc_builtin.cc b/net/cert/cert_verify_proc_builtin.cc
index 08a2feed..ee85d5e0a 100644
--- a/net/cert/cert_verify_proc_builtin.cc
+++ b/net/cert/cert_verify_proc_builtin.cc
@@ -7,11 +7,6 @@
 #include <string>
 #include <vector>
 
-#if defined(USE_NSS_CERTS)
-#include <cert.h>
-#include <pk11pub.h>
-#endif
-
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/sha1.h"
@@ -27,20 +22,12 @@
 #include "net/cert/internal/parsed_certificate.h"
 #include "net/cert/internal/path_builder.h"
 #include "net/cert/internal/signature_policy.h"
-#include "net/cert/internal/trust_store_collection.h"
-#include "net/cert/internal/trust_store_in_memory.h"
+#include "net/cert/internal/system_trust_store.h"
 #include "net/cert/internal/verify_certificate_chain.h"
 #include "net/cert/x509_certificate.h"
 #include "net/cert/x509_util.h"
 #include "net/der/encode_values.h"
 
-#if defined(USE_NSS_CERTS)
-#include "crypto/nss_util.h"
-#include "net/cert/internal/cert_issuer_source_nss.h"
-#include "net/cert/internal/trust_store_nss.h"
-#include "net/cert/scoped_nss_types.h"
-#endif
-
 namespace net {
 
 namespace {
@@ -102,129 +89,6 @@
   }
 }
 
-// The SystemTrustStore interface augments the TrustStore interface with some
-// additional functionality:
-//
-//  * Determine if a trust anchor was one of the known roots
-//  * Determine if a trust anchor was one of the "extra" ones that
-//    was specified during verification.
-//
-// Implementations of SystemTrustStore create an effective trust
-// store that is the composition of:
-//
-//  (1) System trust store
-//  (2) |additional_trust_anchors|.
-//  (3) Test certificates (if they are separate from system trust store)
-class SystemTrustStore {
- public:
-  virtual ~SystemTrustStore() {}
-
-  virtual TrustStore* GetTrustStore() = 0;
-
-  // TODO(eroman): Can this be exposed through the TrustStore
-  //               interface instead?
-  virtual CertIssuerSource* GetCertIssuerSource() = 0;
-
-  // IsKnownRoot returns true if the given trust anchor is a standard one (as
-  // opposed to a user-installed root)
-  virtual bool IsKnownRoot(
-      const scoped_refptr<TrustAnchor>& trust_anchor) const = 0;
-
-  virtual bool IsAdditionalTrustAnchor(
-      const scoped_refptr<TrustAnchor>& trust_anchor) const = 0;
-};
-
-#if defined(USE_NSS_CERTS)
-class SystemTrustStoreNSS : public SystemTrustStore {
- public:
-  explicit SystemTrustStoreNSS(const CertificateList& additional_trust_anchors)
-      : trust_store_nss_(trustSSL) {
-    CertErrors errors;
-
-    trust_store_.AddTrustStore(&additional_trust_store_);
-    for (const auto& x509_cert : additional_trust_anchors) {
-      scoped_refptr<ParsedCertificate> cert =
-          ParseCertificateFromOSHandle(x509_cert->os_cert_handle(), &errors);
-      if (cert) {
-        additional_trust_store_.AddTrustAnchor(
-            TrustAnchor::CreateFromCertificateNoConstraints(std::move(cert)));
-      }
-      // TODO(eroman): Surface parsing errors of additional trust anchor.
-    }
-
-    trust_store_.AddTrustStore(&trust_store_nss_);
-  }
-
-  TrustStore* GetTrustStore() override { return &trust_store_; }
-
-  CertIssuerSource* GetCertIssuerSource() override {
-    return &cert_issuer_source_nss_;
-  }
-
-  // IsKnownRoot returns true if the given trust anchor is a standard one (as
-  // opposed to a user-installed root)
-  bool IsKnownRoot(
-      const scoped_refptr<TrustAnchor>& trust_anchor) const override {
-    // TODO(eroman): Based on how the TrustAnchors are created by this
-    // integration, there will always be an associated certificate. However this
-    // contradicts the API for TrustAnchor that states it is optional.
-    DCHECK(trust_anchor->cert());
-
-    // TODO(eroman): The overall approach of IsKnownRoot() is inefficient -- it
-    // requires searching for the trust anchor by DER in NSS, however path
-    // building already had a handle to it.
-    SECItem der_cert;
-    der_cert.data =
-        const_cast<uint8_t*>(trust_anchor->cert()->der_cert().UnsafeData());
-    der_cert.len = trust_anchor->cert()->der_cert().Length();
-    der_cert.type = siDERCertBuffer;
-    ScopedCERTCertificate nss_cert(
-        CERT_FindCertByDERCert(CERT_GetDefaultCertDB(), &der_cert));
-    if (!nss_cert)
-      return false;
-
-    return IsKnownRoot(nss_cert.get());
-  }
-
-  bool IsAdditionalTrustAnchor(
-      const scoped_refptr<TrustAnchor>& trust_anchor) const override {
-    return additional_trust_store_.Contains(trust_anchor.get());
-  }
-
- private:
-  // TODO(eroman): This function was copied verbatim from
-  // cert_verify_proc_nss.cc
-  //
-  // IsKnownRoot returns true if the given certificate is one that we believe
-  // is a standard (as opposed to user-installed) root.
-  bool IsKnownRoot(CERTCertificate* root) const {
-    if (!root || !root->slot)
-      return false;
-
-    // This magic name is taken from
-    // http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ckfw/builtins/constants.c&rev=1.13&mark=86,89#79
-    return 0 == strcmp(PK11_GetSlotName(root->slot), "NSS Builtin Objects");
-  }
-
-  TrustStoreCollection trust_store_;
-  TrustStoreInMemory additional_trust_store_;
-
-  TrustStoreNSS trust_store_nss_;
-  CertIssuerSourceNSS cert_issuer_source_nss_;
-};
-#endif
-
-std::unique_ptr<SystemTrustStore> CreateSystemTrustStore(
-    const CertificateList& additional_trust_anchors) {
-#if defined(USE_NSS_CERTS)
-  return base::MakeUnique<SystemTrustStoreNSS>(additional_trust_anchors);
-#else
-  // TODO(crbug.com/649017): Integrate with other system trust stores.
-  NOTIMPLEMENTED();
-  return nullptr;
-#endif
-}
-
 // Appends the SHA1 and SHA256 hashes of |spki_bytes| to |*hashes|.
 void AppendPublicKeyHashes(const der::Input& spki_bytes,
                            HashValueVector* hashes) {
@@ -335,8 +199,18 @@
     return;
   }
 
-  std::unique_ptr<SystemTrustStore> trust_store =
-      CreateSystemTrustStore(additional_trust_anchors);
+  std::unique_ptr<SystemTrustStore> ssl_trust_store =
+      CreateSslSystemTrustStore();
+
+  for (const auto& x509_cert : additional_trust_anchors) {
+    scoped_refptr<ParsedCertificate> cert = ParseCertificateFromOSHandle(
+        x509_cert->os_cert_handle(), &parsing_errors);
+    if (cert) {
+      ssl_trust_store->AddTrustAnchor(
+          TrustAnchor::CreateFromCertificateNoConstraints(std::move(cert)));
+    }
+    // TODO(eroman): Surface parsing errors of additional trust anchor.
+  }
 
   // TODO(eroman): The path building code in this file enforces its idea of weak
   // keys, and separately cert_verify_proc.cc also checks the chains with its
@@ -358,13 +232,13 @@
 
   // Initialize the path builder.
   CertPathBuilder::Result result;
-  CertPathBuilder path_builder(target, trust_store->GetTrustStore(),
+  CertPathBuilder path_builder(target, ssl_trust_store->GetTrustStore(),
                                &signature_policy, verification_time,
                                KeyPurpose::SERVER_AUTH, &result);
 
   // Allow the path builder to discover intermediates from the trust store.
-  if (trust_store->GetCertIssuerSource())
-    path_builder.AddCertIssuerSource(trust_store->GetCertIssuerSource());
+  if (ssl_trust_store->GetCertIssuerSource())
+    path_builder.AddCertIssuerSource(ssl_trust_store->GetCertIssuerSource());
 
   // Allow the path builder to discover the explicitly provided intermediates in
   // |input_cert|.
@@ -392,10 +266,11 @@
 
   if (partial_path.path.trust_anchor) {
     verify_result->is_issued_by_known_root =
-        trust_store->IsKnownRoot(partial_path.path.trust_anchor);
+        ssl_trust_store->IsKnownRoot(partial_path.path.trust_anchor);
 
     verify_result->is_issued_by_additional_trust_anchor =
-        trust_store->IsAdditionalTrustAnchor(partial_path.path.trust_anchor);
+        ssl_trust_store->IsAdditionalTrustAnchor(
+            partial_path.path.trust_anchor);
   } else {
     // TODO(eroman): This shouldn't be necessary -- partial_path.errors should
     // contain an error if it didn't chain to trust anchor.
diff --git a/net/cert/internal/system_trust_store.cc b/net/cert/internal/system_trust_store.cc
new file mode 100644
index 0000000..64ac209
--- /dev/null
+++ b/net/cert/internal/system_trust_store.cc
@@ -0,0 +1,171 @@
+// 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 "net/cert/internal/system_trust_store.h"
+
+#if defined(USE_NSS_CERTS)
+#include <cert.h>
+#include <pk11pub.h>
+#elif defined(OS_MACOSX) && !defined(OS_IOS)
+#include <Security/Security.h>
+#endif
+
+#include "base/memory/ptr_util.h"
+#include "net/cert/internal/trust_store_collection.h"
+#include "net/cert/internal/trust_store_in_memory.h"
+
+#if defined(USE_NSS_CERTS)
+#include "crypto/nss_util.h"
+#include "net/cert/internal/cert_issuer_source_nss.h"
+#include "net/cert/internal/trust_store_nss.h"
+#include "net/cert/scoped_nss_types.h"
+#elif defined(OS_MACOSX) && !defined(OS_IOS)
+#include "net/cert/internal/trust_store_mac.h"
+#endif
+
+namespace net {
+
+namespace {
+
+// Abstract implementation of SystemTrustStore to be used as a base class.
+// Handles the addition of additional trust anchors.
+class BaseSystemTrustStore : public SystemTrustStore {
+ public:
+  BaseSystemTrustStore() {
+    trust_store_.AddTrustStore(&additional_trust_store_);
+  }
+
+  void AddTrustAnchor(const scoped_refptr<TrustAnchor>& trust_anchor) override {
+    additional_trust_store_.AddTrustAnchor(trust_anchor);
+  }
+
+  TrustStore* GetTrustStore() override { return &trust_store_; }
+
+  CertIssuerSource* GetCertIssuerSource() override { return nullptr; }
+
+  bool IsAdditionalTrustAnchor(
+      const scoped_refptr<TrustAnchor>& trust_anchor) const override {
+    return additional_trust_store_.Contains(trust_anchor.get());
+  }
+
+ protected:
+  TrustStoreCollection trust_store_;
+  TrustStoreInMemory additional_trust_store_;
+};
+
+}  // namespace
+
+#if defined(USE_NSS_CERTS)
+namespace {
+
+class SystemTrustStoreNSS : public BaseSystemTrustStore {
+ public:
+  explicit SystemTrustStoreNSS() : trust_store_nss_(trustSSL) {
+    trust_store_.AddTrustStore(&trust_store_nss_);
+  }
+
+  CertIssuerSource* GetCertIssuerSource() override {
+    return &cert_issuer_source_nss_;
+  }
+
+  bool UsesSystemTrustStore() const override { return true; }
+
+  // IsKnownRoot returns true if the given trust anchor is a standard one (as
+  // opposed to a user-installed root)
+  bool IsKnownRoot(
+      const scoped_refptr<TrustAnchor>& trust_anchor) const override {
+    // TODO(eroman): Based on how the TrustAnchors are created by this
+    // integration, there will always be an associated certificate. However this
+    // contradicts the API for TrustAnchor that states it is optional.
+    DCHECK(trust_anchor->cert());
+
+    // TODO(eroman): The overall approach of IsKnownRoot() is inefficient -- it
+    // requires searching for the trust anchor by DER in NSS, however path
+    // building already had a handle to it.
+    SECItem der_cert;
+    der_cert.data =
+        const_cast<uint8_t*>(trust_anchor->cert()->der_cert().UnsafeData());
+    der_cert.len = trust_anchor->cert()->der_cert().Length();
+    der_cert.type = siDERCertBuffer;
+    ScopedCERTCertificate nss_cert(
+        CERT_FindCertByDERCert(CERT_GetDefaultCertDB(), &der_cert));
+    if (!nss_cert)
+      return false;
+
+    return IsKnownRoot(nss_cert.get());
+  }
+
+ private:
+  // TODO(eroman): This function was copied verbatim from
+  // cert_verify_proc_nss.cc
+  //
+  // IsKnownRoot returns true if the given certificate is one that we believe
+  // is a standard (as opposed to user-installed) root.
+  bool IsKnownRoot(CERTCertificate* root) const {
+    if (!root || !root->slot)
+      return false;
+
+    // This magic name is taken from
+    // http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ckfw/builtins/constants.c&rev=1.13&mark=86,89#79
+    return 0 == strcmp(PK11_GetSlotName(root->slot), "NSS Builtin Objects");
+  }
+
+  TrustStoreNSS trust_store_nss_;
+  CertIssuerSourceNSS cert_issuer_source_nss_;
+};
+
+}  // namespace
+
+std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
+  return base::MakeUnique<SystemTrustStoreNSS>();
+}
+
+#elif defined(OS_MACOSX) && !defined(OS_IOS)
+
+class SystemTrustStoreMac : public BaseSystemTrustStore {
+ public:
+  explicit SystemTrustStoreMac() : trust_store_mac_(kSecPolicyAppleSSL) {
+    trust_store_.AddTrustStore(&trust_store_mac_);
+  }
+
+  CertIssuerSource* GetCertIssuerSource() override {
+    // TODO(eroman): Should this return something?
+    return nullptr;
+  }
+
+  bool UsesSystemTrustStore() const override { return true; }
+
+  // IsKnownRoot returns true if the given trust anchor is a standard one (as
+  // opposed to a user-installed root)
+  bool IsKnownRoot(
+      const scoped_refptr<TrustAnchor>& trust_anchor) const override {
+    // TODO(eroman): Implement.
+    return false;
+  }
+
+ private:
+  TrustStoreMac trust_store_mac_;
+};
+
+std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
+  return base::MakeUnique<SystemTrustStoreMac>();
+}
+#else
+
+class DummySystemTrustStore : public BaseSystemTrustStore {
+ public:
+  bool UsesSystemTrustStore() const override { return false; }
+
+  bool IsKnownRoot(
+      const scoped_refptr<TrustAnchor>& trust_anchor) const override {
+    return false;
+  }
+};
+
+std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
+  return base::MakeUnique<DummySystemTrustStore>();
+}
+#endif
+
+}  // namespace net
diff --git a/net/cert/internal/system_trust_store.h b/net/cert/internal/system_trust_store.h
new file mode 100644
index 0000000..2783ce2a
--- /dev/null
+++ b/net/cert/internal/system_trust_store.h
@@ -0,0 +1,88 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_CERT_INTERNAL_SYSTEM_TRUST_STORE_H_
+#define NET_CERT_INTERNAL_SYSTEM_TRUST_STORE_H_
+
+#include <vector>
+
+#include "base/memory/ref_counted.h"
+#include "net/base/net_export.h"
+#include "net/cert/internal/parsed_certificate.h"
+
+namespace net {
+
+class TrustStore;
+class CertIssuerSource;
+class TrustAnchor;
+
+// The SystemTrustStore interface is used to encapsulate a TrustStore for the
+// current platform, with some extra bells and whistles.
+//
+// This is primarily used to abstract out the platform-specific bits that
+// relate to configuring the TrustStore needed for path building.
+//
+// Implementations of SystemTrustStore create an effective trust
+// store that is the composition of:
+//
+//   * The platform-specific trust store
+//   * A set of manually added trust anchors
+//   * Test certificates added via ScopedTestRoot
+class SystemTrustStore {
+ public:
+  virtual ~SystemTrustStore() {}
+
+  // Returns an aggregate TrustStore that can be used by the path builder. The
+  // store composes the system trust store (if implemented) with manually added
+  // trust anchors added via AddTrustAnchor(). This pointer is non-owned, and
+  // valid only for the lifetime of |this|.
+  virtual TrustStore* GetTrustStore() = 0;
+
+  // Returns false if the implementation of SystemTrustStore doesn't actually
+  // make use of the system's trust store. This might be the case for
+  // unsupported platforms. In the case where this returns false, the trust
+  // store returned by GetTrustStore() is made up solely of the manually added
+  // trust anchors (via AddTrustAnchor()).
+  virtual bool UsesSystemTrustStore() const = 0;
+
+  // TODO(eroman): Expose this through the TrustStore interface instead?
+  //
+  // Returns a CertIssuerSource that finds any intermediates that are present in
+  // the system trust store. These intermediates are not necessarily trusted,
+  // however may be used during path building as another means of finding
+  // certificates. If the implementation of SystemTrustStore doesn't support
+  // this feature may return nullptr.
+  virtual CertIssuerSource* GetCertIssuerSource() = 0;
+
+  // IsKnownRoot() returns true if the given trust anchor originated from the
+  // system trust store and is a "standard" one. The meaning of "standard" is
+  // that it is one of default trust anchors for the system, as opposed to a
+  // user-installed one. IsKnownRoot() is only guaranteed to work for
+  // TrustAnchors returned by GetTrustStore().
+  virtual bool IsKnownRoot(
+      const scoped_refptr<TrustAnchor>& trust_anchor) const = 0;
+
+  // Adds a trust anchor to this particular instance of SystemTrustStore, and
+  // not globally for the system.
+  virtual void AddTrustAnchor(
+      const scoped_refptr<TrustAnchor>& trust_anchor) = 0;
+
+  // Returns true if |trust_anchor| was one added via |AddTrustAnchor()|. This
+  // is only guaranteed to work if |trust_anchor| was one returned by
+  // GetTrustStore(), as it may be implemented by pointer comparison rather than
+  // SPKI comparison.
+  virtual bool IsAdditionalTrustAnchor(
+      const scoped_refptr<TrustAnchor>& trust_anchor) const = 0;
+};
+
+// Creates an instance of SystemTrustStore that wraps the current platform's SSL
+// trust store. This canno return nullptr, even in the case where system trust
+// store integration is not supported. In this latter case, the SystemTrustStore
+// will only give access to the manually added trust anchors. This can be
+// inspected by testing whether UsesSystemTrustStore() returns false.
+NET_EXPORT std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore();
+
+}  // namespace net
+
+#endif  // NET_CERT_INTERNAL_SYSTEM_TRUST_STORE_H_
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
index a654327..52e7463 100644
--- a/net/http/http_network_session.cc
+++ b/net/http/http_network_session.cc
@@ -303,21 +303,23 @@
   std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
   dict->Set("sessions", quic_stream_factory_.QuicStreamFactoryInfoToValue());
   dict->SetBoolean("quic_enabled", IsQuicEnabled());
-  std::unique_ptr<base::ListValue> connection_options(new base::ListValue);
-  for (QuicTagVector::const_iterator it =
-           params_.quic_connection_options.begin();
-       it != params_.quic_connection_options.end(); ++it) {
-    connection_options->AppendString("'" + QuicTagToString(*it) + "'");
-  }
+
+  auto connection_options(base::MakeUnique<base::ListValue>());
+  for (const auto& option : params_.quic_connection_options)
+    connection_options->AppendString(QuicTagToString(option));
   dict->Set("connection_options", std::move(connection_options));
 
-  std::unique_ptr<base::ListValue> origins_to_force_quic_on(
-      new base::ListValue);
-  for (const auto& origin : params_.origins_to_force_quic_on) {
-    origins_to_force_quic_on->AppendString("'" + origin.ToString() + "'");
-  }
+  auto supported_versions(base::MakeUnique<base::ListValue>());
+  for (const auto& version : params_.quic_supported_versions)
+    supported_versions->AppendString(QuicVersionToString(version));
+  dict->Set("supported_versions", std::move(supported_versions));
+
+  auto origins_to_force_quic_on(base::MakeUnique<base::ListValue>());
+  for (const auto& origin : params_.origins_to_force_quic_on)
+    origins_to_force_quic_on->AppendString(origin.ToString());
   dict->Set("origins_to_force_quic_on", std::move(origins_to_force_quic_on));
 
+  dict->SetInteger("max_packet_length", params_.quic_max_packet_length);
   dict->SetInteger("max_server_configs_stored_in_properties",
                    params_.quic_max_server_configs_stored_in_properties);
   dict->SetInteger("idle_connection_timeout_seconds",
@@ -327,9 +329,29 @@
   dict->SetInteger(
       "packet_reader_yield_after_duration_milliseconds",
       params_.quic_packet_reader_yield_after_duration_milliseconds);
-  dict->SetBoolean("force_hol_blocking", params_.quic_force_hol_blocking);
+
+  dict->SetBoolean("mark_quic_broken_when_network_blackholes",
+                   params_.mark_quic_broken_when_network_blackholes);
+  dict->SetBoolean("retry_without_alt_svc_on_quic_errors",
+                   params_.retry_without_alt_svc_on_quic_errors);
   dict->SetBoolean("race_cert_verification",
                    params_.quic_race_cert_verification);
+  dict->SetBoolean("disable_bidirectional_streams",
+                   params_.quic_disable_bidirectional_streams);
+  dict->SetBoolean("close_sessions_on_ip_change",
+                   params_.quic_close_sessions_on_ip_change);
+  dict->SetBoolean("migrate_sessions_on_network_change",
+                   params_.quic_migrate_sessions_on_network_change);
+  dict->SetBoolean("migrate_sessions_early",
+                   params_.quic_migrate_sessions_early);
+  dict->SetBoolean("allow_server_migration",
+                   params_.quic_allow_server_migration);
+  dict->SetBoolean("do_not_fragment", params_.quic_do_not_fragment);
+  dict->SetBoolean("do_not_mark_as_broken_on_network_change",
+                   params_.quic_do_not_mark_as_broken_on_network_change);
+  dict->SetBoolean("estimate_initial_rtt", params_.quic_estimate_initial_rtt);
+  dict->SetBoolean("force_hol_blocking", params_.quic_force_hol_blocking);
+
   return std::move(dict);
 }
 
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc
index a16c22f..f84340a9 100644
--- a/net/http/http_stream_factory_impl.cc
+++ b/net/http/http_stream_factory_impl.cc
@@ -372,8 +372,8 @@
 
   int alt_job_count = 0;
   int main_job_count = 0;
-  int pending_request_count = 0;
-  int preconnect_controller_count = 0;
+  size_t num_controllers_with_request = 0;
+  size_t num_controllers_for_preconnect = 0;
   for (const auto& job_controller : job_controller_set_) {
     DCHECK(job_controller->HasPendingAltJob() ||
            job_controller->HasPendingMainJob());
@@ -383,25 +383,33 @@
       job_controller->LogHistograms();
     // For a preconnect controller, it should have exactly the main job.
     if (job_controller->is_preconnect()) {
-      preconnect_controller_count++;
+      num_controllers_for_preconnect++;
       continue;
     }
     // For non-preconnects.
     if (job_controller->HasPendingRequest())
-      pending_request_count++;
+      num_controllers_with_request++;
     if (job_controller->HasPendingAltJob())
       alt_job_count++;
     if (job_controller->HasPendingMainJob())
       main_job_count++;
   }
-  UMA_HISTOGRAM_COUNTS_1M("Net.JobControllerSet.CountOfPreconnect",
-                          preconnect_controller_count);
+  UMA_HISTOGRAM_COUNTS_1M(
+      "Net.JobControllerSet.CountOfJobController.Preconnect",
+      num_controllers_for_preconnect);
+  UMA_HISTOGRAM_COUNTS_1M(
+      "Net.JobControllerSet.CountOfJobController.NonPreconnect.PendingRequest",
+      num_controllers_with_request);
+
+  UMA_HISTOGRAM_COUNTS_1M(
+      "Net.JobControllerSet.CountOfJobController.NonPreconnect.RequestGone",
+      job_controller_set_.size() - num_controllers_for_preconnect -
+          num_controllers_with_request);
+
   UMA_HISTOGRAM_COUNTS_1M("Net.JobControllerSet.CountOfNonPreconnectAltJob",
                           alt_job_count);
   UMA_HISTOGRAM_COUNTS_1M("Net.JobControllerSet.CountOfNonPreconnectMainJob",
                           main_job_count);
-  UMA_HISTOGRAM_COUNTS_1M("Net.JobControllerSet.CountOfPendingRequest",
-                          pending_request_count);
 }
 
 void HttpStreamFactoryImpl::DumpMemoryStats(
@@ -415,11 +423,11 @@
       pmd->CreateAllocatorDump(name);
   size_t alt_job_count = 0;
   size_t main_job_count = 0;
-  size_t preconnect_controller_count = 0;
+  size_t num_controllers_for_preconnect = 0;
   for (const auto& it : job_controller_set_) {
     // For a preconnect controller, it should have exactly the main job.
     if (it->is_preconnect()) {
-      preconnect_controller_count++;
+      num_controllers_for_preconnect++;
       continue;
     }
     // For non-preconnects.
@@ -447,7 +455,7 @@
   // The number of preconnect controllers.
   factory_dump->AddScalar("preconnect_count",
                           base::trace_event::MemoryAllocatorDump::kUnitsObjects,
-                          preconnect_controller_count);
+                          num_controllers_for_preconnect);
 }
 
 }  // namespace net
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h
index b7b9d5c..9653c7a 100644
--- a/net/log/net_log_event_type_list.h
+++ b/net/log/net_log_event_type_list.h
@@ -480,7 +480,6 @@
 // The SSL stack blocked on a private key operation. The following parameters
 // are attached to the event.
 //   {
-//     "type": <type of the key>,
 //     "hash": <hash function used>,
 //   }
 EVENT_TYPE(SSL_PRIVATE_KEY_OP)
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index a5f1bbc..9bbc41d 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -108,25 +108,8 @@
 }
 
 std::unique_ptr<base::Value> NetLogPrivateKeyOperationCallback(
-    SSLPrivateKey::Type type,
     SSLPrivateKey::Hash hash,
     NetLogCaptureMode mode) {
-  std::string type_str;
-  switch (type) {
-    case SSLPrivateKey::Type::RSA:
-      type_str = "RSA";
-      break;
-    case SSLPrivateKey::Type::ECDSA_P256:
-      type_str = "ECDSA_P256";
-      break;
-    case SSLPrivateKey::Type::ECDSA_P384:
-      type_str = "ECDSA_P384";
-      break;
-    case SSLPrivateKey::Type::ECDSA_P521:
-      type_str = "ECDSA_P521";
-      break;
-  }
-
   std::string hash_str;
   switch (hash) {
     case SSLPrivateKey::Hash::MD5_SHA1:
@@ -147,7 +130,6 @@
   }
 
   std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue);
-  value->SetString("type", type_str);
   value->SetString("hash", hash_str);
   return std::move(value);
 }
@@ -407,16 +389,6 @@
     return socket->NewSessionCallback(session);
   }
 
-  static int PrivateKeyTypeCallback(SSL* ssl) {
-    SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl);
-    return socket->PrivateKeyTypeCallback();
-  }
-
-  static size_t PrivateKeyMaxSignatureLenCallback(SSL* ssl) {
-    SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl);
-    return socket->PrivateKeyMaxSignatureLenCallback();
-  }
-
   static ssl_private_key_result_t PrivateKeySignDigestCallback(
       SSL* ssl,
       uint8_t* out,
@@ -476,8 +448,8 @@
 // TODO(davidben): Switch from sign_digest to sign.
 const SSL_PRIVATE_KEY_METHOD
     SSLClientSocketImpl::SSLContext::kPrivateKeyMethod = {
-        &SSLClientSocketImpl::SSLContext::PrivateKeyTypeCallback,
-        &SSLClientSocketImpl::SSLContext::PrivateKeyMaxSignatureLenCallback,
+        nullptr /* type (unused) */,
+        nullptr /* max_signature_len (unused) */,
         nullptr /* sign */,
         &SSLClientSocketImpl::SSLContext::PrivateKeySignDigestCallback,
         nullptr /* decrypt */,
@@ -1772,25 +1744,6 @@
   return false;
 }
 
-int SSLClientSocketImpl::PrivateKeyTypeCallback() {
-  switch (ssl_config_.client_private_key->GetType()) {
-    case SSLPrivateKey::Type::RSA:
-      return NID_rsaEncryption;
-    case SSLPrivateKey::Type::ECDSA_P256:
-      return NID_X9_62_prime256v1;
-    case SSLPrivateKey::Type::ECDSA_P384:
-      return NID_secp384r1;
-    case SSLPrivateKey::Type::ECDSA_P521:
-      return NID_secp521r1;
-  }
-  NOTREACHED();
-  return NID_undef;
-}
-
-size_t SSLClientSocketImpl::PrivateKeyMaxSignatureLenCallback() {
-  return ssl_config_.client_private_key->GetMaxSignatureLengthInBytes();
-}
-
 ssl_private_key_result_t SSLClientSocketImpl::PrivateKeySignDigestCallback(
     uint8_t* out,
     size_t* out_len,
@@ -1808,10 +1761,8 @@
     return ssl_private_key_failure;
   }
 
-  net_log_.BeginEvent(
-      NetLogEventType::SSL_PRIVATE_KEY_OP,
-      base::Bind(&NetLogPrivateKeyOperationCallback,
-                 ssl_config_.client_private_key->GetType(), hash));
+  net_log_.BeginEvent(NetLogEventType::SSL_PRIVATE_KEY_OP,
+                      base::Bind(&NetLogPrivateKeyOperationCallback, hash));
 
   signature_result_ = ERR_IO_PENDING;
   ssl_config_.client_private_key->SignDigest(
diff --git a/net/socket/ssl_client_socket_impl.h b/net/socket/ssl_client_socket_impl.h
index 5eda482..51ee5fc 100644
--- a/net/socket/ssl_client_socket_impl.h
+++ b/net/socket/ssl_client_socket_impl.h
@@ -201,8 +201,6 @@
   bool IsRenegotiationAllowed() const;
 
   // Callbacks for operations with the private key.
-  int PrivateKeyTypeCallback();
-  size_t PrivateKeyMaxSignatureLenCallback();
   ssl_private_key_result_t PrivateKeySignDigestCallback(uint8_t* out,
                                                         size_t* out_len,
                                                         size_t max_out,
diff --git a/net/ssl/openssl_client_key_store_unittest.cc b/net/ssl/openssl_client_key_store_unittest.cc
index 52cea2f..160769bdf 100644
--- a/net/ssl/openssl_client_key_store_unittest.cc
+++ b/net/ssl/openssl_client_key_store_unittest.cc
@@ -38,21 +38,11 @@
 
   void set_on_destroyed(bool* on_destroyed) { on_destroyed_ = on_destroyed; }
 
-  Type GetType() override {
-    NOTREACHED();
-    return Type::RSA;
-  }
-
   std::vector<Hash> GetDigestPreferences() override {
     NOTREACHED();
     return {};
   }
 
-  size_t GetMaxSignatureLengthInBytes() override {
-    NOTREACHED();
-    return 0;
-  }
-
   void SignDigest(Hash hash,
                   const base::StringPiece& input,
                   const SignCallback& callback) override {
diff --git a/net/ssl/ssl_client_auth_cache_unittest.cc b/net/ssl/ssl_client_auth_cache_unittest.cc
index c6b608b..f61c3a0 100644
--- a/net/ssl/ssl_client_auth_cache_unittest.cc
+++ b/net/ssl/ssl_client_auth_cache_unittest.cc
@@ -18,18 +18,11 @@
  public:
   MockSSLPrivateKey() {}
 
-  Type GetType() override { return Type::RSA; }
-
   std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
     NOTIMPLEMENTED();
     return std::vector<SSLPrivateKey::Hash>();
   }
 
-  size_t GetMaxSignatureLengthInBytes() override {
-    NOTIMPLEMENTED();
-    return 0;
-  }
-
   void SignDigest(Hash hash,
                   const base::StringPiece& input,
                   const SignCallback& callback) override {
diff --git a/net/ssl/ssl_platform_key_android.cc b/net/ssl/ssl_platform_key_android.cc
index 136c63ad..48ab99ac 100644
--- a/net/ssl/ssl_platform_key_android.cc
+++ b/net/ssl/ssl_platform_key_android.cc
@@ -24,6 +24,7 @@
 #include "net/ssl/ssl_platform_key_util.h"
 #include "net/ssl/threaded_ssl_private_key.h"
 #include "third_party/boringssl/src/include/openssl/ecdsa.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
 #include "third_party/boringssl/src/include/openssl/mem.h"
 #include "third_party/boringssl/src/include/openssl/nid.h"
 #include "third_party/boringssl/src/include/openssl/rsa.h"
@@ -74,7 +75,7 @@
 
 class SSLPlatformKeyAndroid : public ThreadedSSLPrivateKey::Delegate {
  public:
-  SSLPlatformKeyAndroid(SSLPrivateKey::Type type,
+  SSLPlatformKeyAndroid(int type,
                         const JavaRef<jobject>& key,
                         size_t max_length,
                         android::AndroidRSA* legacy_rsa)
@@ -84,8 +85,6 @@
 
   ~SSLPlatformKeyAndroid() override {}
 
-  SSLPrivateKey::Type GetType() override { return type_; }
-
   std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
     static const SSLPrivateKey::Hash kHashes[] = {
         SSLPrivateKey::Hash::SHA512, SSLPrivateKey::Hash::SHA384,
@@ -94,8 +93,6 @@
                                             kHashes + arraysize(kHashes));
   }
 
-  size_t GetMaxSignatureLengthInBytes() override { return max_length_; }
-
   Error SignDigest(SSLPrivateKey::Hash hash,
                    const base::StringPiece& input_in,
                    std::vector<uint8_t>* signature) override {
@@ -103,7 +100,7 @@
 
     // Prepend the DigestInfo for RSA.
     bssl::UniquePtr<uint8_t> digest_info_storage;
-    if (type_ == SSLPrivateKey::Type::RSA) {
+    if (type_ == EVP_PKEY_RSA) {
       int hash_nid = NID_undef;
       switch (hash) {
         case SSLPrivateKey::Hash::MD5_SHA1:
@@ -168,7 +165,7 @@
   }
 
  private:
-  SSLPrivateKey::Type type_;
+  int type_;
   ScopedJavaGlobalRef<jobject> key_;
   size_t max_length_;
   android::AndroidRSA* legacy_rsa_;
@@ -181,13 +178,13 @@
 scoped_refptr<SSLPrivateKey> WrapJavaPrivateKey(
     const X509Certificate* certificate,
     const JavaRef<jobject>& key) {
-  SSLPrivateKey::Type type;
+  int type;
   size_t max_length;
   if (!GetClientCertInfo(certificate, &type, &max_length))
     return nullptr;
 
   android::AndroidRSA* sys_rsa = nullptr;
-  if (type == SSLPrivateKey::Type::RSA) {
+  if (type == EVP_PKEY_RSA) {
     const int kAndroid42ApiLevel = 17;
     if (base::android::BuildInfo::GetInstance()->sdk_int() <
         kAndroid42ApiLevel) {
diff --git a/net/ssl/ssl_platform_key_android_unittest.cc b/net/ssl/ssl_platform_key_android_unittest.cc
index ff2c2c50..37f7be7 100644
--- a/net/ssl/ssl_platform_key_android_unittest.cc
+++ b/net/ssl/ssl_platform_key_android_unittest.cc
@@ -48,25 +48,24 @@
 }
 
 struct TestKey {
+  const char* name;
   const char* cert_file;
   const char* key_file;
   android::PrivateKeyType android_key_type;
-  SSLPrivateKey::Type key_type;
 };
 
 const TestKey kTestKeys[] = {
-    {"client_1.pem", "client_1.pk8", android::PRIVATE_KEY_TYPE_RSA,
-     SSLPrivateKey::Type::RSA},
-    {"client_4.pem", "client_4.pk8", android::PRIVATE_KEY_TYPE_ECDSA,
-     SSLPrivateKey::Type::ECDSA_P256},
-    {"client_5.pem", "client_5.pk8", android::PRIVATE_KEY_TYPE_ECDSA,
-     SSLPrivateKey::Type::ECDSA_P384},
-    {"client_6.pem", "client_6.pk8", android::PRIVATE_KEY_TYPE_ECDSA,
-     SSLPrivateKey::Type::ECDSA_P521},
+    {"RSA", "client_1.pem", "client_1.pk8", android::PRIVATE_KEY_TYPE_RSA},
+    {"ECDSA_P256", "client_4.pem", "client_4.pk8",
+     android::PRIVATE_KEY_TYPE_ECDSA},
+    {"ECDSA_P384", "client_5.pem", "client_5.pk8",
+     android::PRIVATE_KEY_TYPE_ECDSA},
+    {"ECDSA_P521", "client_6.pem", "client_6.pk8",
+     android::PRIVATE_KEY_TYPE_ECDSA},
 };
 
 std::string TestKeyToString(const testing::TestParamInfo<TestKey>& params) {
-  return SSLPrivateKeyTypeToString(params.param.key_type);
+  return params.param.name;
 }
 
 }  // namespace
diff --git a/net/ssl/ssl_platform_key_chromecast.cc b/net/ssl/ssl_platform_key_chromecast.cc
index 5993a3bb..1b4d2da3 100644
--- a/net/ssl/ssl_platform_key_chromecast.cc
+++ b/net/ssl/ssl_platform_key_chromecast.cc
@@ -38,20 +38,11 @@
       : key_(std::move(key)) {}
   ~SSLPlatformKeyChromecast() override {}
 
-  SSLPrivateKey::Type GetType() override { return SSLPrivateKey::Type::RSA; }
-
   std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
     return std::vector<SSLPrivateKey::Hash>{SSLPrivateKey::Hash::SHA256,
                                             SSLPrivateKey::Hash::SHA1};
   }
 
-  size_t GetMaxSignatureLengthInBytes() override {
-    int len = PK11_SignatureLen(key_.get());
-    if (len <= 0)
-      return 0;
-    return static_cast<size_t>(len);
-  }
-
   Error SignDigest(SSLPrivateKey::Hash hash,
                    const base::StringPiece& input,
                    std::vector<uint8_t>* signature) override {
diff --git a/net/ssl/ssl_platform_key_mac.cc b/net/ssl/ssl_platform_key_mac.cc
index 1f7e3ef..c4be83d 100644
--- a/net/ssl/ssl_platform_key_mac.cc
+++ b/net/ssl/ssl_platform_key_mac.cc
@@ -36,6 +36,7 @@
 #include "net/ssl/ssl_private_key.h"
 #include "net/ssl/threaded_ssl_private_key.h"
 #include "third_party/boringssl/src/include/openssl/ecdsa.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
 #include "third_party/boringssl/src/include/openssl/mem.h"
 #include "third_party/boringssl/src/include/openssl/nid.h"
 #include "third_party/boringssl/src/include/openssl/rsa.h"
@@ -173,27 +174,22 @@
 
 class SSLPlatformKeyCSSM : public ThreadedSSLPrivateKey::Delegate {
  public:
-  SSLPlatformKeyCSSM(SSLPrivateKey::Type type,
+  SSLPlatformKeyCSSM(int type,
                      size_t max_length,
                      SecKeyRef key,
                      const CSSM_KEY* cssm_key)
-      : type_(type),
-        max_length_(max_length),
+      : max_length_(max_length),
         key_(key, base::scoped_policy::RETAIN),
         cssm_key_(cssm_key) {}
 
   ~SSLPlatformKeyCSSM() override {}
 
-  SSLPrivateKey::Type GetType() override { return type_; }
-
   std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
     return std::vector<SSLPrivateKey::Hash>{
         SSLPrivateKey::Hash::SHA512, SSLPrivateKey::Hash::SHA384,
         SSLPrivateKey::Hash::SHA256, SSLPrivateKey::Hash::SHA1};
   }
 
-  size_t GetMaxSignatureLengthInBytes() override { return max_length_; }
-
   Error SignDigest(SSLPrivateKey::Hash hash,
                    const base::StringPiece& input,
                    std::vector<uint8_t>* signature) override {
@@ -282,7 +278,6 @@
   }
 
  private:
-  SSLPrivateKey::Type type_;
   size_t max_length_;
   base::ScopedCFTypeRef<SecKeyRef> key_;
   const CSSM_KEY* cssm_key_;
@@ -292,25 +287,17 @@
 
 class SSLPlatformKeySecKey : public ThreadedSSLPrivateKey::Delegate {
  public:
-  SSLPlatformKeySecKey(SSLPrivateKey::Type type,
-                       size_t max_length,
-                       SecKeyRef key)
-      : type_(type),
-        max_length_(max_length),
-        key_(key, base::scoped_policy::RETAIN) {}
+  SSLPlatformKeySecKey(int type, size_t max_length, SecKeyRef key)
+      : type_(type), key_(key, base::scoped_policy::RETAIN) {}
 
   ~SSLPlatformKeySecKey() override {}
 
-  SSLPrivateKey::Type GetType() override { return type_; }
-
   std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
     return std::vector<SSLPrivateKey::Hash>{
         SSLPrivateKey::Hash::SHA512, SSLPrivateKey::Hash::SHA384,
         SSLPrivateKey::Hash::SHA256, SSLPrivateKey::Hash::SHA1};
   }
 
-  size_t GetMaxSignatureLengthInBytes() override { return max_length_; }
-
   Error SignDigest(SSLPrivateKey::Hash hash,
                    const base::StringPiece& input,
                    std::vector<uint8_t>* signature) override {
@@ -321,7 +308,7 @@
     }
 
     SecKeyAlgorithm algorithm = nullptr;
-    if (type_ == SSLPrivateKey::Type::RSA) {
+    if (type_ == EVP_PKEY_RSA) {
       switch (hash) {
         case SSLPrivateKey::Hash::SHA512:
           algorithm = apis.kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512;
@@ -339,7 +326,7 @@
           algorithm = apis.kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw;
           break;
       }
-    } else if (SSLPrivateKey::IsECDSAType(type_)) {
+    } else if (type_ == EVP_PKEY_EC) {
       switch (hash) {
         case SSLPrivateKey::Hash::SHA512:
           algorithm = apis.kSecKeyAlgorithmECDSASignatureDigestX962SHA512;
@@ -383,8 +370,7 @@
   }
 
  private:
-  SSLPrivateKey::Type type_;
-  size_t max_length_;
+  int type_;
   base::ScopedCFTypeRef<SecKeyRef> key_;
 
   DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeySecKey);
@@ -401,7 +387,7 @@
   if (!private_key)
     return nullptr;
 
-  SSLPrivateKey::Type key_type;
+  int key_type;
   size_t max_length;
   if (!GetClientCertInfo(certificate, &key_type, &max_length))
     return nullptr;
diff --git a/net/ssl/ssl_platform_key_mac_unittest.cc b/net/ssl/ssl_platform_key_mac_unittest.cc
index e35af63..643fa15c5 100644
--- a/net/ssl/ssl_platform_key_mac_unittest.cc
+++ b/net/ssl/ssl_platform_key_mac_unittest.cc
@@ -33,20 +33,20 @@
 namespace {
 
 struct TestKey {
+  const char* name;
   const char* cert_file;
   const char* key_file;
-  SSLPrivateKey::Type key_type;
 };
 
 const TestKey kTestKeys[] = {
-    {"client_1.pem", "client_1.pk8", SSLPrivateKey::Type::RSA},
-    {"client_4.pem", "client_4.pk8", SSLPrivateKey::Type::ECDSA_P256},
-    {"client_5.pem", "client_5.pk8", SSLPrivateKey::Type::ECDSA_P384},
-    {"client_6.pem", "client_6.pk8", SSLPrivateKey::Type::ECDSA_P521},
+    {"RSA", "client_1.pem", "client_1.pk8"},
+    {"ECDSA_P256", "client_4.pem", "client_4.pk8"},
+    {"ECDSA_P384", "client_5.pem", "client_5.pk8"},
+    {"ECDSA_P521", "client_6.pem", "client_6.pk8"},
 };
 
 std::string TestKeyToString(const testing::TestParamInfo<TestKey>& params) {
-  return SSLPrivateKeyTypeToString(params.param.key_type);
+  return params.param.name;
 }
 
 }  // namespace
diff --git a/net/ssl/ssl_platform_key_nss.cc b/net/ssl/ssl_platform_key_nss.cc
index 447b230..e63fb18 100644
--- a/net/ssl/ssl_platform_key_nss.cc
+++ b/net/ssl/ssl_platform_key_nss.cc
@@ -24,6 +24,7 @@
 #include "third_party/boringssl/src/include/openssl/ec.h"
 #include "third_party/boringssl/src/include/openssl/ec_key.h"
 #include "third_party/boringssl/src/include/openssl/ecdsa.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
 #include "third_party/boringssl/src/include/openssl/mem.h"
 #include "third_party/boringssl/src/include/openssl/nid.h"
 #include "third_party/boringssl/src/include/openssl/rsa.h"
@@ -42,14 +43,10 @@
 
 class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate {
  public:
-  SSLPlatformKeyNSS(SSLPrivateKey::Type type,
-                    size_t max_length,
-                    crypto::ScopedSECKEYPrivateKey key)
-      : type_(type), max_length_(max_length), key_(std::move(key)) {}
+  SSLPlatformKeyNSS(int type, crypto::ScopedSECKEYPrivateKey key)
+      : type_(type), key_(std::move(key)) {}
   ~SSLPlatformKeyNSS() override {}
 
-  SSLPrivateKey::Type GetType() override { return type_; }
-
   std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
     static const SSLPrivateKey::Hash kHashes[] = {
         SSLPrivateKey::Hash::SHA512, SSLPrivateKey::Hash::SHA384,
@@ -58,8 +55,6 @@
                                             kHashes + arraysize(kHashes));
   }
 
-  size_t GetMaxSignatureLengthInBytes() override { return max_length_; }
-
   Error SignDigest(SSLPrivateKey::Hash hash,
                    const base::StringPiece& input,
                    std::vector<uint8_t>* signature) override {
@@ -69,7 +64,7 @@
     digest_item.len = input.size();
 
     bssl::UniquePtr<uint8_t> free_digest_info;
-    if (type_ == SSLPrivateKey::Type::RSA) {
+    if (type_ == EVP_PKEY_RSA) {
       // PK11_Sign expects the caller to prepend the DigestInfo.
       int hash_nid = NID_undef;
       switch (hash) {
@@ -120,7 +115,7 @@
 
     // NSS emits raw ECDSA signatures, but BoringSSL expects a DER-encoded
     // ECDSA-Sig-Value.
-    if (SSLPrivateKey::IsECDSAType(type_)) {
+    if (type_ == EVP_PKEY_EC) {
       if (signature->size() % 2 != 0) {
         LOG(ERROR) << "Bad signature length";
         return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
@@ -149,8 +144,7 @@
   }
 
  private:
-  SSLPrivateKey::Type type_;
-  size_t max_length_;
+  int type_;
   crypto::ScopedSECKEYPrivateKey key_;
 
   DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyNSS);
@@ -167,13 +161,13 @@
         *certificate);
   }
 
-  SSLPrivateKey::Type type;
+  int type;
   size_t max_length;
   if (!GetClientCertInfo(certificate, &type, &max_length))
     return nullptr;
 
   return make_scoped_refptr(new ThreadedSSLPrivateKey(
-      base::MakeUnique<SSLPlatformKeyNSS>(type, max_length, std::move(key)),
+      base::MakeUnique<SSLPlatformKeyNSS>(type, std::move(key)),
       GetSSLPlatformKeyTaskRunner()));
 }
 
diff --git a/net/ssl/ssl_platform_key_nss_unittest.cc b/net/ssl/ssl_platform_key_nss_unittest.cc
index 350c462..2d40ba17 100644
--- a/net/ssl/ssl_platform_key_nss_unittest.cc
+++ b/net/ssl/ssl_platform_key_nss_unittest.cc
@@ -35,20 +35,21 @@
 namespace {
 
 struct TestKey {
+  const char* name;
   const char* cert_file;
   const char* key_file;
-  SSLPrivateKey::Type key_type;
+  bool is_ecdsa;
 };
 
 const TestKey kTestKeys[] = {
-    {"client_1.pem", "client_1.pk8", SSLPrivateKey::Type::RSA},
-    {"client_4.pem", "client_4.pk8", SSLPrivateKey::Type::ECDSA_P256},
-    {"client_5.pem", "client_5.pk8", SSLPrivateKey::Type::ECDSA_P384},
-    {"client_6.pem", "client_6.pk8", SSLPrivateKey::Type::ECDSA_P521},
+    {"RSA", "client_1.pem", "client_1.pk8", false},
+    {"ECDSA_P256", "client_4.pem", "client_4.pk8", true},
+    {"ECDSA_P384", "client_5.pem", "client_5.pk8", true},
+    {"ECDSA_P521", "client_6.pem", "client_6.pk8", true},
 };
 
 std::string TestKeyToString(const testing::TestParamInfo<TestKey>& params) {
-  return SSLPrivateKeyTypeToString(params.param.key_type);
+  return params.param.name;
 }
 
 }  // namespace
@@ -66,7 +67,7 @@
   // Import the key into a test NSS database.
   crypto::ScopedTestNSSDB test_db;
   scoped_refptr<X509Certificate> cert;
-  if (SSLPrivateKey::IsECDSAType(test_key.key_type)) {
+  if (test_key.is_ecdsa) {
     // NSS cannot import unencrypted ECDSA keys, so we encrypt it with an empty
     // password and import manually.
     std::vector<uint8_t> pkcs8_vector(pkcs8.begin(), pkcs8.end());
diff --git a/net/ssl/ssl_platform_key_util.cc b/net/ssl/ssl_platform_key_util.cc
index 39af9eb..edee7db 100644
--- a/net/ssl/ssl_platform_key_util.cc
+++ b/net/ssl/ssl_platform_key_util.cc
@@ -50,7 +50,7 @@
 }
 
 bool GetClientCertInfo(const X509Certificate* certificate,
-                       SSLPrivateKey::Type* out_type,
+                       int* out_type,
                        size_t* out_max_length) {
   crypto::OpenSSLErrStackTracer tracker(FROM_HERE);
 
@@ -71,37 +71,7 @@
     return false;
   }
 
-  int key_type = EVP_PKEY_id(key.get());
-  switch (key_type) {
-    case EVP_PKEY_RSA:
-      *out_type = SSLPrivateKey::Type::RSA;
-      break;
-
-    case EVP_PKEY_EC: {
-      EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key.get());
-      int curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key));
-      switch (curve) {
-        case NID_X9_62_prime256v1:
-          *out_type = SSLPrivateKey::Type::ECDSA_P256;
-          break;
-        case NID_secp384r1:
-          *out_type = SSLPrivateKey::Type::ECDSA_P384;
-          break;
-        case NID_secp521r1:
-          *out_type = SSLPrivateKey::Type::ECDSA_P521;
-          break;
-        default:
-          LOG(ERROR) << "Unsupported curve type " << curve;
-          return false;
-      }
-      break;
-    }
-
-    default:
-      LOG(ERROR) << "Unsupported key type " << key_type;
-      return false;
-  }
-
+  *out_type = EVP_PKEY_id(key.get());
   *out_max_length = EVP_PKEY_size(key.get());
   return true;
 }
diff --git a/net/ssl/ssl_platform_key_util.h b/net/ssl/ssl_platform_key_util.h
index 31ee091..2154fc5 100644
--- a/net/ssl/ssl_platform_key_util.h
+++ b/net/ssl/ssl_platform_key_util.h
@@ -10,7 +10,6 @@
 #include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
 #include "net/base/net_export.h"
-#include "net/ssl/ssl_private_key.h"
 
 namespace net {
 
@@ -23,9 +22,10 @@
 scoped_refptr<base::SingleThreadTaskRunner> GetSSLPlatformKeyTaskRunner();
 
 // Determines the key type and maximum signature length of |certificate|'s
-// public key.
+// public key. |*out_type| will be set to one of the |EVP_PKEY_*| values from
+// BoringSSL.
 NET_EXPORT_PRIVATE bool GetClientCertInfo(const X509Certificate* certificate,
-                                          SSLPrivateKey::Type* out_type,
+                                          int* out_type,
                                           size_t* out_max_length);
 
 }  // namespace net
diff --git a/net/ssl/ssl_platform_key_util_unittest.cc b/net/ssl/ssl_platform_key_util_unittest.cc
index 8a00034..e8c2a02 100644
--- a/net/ssl/ssl_platform_key_util_unittest.cc
+++ b/net/ssl/ssl_platform_key_util_unittest.cc
@@ -13,13 +13,14 @@
 #include "net/test/test_data_directory.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/boringssl/src/include/openssl/ecdsa.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
 
 namespace net {
 
 namespace {
 
 bool GetClientCertInfoFromFile(const char* filename,
-                               SSLPrivateKey::Type* out_type,
+                               int* out_type,
                                size_t* out_max_length) {
   scoped_refptr<X509Certificate> cert =
       ImportCertFromFile(GetTestCertsDirectory(), filename);
@@ -38,23 +39,23 @@
 }  // namespace
 
 TEST(SSLPlatformKeyUtil, GetClientCertInfo) {
-  SSLPrivateKey::Type type;
+  int type;
   size_t max_length;
 
   ASSERT_TRUE(GetClientCertInfoFromFile("client_1.pem", &type, &max_length));
-  EXPECT_EQ(SSLPrivateKey::Type::RSA, type);
+  EXPECT_EQ(EVP_PKEY_RSA, type);
   EXPECT_EQ(2048u / 8u, max_length);
 
   ASSERT_TRUE(GetClientCertInfoFromFile("client_4.pem", &type, &max_length));
-  EXPECT_EQ(SSLPrivateKey::Type::ECDSA_P256, type);
+  EXPECT_EQ(EVP_PKEY_EC, type);
   EXPECT_EQ(ECDSA_SIG_max_len(BitsToBytes(256)), max_length);
 
   ASSERT_TRUE(GetClientCertInfoFromFile("client_5.pem", &type, &max_length));
-  EXPECT_EQ(SSLPrivateKey::Type::ECDSA_P384, type);
+  EXPECT_EQ(EVP_PKEY_EC, type);
   EXPECT_EQ(ECDSA_SIG_max_len(BitsToBytes(384)), max_length);
 
   ASSERT_TRUE(GetClientCertInfoFromFile("client_6.pem", &type, &max_length));
-  EXPECT_EQ(SSLPrivateKey::Type::ECDSA_P521, type);
+  EXPECT_EQ(EVP_PKEY_EC, type);
   EXPECT_EQ(ECDSA_SIG_max_len(BitsToBytes(521)), max_length);
 }
 
diff --git a/net/ssl/ssl_platform_key_win.cc b/net/ssl/ssl_platform_key_win.cc
index a7df502..c2684d97 100644
--- a/net/ssl/ssl_platform_key_win.cc
+++ b/net/ssl/ssl_platform_key_win.cc
@@ -33,13 +33,11 @@
 class SSLPlatformKeyCAPI : public ThreadedSSLPrivateKey::Delegate {
  public:
   // Takes ownership of |provider|.
-  SSLPlatformKeyCAPI(HCRYPTPROV provider, DWORD key_spec, size_t max_length)
-      : provider_(provider), key_spec_(key_spec), max_length_(max_length) {}
+  SSLPlatformKeyCAPI(HCRYPTPROV provider, DWORD key_spec)
+      : provider_(provider), key_spec_(key_spec) {}
 
   ~SSLPlatformKeyCAPI() override {}
 
-  SSLPrivateKey::Type GetType() override { return SSLPrivateKey::Type::RSA; }
-
   std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
     // If the key is in CAPI, assume conservatively that the CAPI service
     // provider may only be able to sign pre-TLS-1.2 and SHA-1 hashes.
@@ -50,8 +48,6 @@
                                             kHashes + arraysize(kHashes));
   }
 
-  size_t GetMaxSignatureLengthInBytes() override { return max_length_; }
-
   Error SignDigest(SSLPrivateKey::Hash hash,
                    const base::StringPiece& input,
                    std::vector<uint8_t>* signature) override {
@@ -118,7 +114,6 @@
  private:
   crypto::ScopedHCRYPTPROV provider_;
   DWORD key_spec_;
-  size_t max_length_;
 
   DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyCAPI);
 };
@@ -126,21 +121,17 @@
 class SSLPlatformKeyCNG : public ThreadedSSLPrivateKey::Delegate {
  public:
   // Takes ownership of |key|.
-  SSLPlatformKeyCNG(NCRYPT_KEY_HANDLE key,
-                    SSLPrivateKey::Type type,
-                    size_t max_length)
+  SSLPlatformKeyCNG(NCRYPT_KEY_HANDLE key, int type, size_t max_length)
       : key_(key), type_(type), max_length_(max_length) {}
 
   ~SSLPlatformKeyCNG() override { NCryptFreeObject(key_); }
 
-  SSLPrivateKey::Type GetType() override { return type_; }
-
   std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
     // If this is an under 1024-bit RSA key, conservatively prefer to sign
     // SHA-1 hashes. Older Estonian ID cards can only sign SHA-1 hashes.
     // However, if the server doesn't advertise SHA-1, the remaining hashes
     // might still be supported.
-    if (type_ == SSLPrivateKey::Type::RSA && max_length_ <= 1024 / 8) {
+    if (type_ == EVP_PKEY_RSA && max_length_ <= 1024 / 8) {
       static const SSLPrivateKey::Hash kHashesSpecial[] = {
           SSLPrivateKey::Hash::SHA1, SSLPrivateKey::Hash::SHA512,
           SSLPrivateKey::Hash::SHA384, SSLPrivateKey::Hash::SHA256};
@@ -154,8 +145,6 @@
                                             kHashes + arraysize(kHashes));
   }
 
-  size_t GetMaxSignatureLengthInBytes() override { return max_length_; }
-
   Error SignDigest(SSLPrivateKey::Hash hash,
                    const base::StringPiece& input,
                    std::vector<uint8_t>* signature) override {
@@ -164,7 +153,7 @@
     BCRYPT_PKCS1_PADDING_INFO rsa_padding_info = {0};
     void* padding_info = nullptr;
     DWORD flags = 0;
-    if (type_ == SSLPrivateKey::Type::RSA) {
+    if (type_ == EVP_PKEY_RSA) {
       switch (hash) {
         case SSLPrivateKey::Hash::MD5_SHA1:
           rsa_padding_info.pszAlgId = nullptr;
@@ -208,7 +197,7 @@
 
     // CNG emits raw ECDSA signatures, but BoringSSL expects a DER-encoded
     // ECDSA-Sig-Value.
-    if (SSLPrivateKey::IsECDSAType(type_)) {
+    if (type_ == EVP_PKEY_EC) {
       if (signature->size() % 2 != 0) {
         LOG(ERROR) << "Bad signature length";
         return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
@@ -238,7 +227,7 @@
 
  private:
   NCRYPT_KEY_HANDLE key_;
-  SSLPrivateKey::Type type_;
+  int type_;
   size_t max_length_;
 
   DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyCNG);
@@ -251,7 +240,7 @@
   // Rather than query the private key for metadata, extract the public key from
   // the certificate without using Windows APIs. CAPI and CNG do not
   // consistently work depending on the system. See https://crbug.com/468345.
-  SSLPrivateKey::Type key_type;
+  int key_type;
   size_t max_length;
   if (!GetClientCertInfo(certificate, &key_type, &max_length))
     return nullptr;
@@ -277,8 +266,8 @@
   if (key_spec == CERT_NCRYPT_KEY_SPEC) {
     delegate.reset(new SSLPlatformKeyCNG(prov_or_key, key_type, max_length));
   } else {
-    DCHECK(SSLPrivateKey::Type::RSA == key_type);
-    delegate.reset(new SSLPlatformKeyCAPI(prov_or_key, key_spec, max_length));
+    DCHECK_EQ(EVP_PKEY_RSA, key_type);
+    delegate.reset(new SSLPlatformKeyCAPI(prov_or_key, key_spec));
   }
   return make_scoped_refptr(new ThreadedSSLPrivateKey(
       std::move(delegate), GetSSLPlatformKeyTaskRunner()));
diff --git a/net/ssl/ssl_private_key.h b/net/ssl/ssl_private_key.h
index 145cd503..0c877a5f 100644
--- a/net/ssl/ssl_private_key.h
+++ b/net/ssl/ssl_private_key.h
@@ -23,19 +23,6 @@
  public:
   using SignCallback = base::Callback<void(Error, const std::vector<uint8_t>&)>;
 
-  enum class Type {
-    RSA,
-    ECDSA_P256,
-    ECDSA_P384,
-    ECDSA_P521,
-  };
-
-  // Returns true if |type| is an ECDSA key type.
-  static bool IsECDSAType(Type type) {
-    return type == Type::ECDSA_P256 || type == Type::ECDSA_P384 ||
-           type == Type::ECDSA_P521;
-  }
-
   enum class Hash {
     MD5_SHA1,
     SHA1,
@@ -46,21 +33,9 @@
 
   SSLPrivateKey() {}
 
-  // Returns whether the key is an RSA key or an ECDSA key. Although the signing
-  // interface is type-agnositic and type tags in interfaces are discouraged,
-  // TLS has key-specific logic in selecting which hashes to sign. Exposing the
-  // key type avoids replicating BoringSSL's TLS-specific logic in SSLPrivateKey
-  // implementations and complicating the interface between Chromium and
-  // BoringSSL.
-  virtual Type GetType() = 0;
-
   // Returns the digests that are supported by the key in decreasing preference.
   virtual std::vector<SSLPrivateKey::Hash> GetDigestPreferences() = 0;
 
-  // Returns the maximum size of a signature, in bytes. For an RSA key, this
-  // must be the size of the modulus.
-  virtual size_t GetMaxSignatureLengthInBytes() = 0;
-
   // Asynchronously signs an |input| which was computed with the hash |hash|. On
   // completion, it calls |callback| with the signature or an error code if the
   // operation failed. For an RSA key, the signature is a PKCS#1 signature. The
diff --git a/net/ssl/ssl_private_key_test_util.cc b/net/ssl/ssl_private_key_test_util.cc
index ddeaca7..18aa49e 100644
--- a/net/ssl/ssl_private_key_test_util.cc
+++ b/net/ssl/ssl_private_key_test_util.cc
@@ -66,27 +66,6 @@
   return nullptr;
 }
 
-SSLPrivateKey::Type TypeForOpenSSLKey(EVP_PKEY* pkey) {
-  switch (EVP_PKEY_id(pkey)) {
-    case EVP_PKEY_RSA:
-      return SSLPrivateKey::Type::RSA;
-    case EVP_PKEY_EC: {
-      switch (EC_GROUP_get_curve_name(
-          EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey)))) {
-        case NID_X9_62_prime256v1:
-          return SSLPrivateKey::Type::ECDSA_P256;
-        case NID_secp384r1:
-          return SSLPrivateKey::Type::ECDSA_P384;
-        case NID_secp521r1:
-          return SSLPrivateKey::Type::ECDSA_P521;
-      }
-    }
-  }
-
-  NOTREACHED();
-  return SSLPrivateKey::Type::RSA;
-}
-
 // Resize a string to |size| bytes of data, then return its data buffer address
 // cast as an 'uint8_t*', as expected by OpenSSL functions.
 // |str| the target string.
@@ -157,22 +136,6 @@
 
 }  // namespace
 
-const char* SSLPrivateKeyTypeToString(SSLPrivateKey::Type type) {
-  switch (type) {
-    case SSLPrivateKey::Type::RSA:
-      return "RSA";
-    case SSLPrivateKey::Type::ECDSA_P256:
-      return "ECDSA_P256";
-    case SSLPrivateKey::Type::ECDSA_P384:
-      return "ECDSA_P384";
-    case SSLPrivateKey::Type::ECDSA_P521:
-      return "ECDSA_P521";
-  }
-
-  NOTREACHED();
-  return "";
-}
-
 void TestSSLPrivateKeyMatches(SSLPrivateKey* key, const std::string& pkcs8) {
   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
 
@@ -183,17 +146,12 @@
   ASSERT_TRUE(openssl_key);
   EXPECT_EQ(0u, CBS_len(&cbs));
 
-  // Check the length and type matches.
-  EXPECT_EQ(TypeForOpenSSLKey(openssl_key.get()), key->GetType());
-  EXPECT_EQ(static_cast<size_t>(EVP_PKEY_size(openssl_key.get())),
-            key->GetMaxSignatureLengthInBytes());
-
   // Test all supported hash algorithms.
   std::vector<SSLPrivateKey::Hash> hashes = key->GetDigestPreferences();
 
   // To support TLS 1.1 and earlier, RSA keys must implicitly support MD5-SHA1,
   // despite not being advertised.
-  if (key->GetType() == SSLPrivateKey::Type::RSA)
+  if (EVP_PKEY_id(openssl_key.get()) == EVP_PKEY_RSA)
     hashes.push_back(SSLPrivateKey::Hash::MD5_SHA1);
 
   for (SSLPrivateKey::Hash hash : hashes) {
@@ -209,7 +167,7 @@
     EXPECT_TRUE(VerifyWithOpenSSL(md, digest, openssl_key.get(), signature));
 
     // RSA signing is deterministic, so further check the signature matches.
-    if (key->GetType() == SSLPrivateKey::Type::RSA) {
+    if (EVP_PKEY_id(openssl_key.get()) == EVP_PKEY_RSA) {
       std::string openssl_signature;
       ASSERT_TRUE(
           SignWithOpenSSL(md, digest, openssl_key.get(), &openssl_signature));
diff --git a/net/ssl/ssl_private_key_test_util.h b/net/ssl/ssl_private_key_test_util.h
index ff922f7c..454bbd9 100644
--- a/net/ssl/ssl_private_key_test_util.h
+++ b/net/ssl/ssl_private_key_test_util.h
@@ -7,11 +7,9 @@
 
 #include <string>
 
-#include "net/ssl/ssl_private_key.h"
-
 namespace net {
 
-const char* SSLPrivateKeyTypeToString(SSLPrivateKey::Type type);
+class SSLPrivateKey;
 
 // Tests that |key| matches the private key serialized in |pkcs8|. It checks the
 // reported type and key size are correct, and then it tests all advertised
diff --git a/net/ssl/test_ssl_private_key.cc b/net/ssl/test_ssl_private_key.cc
index fd1f26f..6876178 100644
--- a/net/ssl/test_ssl_private_key.cc
+++ b/net/ssl/test_ssl_private_key.cc
@@ -24,13 +24,11 @@
 
 class TestSSLPlatformKey : public ThreadedSSLPrivateKey::Delegate {
  public:
-  TestSSLPlatformKey(bssl::UniquePtr<EVP_PKEY> key, SSLPrivateKey::Type type)
-      : key_(std::move(key)), type_(type) {}
+  explicit TestSSLPlatformKey(bssl::UniquePtr<EVP_PKEY> key)
+      : key_(std::move(key)) {}
 
   ~TestSSLPlatformKey() override {}
 
-  SSLPrivateKey::Type GetType() override { return type_; }
-
   std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
     static const SSLPrivateKey::Hash kHashes[] = {
         SSLPrivateKey::Hash::SHA512, SSLPrivateKey::Hash::SHA384,
@@ -39,10 +37,6 @@
                                             kHashes + arraysize(kHashes));
   }
 
-  size_t GetMaxSignatureLengthInBytes() override {
-    return EVP_PKEY_size(key_.get());
-  }
-
   Error SignDigest(SSLPrivateKey::Hash hash,
                    const base::StringPiece& input,
                    std::vector<uint8_t>* signature) override {
@@ -52,7 +46,7 @@
     if (!EVP_PKEY_sign_init(ctx.get()))
       return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
 
-    if (type_ == SSLPrivateKey::Type::RSA) {
+    if (EVP_PKEY_id(key_.get()) == EVP_PKEY_RSA) {
       const EVP_MD* digest = nullptr;
       switch (hash) {
         case SSLPrivateKey::Hash::MD5_SHA1:
@@ -98,7 +92,6 @@
 
  private:
   bssl::UniquePtr<EVP_PKEY> key_;
-  SSLPrivateKey::Type type_;
 
   DISALLOW_COPY_AND_ASSIGN(TestSSLPlatformKey);
 };
@@ -110,36 +103,8 @@
   if (!key)
     return nullptr;
 
-  SSLPrivateKey::Type type;
-  switch (EVP_PKEY_id(key.get())) {
-    case EVP_PKEY_RSA:
-      type = SSLPrivateKey::Type::RSA;
-      break;
-    case EVP_PKEY_EC: {
-      EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key.get());
-      int curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key));
-      switch (curve) {
-        case NID_X9_62_prime256v1:
-          type = SSLPrivateKey::Type::ECDSA_P256;
-          break;
-        case NID_secp384r1:
-          type = SSLPrivateKey::Type::ECDSA_P384;
-          break;
-        case NID_secp521r1:
-          type = SSLPrivateKey::Type::ECDSA_P384;
-          break;
-        default:
-          LOG(ERROR) << "Unknown curve: " << curve;
-          return nullptr;
-      }
-      break;
-    }
-    default:
-      LOG(ERROR) << "Unknown key type: " << EVP_PKEY_id(key.get());
-      return nullptr;
-  }
   return make_scoped_refptr(new ThreadedSSLPrivateKey(
-      base::MakeUnique<TestSSLPlatformKey>(std::move(key), type),
+      base::MakeUnique<TestSSLPlatformKey>(std::move(key)),
       GetSSLPlatformKeyTaskRunner()));
 }
 
diff --git a/net/ssl/threaded_ssl_private_key.cc b/net/ssl/threaded_ssl_private_key.cc
index 42f01f6..53e8c34d 100644
--- a/net/ssl/threaded_ssl_private_key.cc
+++ b/net/ssl/threaded_ssl_private_key.cc
@@ -55,18 +55,10 @@
       task_runner_(std::move(task_runner)),
       weak_factory_(this) {}
 
-SSLPrivateKey::Type ThreadedSSLPrivateKey::GetType() {
-  return core_->delegate()->GetType();
-}
-
 std::vector<SSLPrivateKey::Hash> ThreadedSSLPrivateKey::GetDigestPreferences() {
   return core_->delegate()->GetDigestPreferences();
 }
 
-size_t ThreadedSSLPrivateKey::GetMaxSignatureLengthInBytes() {
-  return core_->delegate()->GetMaxSignatureLengthInBytes();
-}
-
 void ThreadedSSLPrivateKey::SignDigest(
     SSLPrivateKey::Hash hash,
     const base::StringPiece& input,
diff --git a/net/ssl/threaded_ssl_private_key.h b/net/ssl/threaded_ssl_private_key.h
index e2f79aa..da18157 100644
--- a/net/ssl/threaded_ssl_private_key.h
+++ b/net/ssl/threaded_ssl_private_key.h
@@ -34,11 +34,9 @@
     Delegate() {}
     virtual ~Delegate() {}
 
-    // These methods behave as those of the same name on SSLPrivateKey. They
-    // must be callable on any thread.
-    virtual Type GetType() = 0;
+    // Returns the digests that are supported by the key in decreasing
+    // preference. This method must be callable on any thread.
     virtual std::vector<SSLPrivateKey::Hash> GetDigestPreferences() = 0;
-    virtual size_t GetMaxSignatureLengthInBytes() = 0;
 
     // Signs |input| as a digest of type |hash|. On success it returns OK and
     // sets |signature| to the resulting signature. Otherwise it returns a net
@@ -57,9 +55,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
 
   // SSLPrivateKey implementation.
-  Type GetType() override;
   std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override;
-  size_t GetMaxSignatureLengthInBytes() override;
   void SignDigest(Hash hash,
                   const base::StringPiece& input,
                   const SignCallback& callback) override;
diff --git a/net/tools/cert_verify_tool/verify_using_path_builder.cc b/net/tools/cert_verify_tool/verify_using_path_builder.cc
index 6e2293a..45dec38f 100644
--- a/net/tools/cert_verify_tool/verify_using_path_builder.cc
+++ b/net/tools/cert_verify_tool/verify_using_path_builder.cc
@@ -19,8 +19,7 @@
 #include "net/cert/internal/parsed_certificate.h"
 #include "net/cert/internal/path_builder.h"
 #include "net/cert/internal/signature_policy.h"
-#include "net/cert/internal/trust_store_collection.h"
-#include "net/cert/internal/trust_store_in_memory.h"
+#include "net/cert/internal/system_trust_store.h"
 #include "net/cert/x509_util.h"
 #include "net/cert_net/cert_net_fetcher_impl.h"
 #include "net/tools/cert_verify_tool/cert_verify_tool_util.h"
@@ -28,22 +27,11 @@
 #include "net/url_request/url_request_context_builder.h"
 #include "net/url_request/url_request_context_getter.h"
 
-#if defined(USE_NSS_CERTS)
-#include "base/threading/thread_task_runner_handle.h"
-#include "net/cert/internal/cert_issuer_source_nss.h"
-#include "net/cert/internal/trust_store_nss.h"
-#endif
-
 #if defined(OS_LINUX)
 #include "net/proxy/proxy_config.h"
 #include "net/proxy/proxy_config_service_fixed.h"
 #endif
 
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-#include <Security/Security.h>
-#include "net/cert/internal/trust_store_mac.h"
-#endif
-
 namespace {
 
 std::string GetUserAgent() {
@@ -221,31 +209,21 @@
   at_time.UTCExplode(&exploded_time);
   net::der::GeneralizedTime time = ConvertExplodedTime(exploded_time);
 
-  net::TrustStoreCollection trust_store;
+  std::unique_ptr<net::SystemTrustStore> ssl_trust_store =
+      net::CreateSslSystemTrustStore();
 
-  net::TrustStoreInMemory trust_store_in_memory;
-  trust_store.AddTrustStore(&trust_store_in_memory);
   for (const auto& der_cert : root_der_certs) {
     scoped_refptr<net::ParsedCertificate> cert = ParseCertificate(der_cert);
     if (cert) {
-      trust_store_in_memory.AddTrustAnchor(
+      ssl_trust_store->AddTrustAnchor(
           net::TrustAnchor::CreateFromCertificateNoConstraints(cert));
     }
   }
 
-#if defined(USE_NSS_CERTS)
-  net::TrustStoreNSS trust_store_nss(trustSSL);
-  trust_store.AddTrustStore(&trust_store_nss);
-#elif defined(OS_MACOSX) && !defined(OS_IOS)
-  net::TrustStoreMac trust_store_mac(kSecPolicyAppleSSL);
-  trust_store.AddTrustStore(&trust_store_mac);
-#else
-  if (root_der_certs.empty()) {
+  if (!ssl_trust_store->UsesSystemTrustStore() && root_der_certs.empty()) {
     std::cerr << "NOTE: CertPathBuilder does not currently use OS trust "
                  "settings (--roots must be specified).\n";
   }
-#endif
-
   net::CertIssuerSourceStatic intermediate_cert_issuer_source;
   for (const auto& der_cert : intermediate_der_certs) {
     scoped_refptr<net::ParsedCertificate> cert = ParseCertificate(der_cert);
@@ -261,14 +239,13 @@
   // Verify the chain.
   net::SimpleSignaturePolicy signature_policy(2048);
   net::CertPathBuilder::Result result;
-  net::CertPathBuilder path_builder(target_cert, &trust_store,
-                                    &signature_policy, time,
-                                    net::KeyPurpose::SERVER_AUTH, &result);
+  net::CertPathBuilder path_builder(
+      target_cert, ssl_trust_store->GetTrustStore(), &signature_policy, time,
+      net::KeyPurpose::SERVER_AUTH, &result);
   path_builder.AddCertIssuerSource(&intermediate_cert_issuer_source);
-#if defined(USE_NSS_CERTS)
-  net::CertIssuerSourceNSS cert_issuer_source_nss;
-  path_builder.AddCertIssuerSource(&cert_issuer_source_nss);
-#endif
+
+  if (ssl_trust_store->GetCertIssuerSource())
+    path_builder.AddCertIssuerSource(ssl_trust_store->GetCertIssuerSource());
 
   // Create a network thread to be used for AIA fetches, and wait for a
   // CertNetFetcher to be constructed on that thread.
diff --git a/printing/emf_win.cc b/printing/emf_win.cc
index 1bcc75d9..9bd3e1e 100644
--- a/printing/emf_win.cc
+++ b/printing/emf_win.cc
@@ -382,7 +382,6 @@
       } else {
         DCHECK(bitmap.get());
         if (bitmap.get()) {
-          SkAutoLockPixels lock(*bitmap.get());
           DCHECK_EQ(bitmap->colorType(), kN32_SkColorType);
           const uint32_t* pixels =
               static_cast<const uint32_t*>(bitmap->getPixels());
diff --git a/remoting/base/breakpad_win.cc b/remoting/base/breakpad_win.cc
index dc522230..58d95c3 100644
--- a/remoting/base/breakpad_win.cc
+++ b/remoting/base/breakpad_win.cc
@@ -133,7 +133,7 @@
 }
 
 BreakpadWin::~BreakpadWin() {
-  // This object should be leaked so that crashes occurred during the process
+  // This object should be leaked so that crashes which occur during process
   // shutdown will be caught.
   NOTREACHED();
 }
diff --git a/remoting/host/chromeos/skia_bitmap_desktop_frame.cc b/remoting/host/chromeos/skia_bitmap_desktop_frame.cc
index a692a39a..31e2100a 100644
--- a/remoting/host/chromeos/skia_bitmap_desktop_frame.cc
+++ b/remoting/host/chromeos/skia_bitmap_desktop_frame.cc
@@ -19,10 +19,7 @@
   DCHECK_EQ(kBGRA_8888_SkColorType, bitmap->info().colorType())
       << "DesktopFrame objects always hold RGBA data.";
 
-  bitmap->lockPixels();
   uint8_t* bitmap_data = reinterpret_cast<uint8_t*>(bitmap->getPixels());
-  bitmap->unlockPixels();
-
   const size_t row_bytes = bitmap->rowBytes();
   SkiaBitmapDesktopFrame* result = new SkiaBitmapDesktopFrame(
       size, row_bytes, bitmap_data, std::move(bitmap));
diff --git a/remoting/host/host_main.cc b/remoting/host/host_main.cc
index ff5bfd47..5e68691 100644
--- a/remoting/host/host_main.cc
+++ b/remoting/host/host_main.cc
@@ -148,16 +148,6 @@
 
   base::CommandLine::Init(argc, argv);
 
-  // Initialize Breakpad as early as possible. On Mac the command-line needs to
-  // be initialized first, so that the preference for crash-reporting can be
-  // looked up in the config file.
-#if defined(REMOTING_ENABLE_BREAKPAD)
-  // TODO(nicholss): Commenting out Breakpad. See crbug.com/637884
-  // if (IsUsageStatsAllowed()) {
-  //   InitializeCrashReporting();
-  // }
-#endif  // defined(REMOTING_ENABLE_BREAKPAD)
-
   // This object instance is required by Chrome code (for example,
   // LazyInstance, MessageLoop).
   base::AtExitManager exit_manager;
@@ -165,8 +155,17 @@
   // Enable debug logs.
   InitHostLogging();
 
-  // Register and initialize common controls.
+#if defined(REMOTING_ENABLE_BREAKPAD)
+  // Initialize Breakpad as early as possible. On Mac the command-line needs to
+  // be initialized first, so that the preference for crash-reporting can be
+  // looked up in the config file.
+  if (IsUsageStatsAllowed()) {
+    InitializeCrashReporting();
+  }
+#endif  // defined(REMOTING_ENABLE_BREAKPAD)
+
 #if defined(OS_WIN)
+  // Register and initialize common controls.
   INITCOMMONCONTROLSEX info;
   info.dwSize = sizeof(info);
   info.dwICC = ICC_STANDARD_CLASSES;
diff --git a/remoting/host/it2me/it2me_native_messaging_host_main.cc b/remoting/host/it2me/it2me_native_messaging_host_main.cc
index 8d80b58..27f238b 100644
--- a/remoting/host/it2me/it2me_native_messaging_host_main.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host_main.cc
@@ -62,10 +62,9 @@
   // Initialize Breakpad as early as possible. On Mac the command-line needs to
   // be initialized first, so that the preference for crash-reporting can be
   // looked up in the config file.
-  // TODO(nicholss): Commenting out Breakpad. See crbug.com/637884
-  // if (IsUsageStatsAllowed()) {
-  //   InitializeCrashReporting();
-  // }
+  if (IsUsageStatsAllowed()) {
+    InitializeCrashReporting();
+  }
 #endif  // defined(REMOTING_ENABLE_BREAKPAD)
 
 #if defined(OS_WIN)
diff --git a/remoting/host/mac/BUILD.gn b/remoting/host/mac/BUILD.gn
index 90d097c..73cf0e8 100644
--- a/remoting/host/mac/BUILD.gn
+++ b/remoting/host/mac/BUILD.gn
@@ -67,9 +67,10 @@
     "MACOSX_DEPLOYMENT_TARGET=10.7",
   ]
 
-  if (is_chrome_branded && is_official_build) {
-    defines = [ "REMOTING_ENABLE_BREAKPAD" ]
-  }
+  # TODO(joedow): Re-enable or replace with Crashpad: crbug.com/637884.
+  # if (is_chrome_branded && is_official_build) {
+  #   defines = [ "REMOTING_ENABLE_BREAKPAD" ]
+  # }
 
   deps = [
     "//build/config/sanitizers:deps",
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc
index 5b65023e..bc32e51a 100644
--- a/remoting/host/remoting_me2me_host.cc
+++ b/remoting/host/remoting_me2me_host.cc
@@ -41,7 +41,6 @@
 #include "net/socket/client_socket_factory.h"
 #include "net/url_request/url_fetcher.h"
 #include "remoting/base/auto_thread_task_runner.h"
-#include "remoting/base/breakpad.h"
 #include "remoting/base/chromium_url_request.h"
 #include "remoting/base/constants.h"
 #include "remoting/base/logging.h"
diff --git a/remoting/host/setup/me2me_native_messaging_host_main.cc b/remoting/host/setup/me2me_native_messaging_host_main.cc
index adfe9cf..75e028e89 100644
--- a/remoting/host/setup/me2me_native_messaging_host_main.cc
+++ b/remoting/host/setup/me2me_native_messaging_host_main.cc
@@ -80,10 +80,9 @@
   // Initialize Breakpad as early as possible. On Mac the command-line needs to
   // be initialized first, so that the preference for crash-reporting can be
   // looked up in the config file.
-  // TODO(nicholss): Commenting out Breakpad. See crbug.com/637884
-  // if (IsUsageStatsAllowed()) {
-  //   InitializeCrashReporting();
-  // }
+  if (IsUsageStatsAllowed()) {
+    InitializeCrashReporting();
+  }
 #endif  // defined(REMOTING_ENABLE_BREAKPAD)
 
   base::TaskScheduler::CreateAndSetSimpleTaskScheduler("Me2Me");
diff --git a/remoting/host/usage_stats_consent_win.cc b/remoting/host/usage_stats_consent_win.cc
index bacab67..d21d6e8a 100644
--- a/remoting/host/usage_stats_consent_win.cc
+++ b/remoting/host/usage_stats_consent_win.cc
@@ -46,9 +46,9 @@
   // supported.
   *set_by_policy = false;
 
-  // The user's consent to collect crash dumps is recored as the "usagestats"
-  // value in the ClientState or ClientStateMedium key. Probe
-  // the ClientStateMedium key first.
+  // The user's consent to collect crash dumps is recorded as the "usagestats"
+  // value in the ClientState or ClientStateMedium key. Probe the
+  // ClientStateMedium key first.
   DWORD value = 0;
   if (ReadUsageStatsValue(kOmahaClientStateMedium, &value) == ERROR_SUCCESS) {
     *allowed = value != 0;
diff --git a/remoting/host/win/BUILD.gn b/remoting/host/win/BUILD.gn
index d93224d..683809b 100644
--- a/remoting/host/win/BUILD.gn
+++ b/remoting/host/win/BUILD.gn
@@ -330,6 +330,10 @@
               "VERSION=$chrome_version_full",
             ]
 
+  if (is_chrome_branded && is_official_build) {
+    defines += [ "REMOTING_ENABLE_BREAKPAD" ]
+  }
+
   if (remoting_multi_process != 0 && remoting_rdp_session != 0) {
     defines += [ "REMOTING_RDP_SESSION" ]
   }
diff --git a/remoting/test/frame_generator_util.cc b/remoting/test/frame_generator_util.cc
index bef4040390..f8231fa6 100644
--- a/remoting/test/frame_generator_util.cc
+++ b/remoting/test/frame_generator_util.cc
@@ -18,13 +18,11 @@
 void CopyPixelsToBuffer(const SkBitmap& src,
                         uint8_t* dst_pixels,
                         int dst_stride) {
-  SkBitmap tmp(src);
-  tmp.lockPixels();
-  const char* src_pixels = static_cast<const char*>(tmp.getPixels());
-  size_t src_stride = tmp.rowBytes();
+  const char* src_pixels = static_cast<const char*>(src.getPixels());
+  size_t src_stride = src.rowBytes();
   // Only need to copy the important parts of the row.
-  size_t bytes_per_row = tmp.width() * tmp.bytesPerPixel();
-  for (int y = 0; y < tmp.height(); ++y) {
+  size_t bytes_per_row = src.width() * src.bytesPerPixel();
+  for (int y = 0; y < src.height(); ++y) {
     memcpy(dst_pixels, src_pixels, bytes_per_row);
     src_pixels += src_stride;
     dst_pixels += dst_stride;
diff --git a/services/ui/public/interfaces/cursor/cursor_struct_traits_unittest.cc b/services/ui/public/interfaces/cursor/cursor_struct_traits_unittest.cc
index 179c6ca..fa0d041 100644
--- a/services/ui/public/interfaces/cursor/cursor_struct_traits_unittest.cc
+++ b/services/ui/public/interfaces/cursor/cursor_struct_traits_unittest.cc
@@ -89,17 +89,12 @@
     ASSERT_EQ(input.cursor_frames()[f].height(),
               output.cursor_frames()[f].height());
 
-    input.cursor_frames()[f].lockPixels();
-    output.cursor_frames()[f].lockPixels();
     for (int x = 0; x < input.cursor_frames()[f].width(); ++x) {
       for (int y = 0; y < input.cursor_frames()[f].height(); ++y) {
         EXPECT_EQ(input.cursor_frames()[f].getColor(x, y),
                   output.cursor_frames()[f].getColor(x, y));
       }
     }
-
-    output.cursor_frames()[f].unlockPixels();
-    input.cursor_frames()[f].unlockPixels();
   }
 }
 
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 367e000..9a2c463 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -224,10 +224,6 @@
 #define SK_LEGACY_SWEEP_GRADIENT
 #endif
 
-#ifndef SK_SUPPORT_OBSOLETE_LOCKPIXELS
-#define SK_SUPPORT_OBSOLETE_LOCKPIXELS
-#endif
-
 ///////////////////////// Imported from BUILD.gn and skia_common.gypi
 
 /* In some places Skia can use static initializers for global initialization,
diff --git a/skia/ext/image_operations.cc b/skia/ext/image_operations.cc
index 318ae50..8b5f371d 100644
--- a/skia/ext/image_operations.cc
+++ b/skia/ext/image_operations.cc
@@ -360,7 +360,6 @@
   SkASSERT((ImageOperations::RESIZE_FIRST_ALGORITHM_METHOD <= method) &&
            (method <= ImageOperations::RESIZE_LAST_ALGORITHM_METHOD));
 
-  SkAutoLockPixels locker(source);
   if (!source.readyToDraw() || source.colorType() != kN32_SkColorType)
     return SkBitmap();
 
diff --git a/skia/ext/image_operations_unittest.cc b/skia/ext/image_operations_unittest.cc
index e88c5e2..a05dfeda 100644
--- a/skia/ext/image_operations_unittest.cc
+++ b/skia/ext/image_operations_unittest.cc
@@ -162,7 +162,6 @@
 
 #if DEBUG_BITMAP_GENERATION
 void SaveBitmapToPNG(const SkBitmap& bmp, const char* path) {
-  SkAutoLockPixels lock(bmp);
   std::vector<unsigned char> png;
   gfx::PNGCodec::ColorFormat color_format = gfx::PNGCodec::FORMAT_RGBA;
   if (!gfx::PNGCodec::Encode(
@@ -195,8 +194,6 @@
   ASSERT_EQ(src_w, results.width());
   ASSERT_EQ(src_h, results.height());
 
-  SkAutoLockPixels src_lock(src);
-  SkAutoLockPixels results_lock(results);
   for (int y = 0; y < src_h; y++) {
     for (int x = 0; x < src_w; x++) {
       EXPECT_EQ(*src.getAddr32(x, y), *results.getAddr32(x, y));
@@ -261,8 +258,6 @@
   float max_observed_distance = 0.0f;
   bool all_pixels_ok = true;
 
-  SkAutoLockPixels dest_lock(dest);
-
   for (size_t pixel_index = 0;
        pixel_index < arraysize(tested_pixels);
        ++pixel_index) {
@@ -367,7 +362,6 @@
   ASSERT_EQ(src_h / 2, actual_results.height());
 
   // Compute the expected values & compare.
-  SkAutoLockPixels lock(actual_results);
   for (int y = 0; y < actual_results.height(); y++) {
     for (int x = 0; x < actual_results.width(); x++) {
       // Note that those expressions take into account the "half-pixel"
@@ -421,8 +415,6 @@
 
   // The computed subset and the corresponding subset of the original image
   // should be the same.
-  SkAutoLockPixels full_lock(full_results);
-  SkAutoLockPixels subset_lock(subset_results);
   for (int y = 0; y < subset_rect.height(); y++) {
     for (int x = 0; x < subset_rect.width(); x++) {
       ASSERT_EQ(
@@ -543,7 +535,6 @@
       src,
       skia::ImageOperations::RESIZE_LANCZOS3,
       dst_w, dst_h);
-  SkAutoLockPixels dst_lock(dst);
   for (int dst_y = 0; dst_y < dst_h; ++dst_y) {
     for (int dst_x = 0; dst_x < dst_w; ++dst_x) {
       float dst_x_in_src = (dst_x + 0.5) * src_w / dst_w;
diff --git a/skia/ext/platform_canvas_unittest.cc b/skia/ext/platform_canvas_unittest.cc
index 1bd15a6..8d7e597 100644
--- a/skia/ext/platform_canvas_unittest.cc
+++ b/skia/ext/platform_canvas_unittest.cc
@@ -58,7 +58,6 @@
                 uint32_t canvas_color, uint32_t rect_color,
                 int x, int y, int w, int h) {
   const SkBitmap bitmap = skia::ReadPixels(const_cast<SkCanvas*>(&canvas));
-  SkAutoLockPixels lock(bitmap);
 
   for (int cur_y = 0; cur_y < bitmap.height(); cur_y++) {
     for (int cur_x = 0; cur_x < bitmap.width(); cur_x++) {
diff --git a/skia/public/interfaces/bitmap_skbitmap_struct_traits.cc b/skia/public/interfaces/bitmap_skbitmap_struct_traits.cc
index 35f18be..f5b5550c 100644
--- a/skia/public/interfaces/bitmap_skbitmap_struct_traits.cc
+++ b/skia/public/interfaces/bitmap_skbitmap_struct_traits.cc
@@ -180,14 +180,12 @@
   if (data.width() == 0 || data.height() == 0)
     return true;
 
-  SkAutoPixmapUnlock pixmap;
   mojo::ArrayDataView<uint8_t> data_view;
   data.GetPixelDataDataView(&data_view);
   if (static_cast<uint32_t>(b->width()) != data.width() ||
       static_cast<uint32_t>(b->height()) != data.height() ||
       static_cast<uint64_t>(b->rowBytes()) != data.row_bytes() ||
-      b->getSize() != data_view.size() || !b->requestLock(&pixmap) ||
-      !b->readyToDraw()) {
+      b->getSize() != data_view.size() || !b->readyToDraw()) {
     return false;
   }
 
@@ -200,18 +198,4 @@
   return true;
 }
 
-// static
-void* StructTraits<skia::mojom::BitmapDataView, SkBitmap>::SetUpContext(
-    const SkBitmap& b) {
-  b.lockPixels();
-  return nullptr;
-}
-
-// static
-void StructTraits<skia::mojom::BitmapDataView, SkBitmap>::TearDownContext(
-    const SkBitmap& b,
-    void* context) {
-  b.unlockPixels();
-}
-
 }  // namespace mojo
diff --git a/skia/public/interfaces/bitmap_skbitmap_struct_traits.h b/skia/public/interfaces/bitmap_skbitmap_struct_traits.h
index 8c7cf77..7e45bb2 100644
--- a/skia/public/interfaces/bitmap_skbitmap_struct_traits.h
+++ b/skia/public/interfaces/bitmap_skbitmap_struct_traits.h
@@ -27,8 +27,6 @@
   static uint64_t row_bytes(const SkBitmap& b);
   static BitmapBuffer pixel_data(const SkBitmap& b);
   static bool Read(skia::mojom::BitmapDataView data, SkBitmap* b);
-  static void* SetUpContext(const SkBitmap& b);
-  static void TearDownContext(const SkBitmap& b, void* context);
 };
 
 }  // namespace mojo
diff --git a/sql/connection.h b/sql/connection.h
index 639c333..838d552 100644
--- a/sql/connection.h
+++ b/sql/connection.h
@@ -527,6 +527,7 @@
   FRIEND_TEST_ALL_PREFIXES(SQLConnectionTest, GetAppropriateMmapSizeAltStatus);
   FRIEND_TEST_ALL_PREFIXES(SQLConnectionTest, OnMemoryDump);
   FRIEND_TEST_ALL_PREFIXES(SQLConnectionTest, RegisterIntentToUpload);
+  FRIEND_TEST_ALL_PREFIXES(SQLiteFeaturesTest, WALNoClose);
 
   // Internal initialize function used by both Init and InitInMemory. The file
   // name is always 8 bits since we want to use the 8-bit version of
diff --git a/sql/sqlite_features_unittest.cc b/sql/sqlite_features_unittest.cc
index 0f124af..88f7802f 100644
--- a/sql/sqlite_features_unittest.cc
+++ b/sql/sqlite_features_unittest.cc
@@ -32,8 +32,12 @@
 
 // Test that certain features are/are-not enabled in our SQLite.
 
+namespace sql {
 namespace {
 
+using sql::test::ExecuteWithResult;
+using sql::test::ExecuteWithResults;
+
 void CaptureErrorCallback(int* error_pointer, std::string* sql_text,
                           int error, sql::Statement* stmt) {
   *error_pointer = error;
@@ -41,6 +45,8 @@
   *sql_text = text ? text : "no statement available";
 }
 
+}  // namespace
+
 class SQLiteFeaturesTest : public sql::SQLTestBase {
  public:
   SQLiteFeaturesTest() : error_(SQLITE_OK) {}
@@ -102,10 +108,8 @@
 
   ASSERT_TRUE(db().Execute("INSERT INTO foo (x) VALUES ('test')"));
 
-  sql::Statement s(db().GetUniqueStatement(
-      "SELECT x FROM foo WHERE x MATCH 'te*'"));
-  ASSERT_TRUE(s.Step());
-  EXPECT_EQ("test", s.ColumnString(0));
+  EXPECT_EQ("test",
+            ExecuteWithResult(&db(), "SELECT x FROM foo WHERE x MATCH 'te*'"));
 }
 #endif
 
@@ -118,10 +122,9 @@
   sqlite3_sleep(1);
   base::TimeDelta delta = base::TimeTicks::Now() - before;
 
-  // It is not impossible for this to be over 1000 if things are compiled the
-  // right way.  But it is very unlikely, most platforms seem to be around
-  // <TBD>.
-  LOG(ERROR) << "Milliseconds: " << delta.InMilliseconds();
+  // It is not impossible for this to be over 1000 if things are compiled
+  // correctly, but that is very unlikely.  Most platforms seem to be exactly
+  // 1ms, with the rest at 2ms, and the worst observed cases was ASAN at 7ms.
   EXPECT_LT(delta.InMilliseconds(), 1000);
 }
 #endif
@@ -135,28 +138,29 @@
       "CREATE TABLE children ("
       "    id INTEGER PRIMARY KEY,"
       "    pid INTEGER NOT NULL REFERENCES parents(id) ON DELETE CASCADE)"));
+  const char kSelectParents[] = "SELECT * FROM parents ORDER BY id";
+  const char kSelectChildren[] = "SELECT * FROM children ORDER BY id";
 
   // Inserting without a matching parent should fail with constraint violation.
   // Mask off any extended error codes for USE_SYSTEM_SQLITE.
-  int insertErr = db().ExecuteAndReturnErrorCode(
-      "INSERT INTO children VALUES (10, 1)");
-  EXPECT_EQ(SQLITE_CONSTRAINT, (insertErr&0xff));
-
-  size_t rows;
-  EXPECT_TRUE(sql::test::CountTableRows(&db(), "children", &rows));
-  EXPECT_EQ(0u, rows);
+  EXPECT_EQ("", ExecuteWithResult(&db(), kSelectParents));
+  const int insert_error =
+      db().ExecuteAndReturnErrorCode("INSERT INTO children VALUES (10, 1)");
+  EXPECT_EQ(SQLITE_CONSTRAINT, (insert_error & 0xff));
+  EXPECT_EQ("", ExecuteWithResult(&db(), kSelectChildren));
 
   // Inserting with a matching parent should work.
   ASSERT_TRUE(db().Execute("INSERT INTO parents VALUES (1)"));
+  EXPECT_EQ("1", ExecuteWithResults(&db(), kSelectParents, "|", "\n"));
   EXPECT_TRUE(db().Execute("INSERT INTO children VALUES (11, 1)"));
   EXPECT_TRUE(db().Execute("INSERT INTO children VALUES (12, 1)"));
-  EXPECT_TRUE(sql::test::CountTableRows(&db(), "children", &rows));
-  EXPECT_EQ(2u, rows);
+  EXPECT_EQ("11|1\n12|1",
+            ExecuteWithResults(&db(), kSelectChildren, "|", "\n"));
 
-  // Deleting the parent should cascade, i.e., delete the children as well.
+  // Deleting the parent should cascade, deleting the children as well.
   ASSERT_TRUE(db().Execute("DELETE FROM parents"));
-  EXPECT_TRUE(sql::test::CountTableRows(&db(), "children", &rows));
-  EXPECT_EQ(0u, rows);
+  EXPECT_EQ("", ExecuteWithResult(&db(), kSelectParents));
+  EXPECT_EQ("", ExecuteWithResult(&db(), kSelectChildren));
 }
 
 #if defined(MOJO_APPTEST_IMPL) || defined(OS_IOS)
@@ -453,4 +457,36 @@
 }
 #endif  // !defined(USE_SYSTEM_SQLITE)
 
-}  // namespace
+#if !defined(USE_SYSTEM_SQLITE)
+// SQLite WAL mode defaults to checkpointing the WAL on close.  This would push
+// additional work into Chromium shutdown.  Verify that SQLite supports a config
+// option to not checkpoint on close.
+TEST_F(SQLiteFeaturesTest, WALNoClose) {
+  base::FilePath wal_path(db_path().value() + FILE_PATH_LITERAL("-wal"));
+
+  // Turn on WAL mode, then verify that the mode changed (WAL is supported).
+  ASSERT_TRUE(db().Execute("PRAGMA journal_mode = WAL"));
+  ASSERT_EQ("wal", ExecuteWithResult(&db(), "PRAGMA journal_mode"));
+
+  // The WAL file is created lazily on first change.
+  ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
+
+  // By default, the WAL is checkpointed then deleted on close.
+  ASSERT_TRUE(GetPathExists(wal_path));
+  db().Close();
+  ASSERT_FALSE(GetPathExists(wal_path));
+
+  // Reopen and configure the database to not checkpoint WAL on close.
+  ASSERT_TRUE(Reopen());
+  ASSERT_TRUE(db().Execute("PRAGMA journal_mode = WAL"));
+  ASSERT_TRUE(db().Execute("ALTER TABLE foo ADD COLUMN c"));
+  ASSERT_EQ(
+      SQLITE_OK,
+      sqlite3_db_config(db().db_, SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, 1, NULL));
+  ASSERT_TRUE(GetPathExists(wal_path));
+  db().Close();
+  ASSERT_TRUE(GetPathExists(wal_path));
+}
+#endif
+
+}  // namespace sql
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index ee3acb5..4dd1b30 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -303,6 +303,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "mus_gpu_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mus_ws_unittests"
       },
       {
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json
index 747eac1..594c89c 100644
--- a/testing/buildbot/chromium.perf.json
+++ b/testing/buildbot/chromium.perf.json
@@ -81347,7 +81347,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81377,7 +81377,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81406,7 +81406,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81436,7 +81436,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81465,7 +81465,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81495,7 +81495,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81642,7 +81642,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81672,7 +81672,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81701,7 +81701,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81731,7 +81731,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81760,7 +81760,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81790,7 +81790,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81819,7 +81819,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81849,7 +81849,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81878,7 +81878,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -81908,7 +81908,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82055,7 +82055,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82085,7 +82085,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82350,7 +82350,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82380,7 +82380,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82409,7 +82409,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82439,7 +82439,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82527,7 +82527,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82557,7 +82557,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82586,7 +82586,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82616,7 +82616,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82645,7 +82645,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82675,7 +82675,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82704,7 +82704,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82734,7 +82734,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82763,7 +82763,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82793,7 +82793,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82822,7 +82822,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82852,7 +82852,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82881,7 +82881,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82911,7 +82911,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82940,7 +82940,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82970,7 +82970,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -82999,7 +82999,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83029,7 +83029,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83058,7 +83058,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83088,7 +83088,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83117,7 +83117,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83147,7 +83147,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83176,7 +83176,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83206,7 +83206,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83235,7 +83235,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83265,7 +83265,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83412,7 +83412,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83442,7 +83442,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83766,7 +83766,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83796,7 +83796,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83884,7 +83884,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -83914,7 +83914,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -84297,7 +84297,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -84327,7 +84327,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -84356,7 +84356,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -84386,7 +84386,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -84415,7 +84415,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -84445,7 +84445,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -84474,7 +84474,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -84504,7 +84504,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -84828,7 +84828,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -84858,7 +84858,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -84887,7 +84887,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -84917,7 +84917,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85064,7 +85064,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85094,7 +85094,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85300,7 +85300,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85330,7 +85330,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85359,7 +85359,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85389,7 +85389,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85536,7 +85536,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85566,7 +85566,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85595,7 +85595,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85625,7 +85625,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85654,7 +85654,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85684,7 +85684,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85713,7 +85713,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85743,7 +85743,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85772,7 +85772,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85802,7 +85802,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85831,7 +85831,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85861,7 +85861,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85949,7 +85949,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -85979,7 +85979,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86155,7 +86155,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86185,7 +86185,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86214,7 +86214,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86244,7 +86244,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86273,7 +86273,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86303,7 +86303,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86391,7 +86391,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86421,7 +86421,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86568,7 +86568,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86598,7 +86598,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86686,7 +86686,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86716,7 +86716,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86804,7 +86804,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -86834,7 +86834,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87040,7 +87040,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87070,7 +87070,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87099,7 +87099,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87129,7 +87129,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87158,7 +87158,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87188,7 +87188,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87217,7 +87217,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87247,7 +87247,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87394,7 +87394,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87424,7 +87424,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87453,7 +87453,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87483,7 +87483,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87630,7 +87630,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87660,7 +87660,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87689,7 +87689,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87719,7 +87719,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87748,7 +87748,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -87778,7 +87778,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88043,7 +88043,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88073,7 +88073,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88220,7 +88220,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88250,7 +88250,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88279,7 +88279,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88309,7 +88309,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88338,7 +88338,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88368,7 +88368,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88397,7 +88397,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88427,7 +88427,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88456,7 +88456,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88486,7 +88486,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88515,7 +88515,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88545,7 +88545,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88574,7 +88574,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88604,7 +88604,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88692,7 +88692,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88722,7 +88722,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88751,7 +88751,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88781,7 +88781,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88810,7 +88810,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88840,7 +88840,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -88987,7 +88987,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89135,7 +89135,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89400,7 +89400,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89430,7 +89430,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89459,7 +89459,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89489,7 +89489,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89577,7 +89577,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89607,7 +89607,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89695,7 +89695,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89725,7 +89725,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89754,7 +89754,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89784,7 +89784,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build180-b4",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89813,7 +89813,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89843,7 +89843,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89872,7 +89872,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89902,7 +89902,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -89990,7 +89990,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -90020,7 +90020,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -90226,7 +90226,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -90256,7 +90256,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -90403,7 +90403,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -90433,7 +90433,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -90816,7 +90816,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -90846,7 +90846,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -90934,7 +90934,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -90964,7 +90964,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build117-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -90993,7 +90993,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -91023,7 +91023,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -91052,7 +91052,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -91082,7 +91082,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build120-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -91642,7 +91642,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -91672,7 +91672,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -92350,7 +92350,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -92498,7 +92498,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build119-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -92527,7 +92527,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -92557,7 +92557,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -92586,7 +92586,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -92616,7 +92616,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build120-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -92645,7 +92645,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -92675,7 +92675,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build180-b4",
+              "id": "build118-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -92704,7 +92704,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -92734,7 +92734,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build117-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -92822,7 +92822,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -92852,7 +92852,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:1616",
-              "id": "build118-b1",
+              "id": "build119-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -174523,7 +174523,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -174553,7 +174553,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -174582,7 +174582,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -174612,7 +174612,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -174641,7 +174641,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -174671,7 +174671,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -174818,7 +174818,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -174848,7 +174848,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -174877,7 +174877,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -174907,7 +174907,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -174936,7 +174936,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -174966,7 +174966,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -174995,7 +174995,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175025,7 +175025,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175054,7 +175054,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175084,7 +175084,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175231,7 +175231,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175261,7 +175261,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175526,7 +175526,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175556,7 +175556,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175585,7 +175585,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175615,7 +175615,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175703,7 +175703,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175733,7 +175733,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175762,7 +175762,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175792,7 +175792,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175821,7 +175821,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175851,7 +175851,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175880,7 +175880,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175910,7 +175910,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175939,7 +175939,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175969,7 +175969,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -175998,7 +175998,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176028,7 +176028,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176057,7 +176057,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176087,7 +176087,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176116,7 +176116,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176146,7 +176146,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176175,7 +176175,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176205,7 +176205,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176234,7 +176234,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176264,7 +176264,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176293,7 +176293,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176323,7 +176323,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176352,7 +176352,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176382,7 +176382,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176411,7 +176411,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176441,7 +176441,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176588,7 +176588,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176618,7 +176618,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176942,7 +176942,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -176972,7 +176972,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -177060,7 +177060,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -177090,7 +177090,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -177473,7 +177473,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -177503,7 +177503,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -177532,7 +177532,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -177562,7 +177562,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -177591,7 +177591,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -177621,7 +177621,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -177650,7 +177650,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -177680,7 +177680,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178004,7 +178004,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178034,7 +178034,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178063,7 +178063,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178093,7 +178093,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178240,7 +178240,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178270,7 +178270,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178476,7 +178476,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178506,7 +178506,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178535,7 +178535,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178565,7 +178565,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178712,7 +178712,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178742,7 +178742,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178771,7 +178771,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178801,7 +178801,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178830,7 +178830,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178860,7 +178860,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178889,7 +178889,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178919,7 +178919,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178948,7 +178948,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -178978,7 +178978,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179007,7 +179007,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179037,7 +179037,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179125,7 +179125,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179155,7 +179155,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179331,7 +179331,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179361,7 +179361,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179390,7 +179390,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179420,7 +179420,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179449,7 +179449,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179479,7 +179479,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179567,7 +179567,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179597,7 +179597,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179744,7 +179744,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179774,7 +179774,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179862,7 +179862,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179892,7 +179892,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -179980,7 +179980,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180010,7 +180010,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180216,7 +180216,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180246,7 +180246,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180275,7 +180275,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180305,7 +180305,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180334,7 +180334,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180364,7 +180364,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180393,7 +180393,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180423,7 +180423,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180570,7 +180570,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180600,7 +180600,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180629,7 +180629,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180659,7 +180659,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180806,7 +180806,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180836,7 +180836,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180865,7 +180865,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180895,7 +180895,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180924,7 +180924,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -180954,7 +180954,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181219,7 +181219,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181249,7 +181249,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181396,7 +181396,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181426,7 +181426,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181455,7 +181455,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181485,7 +181485,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181514,7 +181514,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181544,7 +181544,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181573,7 +181573,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181603,7 +181603,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181632,7 +181632,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181662,7 +181662,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181691,7 +181691,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181721,7 +181721,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181750,7 +181750,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181780,7 +181780,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181868,7 +181868,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181898,7 +181898,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181927,7 +181927,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181957,7 +181957,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -181986,7 +181986,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182016,7 +182016,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182163,7 +182163,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182311,7 +182311,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182576,7 +182576,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182606,7 +182606,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182635,7 +182635,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182665,7 +182665,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182753,7 +182753,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182783,7 +182783,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182871,7 +182871,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182901,7 +182901,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182930,7 +182930,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182960,7 +182960,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build34-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -182989,7 +182989,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -183019,7 +183019,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -183048,7 +183048,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -183078,7 +183078,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -183166,7 +183166,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -183196,7 +183196,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -183402,7 +183402,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -183432,7 +183432,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -183579,7 +183579,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -183609,7 +183609,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -183992,7 +183992,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -184022,7 +184022,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -184110,7 +184110,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -184140,7 +184140,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build30-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -184169,7 +184169,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -184199,7 +184199,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -184228,7 +184228,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -184258,7 +184258,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build33-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -184818,7 +184818,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -184848,7 +184848,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -185526,7 +185526,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -185674,7 +185674,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build32-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -185703,7 +185703,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -185733,7 +185733,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -185762,7 +185762,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -185792,7 +185792,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build33-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -185821,7 +185821,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -185851,7 +185851,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build34-b1",
+              "id": "build31-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -185880,7 +185880,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -185910,7 +185910,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build30-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -185998,7 +185998,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
@@ -186028,7 +186028,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:161e",
-              "id": "build31-b1",
+              "id": "build32-b1",
               "os": "Windows-10-10240",
               "pool": "Chrome-perf"
             }
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 4123ca3c..c2c66ff 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -515,7 +515,10 @@
             ],
             "experiments": [
                 {
-                    "name": "Enabled"
+                    "name": "Enabled",
+                    "params": {
+                        "snackbar_promo_data_savings_in_megabytes": "1024;100"
+                    }
                 }
             ]
         }
@@ -1815,6 +1818,27 @@
             ]
         }
     ],
+    "ParallelDownloading": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "params": {
+                        "min_slice_size": "2097152",
+                        "parallel_request_delay": "5000",
+                        "parallel_request_remaining_time": "2",
+                        "request_count": "2"
+                    },
+                    "enable_features": [
+                        "ParallelDownloading"
+                    ]
+                }
+            ]
+        }
+    ],
     "PassiveDocumentEventListeners": [
         {
             "platforms": [
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 12b79ac..229c108 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -268,6 +268,269 @@
 # ====== LayoutNG-only failures from here ======
 # LayoutNG - is a new layout system for Blink.
 
+### external/wpt/css/CSS2/positioning
+#### Passed: 264 50%
+#### Skipped: 259
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-height-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-height-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-height-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-height-005.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-height-006.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-height-008.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-height-010.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-height-011.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-height-012.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-height-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-height-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-height-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-height-005.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-height-006.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-height-008.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-height-010.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-height-011.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-max-height-012.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-005.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-006.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-007.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-008.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-010.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-011.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-012.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-013.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-014.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-015.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-016.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-019.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-020.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-021.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-022.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-023.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-024.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-025.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-non-replaced-width-026.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-005.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-006.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-007.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-011.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-012.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-018.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-019.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-025.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-026.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-032.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-033.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-036.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-003a.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-003b.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-003c.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-013.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-023.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-024.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-027.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-030.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-031.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-032.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-037.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-038.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-051.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-052.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-064.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-065.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-066.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-067.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-width-071.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-007.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-008.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-011.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-012.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-017.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-018.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-019.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-020.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-022.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-024.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-027.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-028.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-containing-block-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-containing-block-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-containing-block-007.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-inline-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-inline-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-inline-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-inline-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-inline-005.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-inline-006.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-paged-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-paged-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-applies-to-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-applies-to-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-applies-to-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-applies-to-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-applies-to-005.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-applies-to-006.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-applies-to-007.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-applies-to-009.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-applies-to-012.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-applies-to-013.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-applies-to-014.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-applies-to-015.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-offset-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-offset-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-offset-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-offset-percentage-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/left-applies-to-009.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/left-applies-to-012.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/left-offset-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/left-offset-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/left-offset-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/left-offset-percentage-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-absolute-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-absolute-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-absolute-006.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-applies-to-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-applies-to-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-applies-to-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-applies-to-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-applies-to-005.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-applies-to-006.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-applies-to-007.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-applies-to-009.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-applies-to-012.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-applies-to-013.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-applies-to-014.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-applies-to-015.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-fixed-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-fixed-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-fixed-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-fixed-005.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-fixed-007.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-014.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-015.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-016.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-017.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-019.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-020.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-021.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-022.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-027.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-028.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-029.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-030.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-031.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-032.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-034.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-035.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-036.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-037.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-038.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-static-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/positioning-float-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/positioning-float-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/relpos-calcs-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/relpos-calcs-005.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-005.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-006.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-007.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-008.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-016.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-017.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-018.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-019.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-020.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-028.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-029.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-030.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-031.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-032.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-040.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-041.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-042.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-043.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-044.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-052.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-053.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-054.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-055.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-056.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-064.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-065.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-066.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-067.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-068.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-076.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-077.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-078.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-079.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-080.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-088.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-089.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-090.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-091.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-092.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-100.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-101.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-102.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-103.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-104.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-109.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-110.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-111.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-112.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-113.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-applies-to-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-applies-to-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-applies-to-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-applies-to-004.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-applies-to-005.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-applies-to-006.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-applies-to-007.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-applies-to-009.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-applies-to-012.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-applies-to-013.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-applies-to-014.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-applies-to-015.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-offset-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-offset-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-offset-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-offset-percentage-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-007.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-008.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-019.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-020.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-031.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-032.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-043.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-044.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-055.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-056.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-067.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-068.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-079.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-080.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-091.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-092.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-103.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-104.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-113.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-offset-001.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-offset-002.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-offset-003.xht [ Skip ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-offset-percentage-001.xht [ Skip ]
+
 #### external/wpt/css/CSS2/abspos
 #### Passed: 13 81%
 #### Skipped: 3
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites
index 80c24ad..9260384 100644
--- a/third_party/WebKit/LayoutTests/VirtualTestSuites
+++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -473,6 +473,21 @@
     "args": ["--enable-blink-features=LayoutNG"]
   },
   {
+    "prefix": "layout_ng",
+    "base": "external/wpt/css/CSS2/normal-flow",
+    "args": ["--enable-blink-features=LayoutNG"]
+  },
+  {
+    "prefix": "layout_ng",
+    "base": "external/wpt/css/CSS2/abspos",
+    "args": ["--enable-blink-features=LayoutNG"]
+  },
+  {
+    "prefix": "layout_ng",
+    "base": "external/wpt/css/CSS2/positioning",
+    "args": ["--enable-blink-features=LayoutNG"]
+  },
+  {
     "prefix": "feature-policy",
     "base": "http/tests/feature-policy",
     "args": ["--enable-blink-features=FeaturePolicy"]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/interfaces-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/interfaces-expected.txt
index 2e905df7..4a1dad92 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/dom/interfaces-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/dom/interfaces-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 1609 tests; 1429 PASS, 180 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 1609 tests; 1432 PASS, 177 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Event interface: existence and properties of interface object 
 PASS Event interface object length 
 PASS Event interface object name 
@@ -476,7 +476,7 @@
 PASS Node interface: xmlDoc must inherit property "NOTATION_NODE" with the proper type (11) 
 PASS Node interface: xmlDoc must inherit property "nodeType" with the proper type (12) 
 PASS Node interface: xmlDoc must inherit property "nodeName" with the proper type (13) 
-FAIL Node interface: xmlDoc must inherit property "baseURI" with the proper type (14) assert_equals: expected "string" but got "object"
+PASS Node interface: xmlDoc must inherit property "baseURI" with the proper type (14) 
 PASS Node interface: xmlDoc must inherit property "isConnected" with the proper type (15) 
 PASS Node interface: xmlDoc must inherit property "ownerDocument" with the proper type (16) 
 PASS Node interface: xmlDoc must inherit property "getRootNode" with the proper type (17) 
@@ -887,7 +887,7 @@
 PASS Node interface: element must inherit property "NOTATION_NODE" with the proper type (11) 
 PASS Node interface: element must inherit property "nodeType" with the proper type (12) 
 PASS Node interface: element must inherit property "nodeName" with the proper type (13) 
-FAIL Node interface: element must inherit property "baseURI" with the proper type (14) assert_equals: expected "string" but got "object"
+PASS Node interface: element must inherit property "baseURI" with the proper type (14) 
 PASS Node interface: element must inherit property "isConnected" with the proper type (15) 
 PASS Node interface: element must inherit property "ownerDocument" with the proper type (16) 
 PASS Node interface: element must inherit property "getRootNode" with the proper type (17) 
@@ -1207,7 +1207,7 @@
 PASS Node interface: xmlDoc.createProcessingInstruction("abc", "def") must inherit property "NOTATION_NODE" with the proper type (11) 
 PASS Node interface: xmlDoc.createProcessingInstruction("abc", "def") must inherit property "nodeType" with the proper type (12) 
 PASS Node interface: xmlDoc.createProcessingInstruction("abc", "def") must inherit property "nodeName" with the proper type (13) 
-FAIL Node interface: xmlDoc.createProcessingInstruction("abc", "def") must inherit property "baseURI" with the proper type (14) assert_equals: expected "string" but got "object"
+PASS Node interface: xmlDoc.createProcessingInstruction("abc", "def") must inherit property "baseURI" with the proper type (14) 
 PASS Node interface: xmlDoc.createProcessingInstruction("abc", "def") must inherit property "isConnected" with the proper type (15) 
 PASS Node interface: xmlDoc.createProcessingInstruction("abc", "def") must inherit property "ownerDocument" with the proper type (16) 
 PASS Node interface: xmlDoc.createProcessingInstruction("abc", "def") must inherit property "getRootNode" with the proper type (17) 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-misc-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-misc-expected.txt
index ab86e3b..f99d09f 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-misc-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/dom/reflection-misc-expected.txt
@@ -16,39 +16,7 @@
 PASS script.tabIndex: 24 tests
 PASS script.src: 38 tests
 PASS script.type: 32 tests
-FAIL script.noModule: typeof IDL attribute assert_equals: expected "boolean" but got "undefined"
-FAIL script.noModule: IDL get with DOM attribute unset assert_equals: expected (boolean) false but got (undefined) undefined
-FAIL script.noModule: setAttribute() to "" assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to " foo " assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to undefined assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to null assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to 7 assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to 1.5 assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to true assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to false assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to object "[object Object]" assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to NaN assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to Infinity assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to -Infinity assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to "\0" assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to object "test-toString" assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to object "test-valueOf" assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: setAttribute() to "noModule" assert_equals: IDL get expected (boolean) true but got (undefined) undefined
-FAIL script.noModule: IDL set to "" assert_equals: hasAttribute() expected false but got true
-FAIL script.noModule: IDL set to " foo " assert_equals: IDL get expected (boolean) true but got (string) " foo "
-FAIL script.noModule: IDL set to undefined assert_equals: hasAttribute() expected false but got true
-FAIL script.noModule: IDL set to null assert_equals: hasAttribute() expected false but got true
-FAIL script.noModule: IDL set to 7 assert_equals: IDL get expected (boolean) true but got (number) 7
-FAIL script.noModule: IDL set to 1.5 assert_equals: IDL get expected (boolean) true but got (number) 1.5
-PASS script.noModule: IDL set to true 
-FAIL script.noModule: IDL set to false assert_equals: hasAttribute() expected false but got true
-FAIL script.noModule: IDL set to object "[object Object]" assert_equals: IDL get expected (boolean) true but got (object) object "[object Object]"
-FAIL script.noModule: IDL set to NaN assert_equals: hasAttribute() expected false but got true
-FAIL script.noModule: IDL set to Infinity assert_equals: IDL get expected (boolean) true but got (number) Infinity
-FAIL script.noModule: IDL set to -Infinity assert_equals: IDL get expected (boolean) true but got (number) -Infinity
-FAIL script.noModule: IDL set to "\0" assert_equals: IDL get expected (boolean) true but got (string) "\0"
-FAIL script.noModule: IDL set to object "test-toString" assert_equals: IDL get expected (boolean) true but got (object) object "test-toString"
-FAIL script.noModule: IDL set to object "test-valueOf" assert_equals: IDL get expected (boolean) true but got (object) object "test-valueOf"
+PASS script.noModule: 33 tests
 PASS script.charset: 32 tests
 PASS script.defer: 33 tests
 PASS script.crossOrigin: 52 tests
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-reflect-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-reflect-expected.txt
deleted file mode 100644
index c009d0a..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-reflect-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-FAIL noModule IDL attribute on a parser created classic script element without nomodule content attribute assert_false: expected false got undefined
-FAIL noModule IDL attribute on a parser created classic script element with nomodule content attribute assert_true: expected true got undefined
-FAIL noModule IDL attribute on a parser created module script element without nomodule content attribute assert_false: expected false got undefined
-FAIL noModule IDL attribute on a parser created module script element with nomodule content attribute assert_true: expected true got undefined
-FAIL noModule IDL attribute on a dynamically created script element without nomodule content attribute assert_false: expected false got undefined
-FAIL noModule IDL attribute on a dynamically created script element after nomodule content attribute is set to "nomodule" assert_true: expected true got undefined
-FAIL noModule IDL attribute on a dynamically created script element after nomodule content attribute is set to "" assert_true: expected true got undefined
-FAIL noModule IDL attribute on a dynamically created script element after nomodule content attribute had been removed assert_true: expected true got undefined
-FAIL noModule IDL attribute must add nomodule content attribute on setting to true assert_true: expected true got false
-FAIL noModule IDL attribute must remove nomodule content attribute on setting to false assert_false: expected false got true
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script-expected.txt
deleted file mode 100644
index 3390614..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS An asynchronously loaded classic script with noModule set to false must run 
-FAIL An asynchronously loaded classic script with noModule set to true must not run assert_false: expected false got true
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-classic-scripts-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-classic-scripts-expected.txt
deleted file mode 100644
index b0b9aa143..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-inline-classic-scripts-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-PASS An inline classic script without nomodule content attribute must run 
-FAIL An inline classic script with nomodule content attribute must not run assert_false: expected false got true
-PASS An inline classic script element dynamically inserted after noModule was set to false must run. 
-FAIL An inline classic script element dynamically inserted after noModule was set to true must not run. assert_false: expected false got true
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts-expected.txt
deleted file mode 100644
index dcb5fc4b..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS A synchronously loaded external classic script without nomodule content attribute must run 
-FAIL A synchronously loaded external classic script with nomodule content attribute must not run assert_false: expected false got true
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/webgl/webgl-sharedarraybuffer.html b/third_party/WebKit/LayoutTests/fast/canvas/webgl/webgl-sharedarraybuffer.html
new file mode 100644
index 0000000..ef4f7ef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/webgl/webgl-sharedarraybuffer.html
@@ -0,0 +1,193 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="resources/webgl-test.js"></script>
+<script src="resources/webgl-test-utils.js"></script>
+</head>
+<body>
+<script>
+if (window.SharedArrayBuffer) {
+  var canvas = document.createElement("canvas");
+  var gl;
+  for (var name of ['webgl2', 'webgl']) {
+    try {
+      gl = canvas.getContext(name);
+    } catch(e) {
+    }
+    if (gl)
+      break;
+  }
+  var has_webgl2 = name == 'webgl2';
+
+  if (gl) {
+    // Nearly all of the tests below are invalid (e.g. will set the GL error),
+    // but we don't really care; we just want to ensure that passing a
+    // SharedArrayBuffer view is allowed and doesn't throw.
+    var sab = new SharedArrayBuffer(16);
+    var u8array = new Uint8Array(sab);
+    var i32array = new Int32Array(sab);
+    var u32array = new Uint32Array(sab);
+    var f32array = new Float32Array(sab);
+
+    var vs = "attribute float a; uniform float u; void main() {}";
+    var fs = "precision mediump float; void main() {}";
+    var program = WebGLTestUtils.loadProgram(gl, vs, fs);
+    var uniform = gl.getUniformLocation(program, 'u');
+    var attribute = gl.getAttribLocation(program, 'a');
+
+    test(() => {
+      gl.bufferData(gl.ARRAY_BUFFER, u8array, gl.STATIC_DRAW);
+      if (has_webgl2) {
+        gl.bufferData(gl.ARRAY_BUFFER, u8array, gl.STATIC_DRAW, 0, 1);
+      }
+    }, "bufferData");
+
+    test(() => {
+      gl.compressedTexImage2D(gl.TEXTURE_2D, 0, 0, 1, 1, 0, u8array);
+      if (has_webgl2) {
+        gl.compressedTexImage2D(gl.TEXTURE_2D, 0, 0, 1, 1, 0, u8array, 0);
+      }
+    }, "compressedTexImage2D");
+
+    test(() => {
+      gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 1, 1, 0, 0, u8array);
+      if (has_webgl2) {
+        gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 1, 1, 0, 0, u8array, 0);
+      }
+    }, "compressedTexSubImage2D");
+
+    test(() => {
+      gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, u8array);
+      if (has_webgl2) {
+        gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, u8array, 0);
+      }
+    }, "readPixels");
+
+    test(() => {
+      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA,
+                    gl.UNSIGNED_BYTE, u8array);
+      if (has_webgl2) {
+        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA,
+                      gl.UNSIGNED_BYTE, u8array, 0);
+      }
+    }, "texImage2D");
+
+    test(() => {
+      gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE,
+                       u8array);
+      if (has_webgl2) {
+        gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, gl.RGBA,
+                         gl.UNSIGNED_BYTE, u8array, 0);
+      }
+    }, "texSubImage2D");
+
+    test(() => {
+      gl.uniformMatrix2fv(uniform, false, f32array);
+    }, "uniformMatrix2fv");
+
+    test(() => {
+      gl.uniformMatrix3fv(uniform, false, f32array);
+    }, "uniformMatrix3fv");
+
+    test(() => {
+      gl.uniformMatrix4fv(uniform, false, f32array);
+    }, "uniformMatrix4fv");
+
+    test(() => {
+      gl.vertexAttrib1fv(attribute, f32array);
+    }, "vertexAttrib1fv");
+
+    test(() => {
+      gl.vertexAttrib2fv(attribute, f32array);
+    }, "vertexAttrib2fv");
+
+    test(() => {
+      gl.vertexAttrib3fv(attribute, f32array);
+    }, "vertexAttrib3fv");
+
+    test(() => {
+      gl.vertexAttrib4fv(attribute, f32array);
+    }, "vertexAttrib4fv");
+
+    if (has_webgl2) {
+      test(() => {
+        gl.bufferSubData(gl.ARRAY_BUFFER, 0, u8array, 0, 1);
+      }, "bufferSubData");
+
+      test(() => {
+        gl.getBufferSubData(gl.ARRAY_BUFFER, 0, u8array);
+      }, "getBufferSubData");
+
+      test(() => {
+        gl.compressedTexImage3D(gl.TEXTURE_3D, 0, 0, 1, 1, 1, 0, u8array);
+      }, "compressedTexImage3D");
+
+      test(() => {
+        gl.compressedTexSubImage3D(gl.TEXTURE_3D, 0, 0, 1, 1, 1, 0, 0, 0,
+                                   u8array);
+      }, "compressedTexSubImage3D");
+
+      test(() => {
+        gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, 1, 1, 0, 0,
+                      gl.UNSIGNED_BYTE, u8array);
+        gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, 1, 1, 0, 0,
+                      gl.UNSIGNED_BYTE, u8array, 0);
+      }, "texImage3D");
+
+      test(() => {
+        gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, gl.RGBA,
+                         gl.UNSIGNED_BYTE, u8array);
+      }, "texSubImage3D");
+
+      test(() => {
+        gl.uniformMatrix2x3fv(uniform, false, f32array);
+      }, "uniformMatrix2x3fv");
+
+      test(() => {
+        gl.uniformMatrix3x2fv(uniform, false, f32array);
+      }, "uniformMatrix3x2fv");
+
+      test(() => {
+        gl.uniformMatrix2x4fv(uniform, false, f32array);
+      }, "uniformMatrix2x4fv");
+
+      test(() => {
+        gl.uniformMatrix4x2fv(uniform, false, f32array);
+      }, "uniformMatrix4x2fv");
+
+      test(() => {
+        gl.uniformMatrix3x4fv(uniform, false, f32array);
+      }, "uniformMatrix3x4fv");
+
+      test(() => {
+        gl.uniformMatrix4x3fv(uniform, false, f32array);
+      }, "uniformMatrix4x3fv");
+
+      test(() => {
+        gl.vertexAttribI4iv(attribute, i32array);
+      }, "vertexAttribI4iv");
+
+      test(() => {
+        gl.vertexAttribI4uiv(attribute, u32array);
+      }, "vertexAttribI4uiv");
+
+      test(() => {
+        gl.clearBufferiv(gl.COLOR, 0, i32array);
+      }, "clearBufferiv");
+
+      test(() => {
+        gl.clearBufferuiv(gl.COLOR, 0, u32array);
+      }, "clearBufferuiv");
+
+      test(() => {
+        gl.clearBufferfv(gl.COLOR, 0, f32array);
+      }, "clearBufferfv");
+    }
+  }
+}
+done();
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/elements-test.js
index 495b94a..d965cc1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/elements-test.js
@@ -967,7 +967,7 @@
 
     function nodeResolved(node)
     {
-        InspectorTest.DOMAgent.getHighlightObjectForTest(node.id, report);
+        InspectorTest.OverlayAgent.getHighlightObjectForTest(node.id, report);
     }
 
     function report(error, result)
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
index 27539da..bee51ac1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
@@ -978,6 +978,7 @@
         InspectorTest.HeapProfilerAgent = target.heapProfilerAgent();
         InspectorTest.InspectorAgent = target.inspectorAgent();
         InspectorTest.NetworkAgent = target.networkAgent();
+        InspectorTest.OverlayAgent = target.overlayAgent();
         InspectorTest.PageAgent = target.pageAgent();
         InspectorTest.ProfilerAgent = target.profilerAgent();
         InspectorTest.RuntimeAgent = target.runtimeAgent();
@@ -992,6 +993,7 @@
         InspectorTest.domDebuggerModel = target.model(SDK.DOMDebuggerModel);
         InspectorTest.cssModel = target.model(SDK.CSSModel);
         InspectorTest.cpuProfilerModel = target.model(SDK.CPUProfilerModel);
+        InspectorTest.overlayModel = target.model(SDK.OverlayModel);
         InspectorTest.serviceWorkerManager = target.model(SDK.ServiceWorkerManager);
         InspectorTest.tracingManager = target.model(SDK.TracingManager);
         InspectorTest.mainTarget = target;
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-setInspectModeEnabled.html b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-setInspectModeEnabled.html
index 24432f9..f10e98e 100644
--- a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-setInspectModeEnabled.html
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-setInspectModeEnabled.html
@@ -7,9 +7,10 @@
 {
     var nodeInfo = {};
     InspectorTest.eventHandler["DOM.setChildNodes"] = setChildNodes;
-    InspectorTest.eventHandler["DOM.inspectNodeRequested"] = inspectNodeRequested;
+    InspectorTest.eventHandler["Overlay.inspectNodeRequested"] = inspectNodeRequested;
     InspectorTest.sendCommand("DOM.enable", {});
-    InspectorTest.sendCommand("DOM.setInspectMode", { "mode": "searchForNode", highlightConfig: {} }, onSetModeEnabled);
+    InspectorTest.sendCommand("Overlay.enable", {});
+    InspectorTest.sendCommand("Overlay.setInspectMode", { "mode": "searchForNode", highlightConfig: {} }, onSetModeEnabled);
 
     function onSetModeEnabled(message)
     {
diff --git a/third_party/WebKit/LayoutTests/inspector/agents-enable-disable-expected.txt b/third_party/WebKit/LayoutTests/inspector/agents-enable-disable-expected.txt
index e9cbe18..c9fe4a65 100644
--- a/third_party/WebKit/LayoutTests/inspector/agents-enable-disable-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/agents-enable-disable-expected.txt
@@ -11,6 +11,7 @@
 LayerTree.disable finished successfully
 Log.disable finished successfully
 Network.disable finished successfully
+Overlay.disable finished successfully
 Page.disable finished successfully
 Profiler.disable finished successfully
 Runtime.disable finished successfully
@@ -48,6 +49,9 @@
 Network.enable finished successfully
 Network.disable finished successfully
 
+Overlay.enable finished with error DOM should be enabled first
+Overlay.disable finished successfully
+
 Page.enable finished successfully
 Page.disable finished successfully
 
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/inspect-mode-after-profiling.html b/third_party/WebKit/LayoutTests/inspector/elements/inspect-mode-after-profiling.html
index 8d40576..cba03b6 100644
--- a/third_party/WebKit/LayoutTests/inspector/elements/inspect-mode-after-profiling.html
+++ b/third_party/WebKit/LayoutTests/inspector/elements/inspect-mode-after-profiling.html
@@ -18,7 +18,7 @@
 {
     InspectorTest.cpuProfilerModel.startRecording();
     InspectorTest.cpuProfilerModel.stopRecording();
-    InspectorTest.domModel.setInspectMode(Protocol.DOM.InspectMode.SearchForNode, clickAtInspected);
+    InspectorTest.overlayModel.setInspectMode(Protocol.Overlay.InspectMode.SearchForNode).then(clickAtInspected);
 
     function clickAtInspected()
     {
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/inspect-mode-shadow-text.html b/third_party/WebKit/LayoutTests/inspector/elements/inspect-mode-shadow-text.html
index 694383e..fb1e8d04 100644
--- a/third_party/WebKit/LayoutTests/inspector/elements/inspect-mode-shadow-text.html
+++ b/third_party/WebKit/LayoutTests/inspector/elements/inspect-mode-shadow-text.html
@@ -19,7 +19,7 @@
 
 function test()
 {
-    InspectorTest.domModel.setInspectMode(Protocol.DOM.InspectMode.SearchForNode, step2);
+    InspectorTest.overlayModel.setInspectMode(Protocol.Overlay.InspectMode.SearchForNode).then(step2);
 
     function step2()
     {
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/inspect-pointer-events-none.html b/third_party/WebKit/LayoutTests/inspector/elements/inspect-pointer-events-none.html
index 71505d93f..ab0ee74 100644
--- a/third_party/WebKit/LayoutTests/inspector/elements/inspect-pointer-events-none.html
+++ b/third_party/WebKit/LayoutTests/inspector/elements/inspect-pointer-events-none.html
@@ -59,7 +59,7 @@
 
     function step1()
     {
-        InspectorTest.domModel.setInspectMode(Protocol.DOM.InspectMode.SearchForNode, step2);
+        InspectorTest.overlayModel.setInspectMode(Protocol.Overlay.InspectMode.SearchForNode).then(step2);
     }
 
     function step2()
@@ -72,7 +72,7 @@
     {
         InspectorTest.firstElementsTreeOutline().removeEventListener(Elements.ElementsTreeOutline.Events.SelectedNodeChanged, step3);
         expectSelectedNode("inner");
-        InspectorTest.domModel.setInspectMode(Protocol.DOM.InspectMode.SearchForNode, step4);
+        InspectorTest.overlayModel.setInspectMode(Protocol.Overlay.InspectMode.SearchForNode).then(step4);
     }
 
     function step4()
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/inspect-pseudo-element.html b/third_party/WebKit/LayoutTests/inspector/elements/inspect-pseudo-element.html
index 5f34553..2598996 100644
--- a/third_party/WebKit/LayoutTests/inspector/elements/inspect-pseudo-element.html
+++ b/third_party/WebKit/LayoutTests/inspector/elements/inspect-pseudo-element.html
@@ -16,7 +16,7 @@
 
 function test()
 {
-    InspectorTest.domModel.setInspectMode(Protocol.DOM.InspectMode.SearchForNode, inspectModeEnabled);
+    InspectorTest.overlayModel.setInspectMode(Protocol.Overlay.InspectMode.SearchForNode).then(inspectModeEnabled);
 
     function inspectModeEnabled()
     {
diff --git a/third_party/WebKit/LayoutTests/inspector/layers/no-overlay-layers.html b/third_party/WebKit/LayoutTests/inspector/layers/no-overlay-layers.html
index 0a82d716..8300cdb 100644
--- a/third_party/WebKit/LayoutTests/inspector/layers/no-overlay-layers.html
+++ b/third_party/WebKit/LayoutTests/inspector/layers/no-overlay-layers.html
@@ -25,7 +25,7 @@
     {
         // Assure layer objects are not re-created during updates.
         InspectorTest.layerTreeModel().layerTree().forEachLayer(function(layer) { layersBeforeHighlight.push(layer.id()); });
-        InspectorTest.DOMAgent.highlightRect(0, 0, 200, 200, {r:255, g:0, b:0});
+        InspectorTest.OverlayAgent.highlightRect(0, 0, 200, 200, {r:255, g:0, b:0});
         InspectorTest.evaluateAndRunWhenTreeChanges("requestAnimationFrame(updateGeometry)", step2);
     }
 
diff --git a/third_party/WebKit/LayoutTests/inspector/profiler/agents-disabled-check-expected.txt b/third_party/WebKit/LayoutTests/inspector/profiler/agents-disabled-check-expected.txt
index 0d62404..accaa67 100644
--- a/third_party/WebKit/LayoutTests/inspector/profiler/agents-disabled-check-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/profiler/agents-disabled-check-expected.txt
@@ -1,22 +1,22 @@
 Test that if a profiler is working all the agents are disabled.
 
 --> SDK.targetManager.suspendAllTargets();
-frontend: {"id":<number>,"method":"Page.configureOverlay","params":{"suspended":true}}
 frontend: {"id":<number>,"method":"Target.setAutoAttach","params":{"autoAttach":true,"waitForDebuggerOnStart":false}}
 frontend: {"id":<number>,"method":"Debugger.disable"}
 frontend: {"id":<number>,"method":"Debugger.setAsyncCallStackDepth","params":{"maxDepth":0}}
-frontend: {"id":<number>,"method":"Page.configureOverlay","params":{"suspended":true}}
+frontend: {"id":<number>,"method":"Overlay.setPausedInDebuggerMessage"}
 frontend: {"id":<number>,"method":"DOM.disable"}
 frontend: {"id":<number>,"method":"CSS.disable"}
+frontend: {"id":<number>,"method":"Overlay.setSuspended","params":{"suspended":true}}
 
 --> SDK.targetManager.resumeAllTargets();
-frontend: {"id":<number>,"method":"Page.configureOverlay","params":{"suspended":false}}
 frontend: {"id":<number>,"method":"Target.setAutoAttach","params":{"autoAttach":true,"waitForDebuggerOnStart":true}}
 frontend: {"id":<number>,"method":"Debugger.enable"}
 frontend: {"id":<number>,"method":"Debugger.setPauseOnExceptions","params":{"state":"none"}}
 frontend: {"id":<number>,"method":"Debugger.setAsyncCallStackDepth","params":{"maxDepth":8}}
 frontend: {"id":<number>,"method":"DOM.enable"}
 frontend: {"id":<number>,"method":"CSS.enable"}
+frontend: {"id":<number>,"method":"Overlay.setSuspended","params":{"suspended":false}}
 
 --> done
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/dom/HTMLProgressElement/progress-element-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/dom/HTMLProgressElement/progress-element-expected.png
index fa9de355..52de6431 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/dom/HTMLProgressElement/progress-element-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/dom/HTMLProgressElement/progress-element-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/layout_ng/external/wpt/css/CSS2/positioning/README.txt b/third_party/WebKit/LayoutTests/virtual/layout_ng/external/wpt/css/CSS2/positioning/README.txt
new file mode 100644
index 0000000..544f549f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/layout_ng/external/wpt/css/CSS2/positioning/README.txt
@@ -0,0 +1,3 @@
+# This suite runs the tests in external/wpt/css/CSS2/positioning with
+# --enable-blink-features=LayoutNG.
+# The LayoutNG project is described here: http://goo.gl/1hwhfX
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
index 3813f6b..960ac76c 100644
--- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/webexposed/global-interface-listing-expected.txt
@@ -3217,6 +3217,7 @@
     getter event
     getter htmlFor
     getter integrity
+    getter noModule
     getter nonce
     getter src
     getter text
@@ -3229,6 +3230,7 @@
     setter event
     setter htmlFor
     setter integrity
+    setter noModule
     setter nonce
     setter src
     setter text
diff --git a/third_party/WebKit/LayoutTests/webaudio/ConstantSource/constant-source-basic.html b/third_party/WebKit/LayoutTests/webaudio/ConstantSource/constant-source-basic.html
index 605385979..6ec87340 100644
--- a/third_party/WebKit/LayoutTests/webaudio/ConstantSource/constant-source-basic.html
+++ b/third_party/WebKit/LayoutTests/webaudio/ConstantSource/constant-source-basic.html
@@ -5,7 +5,7 @@
     <script src="../../resources/testharness.js"></script>
     <script src="../../resources/testharnessreport.js"></script>
     <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audio-testing.js"></script>
+    <script src="../resources/audit.js"></script>
   </head>
 
   <body>
@@ -14,78 +14,63 @@
 
       var audit = Audit.createTaskRunner();
 
-      audit.defineTask("createConstantSource()", function (taskDone) {
+      audit.define("createConstantSource()", (task, should) => {
         var node;
-        var success = true;
         var prefix = "Factory method: ";
 
-        success = Should(prefix + "node = context.createConstantSource()", function () {
+        should(() => {
           node = context.createConstantSource();
-        }).notThrow();
-        success = Should(prefix + "node instance of ConstantSourceNode",
-          node instanceof ConstantSourceNode)
-          .beEqualTo(true) && success;
+        }, prefix + "node = context.createConstantSource()").notThrow();
+        should(node instanceof ConstantSourceNode,
+          prefix + "node instance of ConstantSourceNode")
+          .beEqualTo(true);
       
-        success = verifyNodeDefaults(node, prefix) && success;
+        verifyNodeDefaults(should, node, prefix);
 
-        Should("createConstantSource()", success)
-          .summarize(
-            "correctly created",
-            "incorrectly created");
-
-        taskDone();
+        task.done();
       });
 
-      audit.defineTask("new ConstantSourceNode()", function (taskDone) {
+      audit.define("new ConstantSourceNode()", (task, should) => {
         var node;
-        var success = true;
         var prefix = "Constructor: ";
 
-        success = Should(prefix + "node = new ConstantSourceNode()", function () {
+        should(() => {
           node = new ConstantSourceNode(context);
-        }).notThrow();
-        success = Should(prefix + "node instance of ConstantSourceNode",
-          node instanceof ConstantSourceNode)
-          .beEqualTo(true) && success;
+        }, prefix + "node = new ConstantSourceNode()").notThrow();
+        should(node instanceof ConstantSourceNode,
+          prefix + "node instance of ConstantSourceNode")
+          .beEqualTo(true);
 
       
-        success = verifyNodeDefaults(node, prefix) && success;
+        verifyNodeDefaults(should, node, prefix);
 
-        Should("new ConstantSourceNode(context)", success)
-          .summarize(
-            "correctly created",
-            "incorrectly created");
-
-        taskDone();
+        task.done();
       });
 
-      function verifyNodeDefaults(node, prefix) {
-        var success = true;
-
-        success = Should(prefix + "node.numberOfInputs", node.numberOfInputs)
+      function verifyNodeDefaults(should, node, prefix) {
+        should(node.numberOfInputs, prefix + "node.numberOfInputs")
           .beEqualTo(0);
-        success = Should(prefix + "node.numberOfOutputs", node.numberOfOutputs)
-          .beEqualTo(1) && success;
-        success = Should(prefix + "node.channelCount", node.channelCount)
-          .beEqualTo(2) && success;
-        success = Should(prefix + "node.channelCountMode", node.channelCountMode)
-          .beEqualTo("max") && success;
-        success = Should(prefix + "node.channelInterpretation", node.channelInterpretation)
-          .beEqualTo("speakers") && success;
+        should(node.numberOfOutputs, prefix + "node.numberOfOutputs")
+          .beEqualTo(1);
+        should(node.channelCount, prefix + "node.channelCount")
+          .beEqualTo(2);
+        should(node.channelCountMode, prefix + "node.channelCountMode")
+          .beEqualTo("max");
+        should(node.channelInterpretation,
+            prefix + "node.channelInterpretation")
+          .beEqualTo("speakers");
 
-        success = Should(prefix + "node.offset.value", node.offset.value)
-          .beEqualTo(1) && success;
-        success = Should(prefix + "node.offset.defaultValue", node.offset.defaultValue)
-          .beEqualTo(1) && success;
-        success = Should(prefix + "node.offset.minValue", node.offset.minValue)
-          .beEqualTo(Math.fround(-3.4028235e38)) && success;
-        success = Should(prefix + "node.offset.maxValue", node.offset.maxValue)
-          .beEqualTo(Math.fround(3.4028235e38)) && success;
-      
-        return success;
+        should(node.offset.value, prefix + "node.offset.value")
+          .beEqualTo(1);
+        should(node.offset.defaultValue, prefix + "node.offset.defaultValue")
+          .beEqualTo(1);
+        should(node.offset.minValue, prefix + "node.offset.minValue")
+          .beEqualTo(Math.fround(-3.4028235e38));
+        should(node.offset.maxValue, prefix + "node.offset.maxValue")
+          .beEqualTo(Math.fround(3.4028235e38));
       }
 
-      audit.runTasks();
+      audit.run();
     </script>
   </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/ConstantSource/constant-source-onended.html b/third_party/WebKit/LayoutTests/webaudio/ConstantSource/constant-source-onended.html
index 2ab18c75..b0960a8 100644
--- a/third_party/WebKit/LayoutTests/webaudio/ConstantSource/constant-source-onended.html
+++ b/third_party/WebKit/LayoutTests/webaudio/ConstantSource/constant-source-onended.html
@@ -4,8 +4,6 @@
     <title>Test ConstantSourceNode onended</title>
     <script src="../../resources/testharness.js"></script>
     <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audio-testing.js"></script>
   </head>
 
   <body>
diff --git a/third_party/WebKit/LayoutTests/webaudio/ConstantSource/constant-source-output.html b/third_party/WebKit/LayoutTests/webaudio/ConstantSource/constant-source-output.html
index 5efb887..0202abe3 100644
--- a/third_party/WebKit/LayoutTests/webaudio/ConstantSource/constant-source-output.html
+++ b/third_party/WebKit/LayoutTests/webaudio/ConstantSource/constant-source-output.html
@@ -5,7 +5,7 @@
     <script src="../../resources/testharness.js"></script>
     <script src="../../resources/testharnessreport.js"></script>
     <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audio-testing.js"></script>
+    <script src="../resources/audit.js"></script>
     <script src="../resources/audioparam-testing.js"></script>
   </head>
 
@@ -17,7 +17,7 @@
 
       var audit = Audit.createTaskRunner();
 
-      audit.defineTask("constant source", function (taskDone) {
+      audit.define("constant source", (task, should) => {
         // Verify a constant source outputs the correct (fixed) constant.
         var context = new OfflineAudioContext(1, renderFrames, sampleRate);
         var node = new ConstantSourceNode(context, {
@@ -31,12 +31,12 @@
           var expected = new Float32Array(actual.length);
           expected.fill(node.offset.value);
 
-          Should("Basic: ConstantSourceNode({offset: 0.5})", actual)
+          should(actual, "Basic: ConstantSourceNode({offset: 0.5})")
             .beEqualToArray(expected);
-        }).then(taskDone);
+        }).then(() => task.done());
       });
 
-      audit.defineTask("start/stop", function (taskDone) {
+      audit.define("start/stop", (task, should) => {
         // Verify a constant source starts and stops at the correct time and has
         // the correct (fixed) value.
         var context = new OfflineAudioContext(1, renderFrames, sampleRate);
@@ -62,31 +62,27 @@
           }
 
           var prefix = "start/stop: ";
-          var success = Should(prefix + "ConstantSourceNode frames [0, " +
-              startFrame + ")",
-              actual.slice(0, startFrame))
+          should(actual.slice(0, startFrame,
+              prefix + "ConstantSourceNode frames [0, " +
+              startFrame + ")"
+              ))
             .beConstantValueOf(0);
 
-          success = Should(prefix + "ConstantSourceNode frames [" + startFrame +
+          should(actual.slice(startFrame, stopFrame,
+              prefix + "ConstantSourceNode frames [" + startFrame +
               ", " +
-              stopFrame + ")",
-              actual.slice(startFrame, stopFrame))
-            .beConstantValueOf(1) && success;
+              stopFrame + ")"))
+            .beConstantValueOf(1);
 
-          success = Should(prefix + "ConstantSourceNode frames [" + stopFrame + ", " +
-              renderFrames + ")",
-              actual.slice(stopFrame))
-            .beConstantValueOf(0) && success;
-
-          Should("ConstantSourceNode started and stopped", success)
-            .summarize(
-              "at the correct times with the correct values",
-              "with the incorrect times or values");
-        }).then(taskDone);
+          should(actual.slice(stopFrame),
+              prefix + "ConstantSourceNode frames [" + stopFrame + ", " +
+              renderFrames + ")")
+            .beConstantValueOf(0);
+        }).then(() => task.done());
         
       });
 
-      audit.defineTask("basic automation", function (taskDone) {
+      audit.define("basic automation", (task, should) => {
         // Verify that automation works as expected.
         var context = new OfflineAudioContext(1, renderFrames, sampleRate);
         var source = context.createConstantSource();
@@ -107,26 +103,21 @@
             var rampEndFrame = Math.ceil(rampEndTime * context.sampleRate);
             var prefix = "Automation: ";
 
-            var success = Should(prefix + "ConstantSourceNode.linearRamp(1, 0.5)",
-                actual.slice(0, rampEndFrame))
+            should(actual.slice(0, rampEndFrame,
+                prefix + "ConstantSourceNode.linearRamp(1, 0.5)"))
               .beCloseToArray(expected, {
                 // Experimentally determined threshold..
                 relativeThreshold: 7.1610e-7
               });
 
-            success = Should(prefix + "ConstantSourceNode after ramp",
-                actual.slice(rampEndFrame))
-              .beConstantValueOf(1) && success;
-
-            Should("ConstantSourceNode automation", success)
-              .summarize(
-                "produced the correct values",
-                "did not produce the correct values");
+            should(actual.slice(rampEndFrame),
+                prefix + "ConstantSourceNode after ramp")
+              .beConstantValueOf(1);
           })
-          .then(taskDone);
+          .then(() => task.done());
       });
       
-      audit.defineTask("connected audioparam", function (taskDone) {
+      audit.define("connected audioparam", (task, should) => {
         // Verify the constant source output with connected AudioParam produces
         // the correct output.
         var context = new OfflineAudioContext(2, renderFrames, sampleRate)
@@ -155,32 +146,26 @@
             // The expected output should be oscillator + 1 because offset
             // is 1.
             expected = expected.map(x => 1 + x);
-            var success = true;
             var prefix = "Connected param: ";
 
             // The initial part of the output should be silent because the
             // source node hasn't started yet.
-            success = Should(prefix + "ConstantSourceNode frames [0, " +
-                sourceStartFrame + ")", actual.slice(0, sourceStartFrame)
-              )
+            should(actual.slice(0, sourceStartFrame),
+                prefix + "ConstantSourceNode frames [0, " +
+                sourceStartFrame + ")")
               .beConstantValueOf(0);
             // The rest of the output should be the same as the oscillator (in
             // channel 1)
-            success = Should(prefix + "ConstantSourceNode frames [" +
-                sourceStartFrame + ", " + renderFrames + ")",
-                actual.slice(sourceStartFrame))
+            should(actual.slice(sourceStartFrame),
+                prefix + "ConstantSourceNode frames [" +
+                sourceStartFrame + ", " + renderFrames + ")")
               .beCloseToArray(expected.slice(sourceStartFrame), 0);
 
-            Should("ConstantSourceNode with connected AudioParam",
-                success)
-              .summarize(
-                "had the expected output",
-                "did not have the expected output");
           })
-          .then(taskDone);
+          .then(() => task.done());
       });
 
-      audit.runTasks();
+      audit.run();
     </script>
   </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt
index bb77da6..27455518 100644
--- a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt
@@ -836,6 +836,7 @@
     property event
     property htmlFor
     property integrity
+    property noModule
     property nonce
     property src
     property text
@@ -1433,6 +1434,7 @@
     property event
     property htmlFor
     property integrity
+    property noModule
     property nonce
     property src
     property text
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 32079e5..9027ab77 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -3217,6 +3217,7 @@
     getter event
     getter htmlFor
     getter integrity
+    getter noModule
     getter nonce
     getter src
     getter text
@@ -3229,6 +3230,7 @@
     setter event
     setter htmlFor
     setter integrity
+    setter noModule
     setter nonce
     setter src
     setter text
diff --git a/third_party/WebKit/Source/bindings/IDLExtendedAttributes.md b/third_party/WebKit/Source/bindings/IDLExtendedAttributes.md
index 986f8f2..fd4b6d404 100644
--- a/third_party/WebKit/Source/bindings/IDLExtendedAttributes.md
+++ b/third_party/WebKit/Source/bindings/IDLExtendedAttributes.md
@@ -1425,6 +1425,21 @@
 
 Usage: Applies to arguments of methods. See modules/webgl/WebGLRenderingContextBase.idl for an example.
 
+### [AllowShared] _(p)_
+
+Summary: `[AllowShared]` indicates that a parameter, which must be an ArrayBufferView (or subtype of, e.g. typed arrays), is allowed to be backed by a SharedArrayBuffer.
+
+Usage: `[AllowShared]` must be specified on a parameter to a method:
+
+```webidl
+interface Context {
+    void bufferData1([AllowShared] ArrayBufferView buffer);
+    void bufferData2([AllowShared] Float32Array buffer);
+}
+```
+
+A SharedArrayBuffer is a distinct type from an ArrayBuffer, but both types use ArrayBufferViews to view the data in the buffer. Most methods do not permit an ArrayBufferView that is backed by a SharedArrayBuffer, and will throw an exception. This attribute indicates that this method permits a shared ArrayBufferView.
+
 ### [PermissiveDictionaryConversion] _(p, d)_
 
 Summary: `[PermissiveDictionaryConversion]` relaxes the rules about what types of values may be passed for an argument of dictionary type.
diff --git a/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt b/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt
index deaea6a5..56c4104 100644
--- a/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt
+++ b/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt
@@ -32,6 +32,7 @@
 #
 
 ActiveScriptWrappable
+AllowShared
 CEReactions
 CachedAccessor
 CachedAttribute=*
diff --git a/third_party/WebKit/Source/bindings/core/v8/ToV8.h b/third_party/WebKit/Source/bindings/core/v8/ToV8.h
index 433c174..10c1cd9 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ToV8.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ToV8.h
@@ -17,6 +17,7 @@
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "bindings/core/v8/V8Binding.h"
 #include "core/CoreExport.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/Forward.h"
 #include "v8/include/v8.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/ToV8ForCore.h b/third_party/WebKit/Source/bindings/core/v8/ToV8ForCore.h
index cb3fed42..96cd46b 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ToV8ForCore.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ToV8ForCore.h
@@ -9,7 +9,7 @@
 // handle. Call sites must check IsEmpty() before using return value.
 
 #include "bindings/core/v8/ToV8.h"
-#include "core/dom/NotShared.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "v8/include/v8.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Binding.h b/third_party/WebKit/Source/bindings/core/v8/V8Binding.h
index 0beb32ac..f14d0f6 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8Binding.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8Binding.h
@@ -47,7 +47,7 @@
 #include "bindings/core/v8/V8ThrowException.h"
 #include "bindings/core/v8/V8ValueCache.h"
 #include "core/CoreExport.h"
-#include "core/dom/NotShared.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/text/AtomicString.h"
 #include "platform/wtf/text/StringView.h"
@@ -1119,6 +1119,18 @@
   return NotSharedType(dom_typed_array);
 }
 
+// Wrap a typed array value in MaybeShared<>, to signify that it may be backed
+// by a SharedArrayBuffer.
+template <typename MaybeSharedType>
+MaybeSharedType ToMaybeShared(v8::Isolate* isolate,
+                              v8::Local<v8::Value> value,
+                              ExceptionState& exception_state) {
+  using DOMTypedArray = typename MaybeSharedType::TypedArrayType;
+  DOMTypedArray* dom_typed_array =
+      V8TypeOf<DOMTypedArray>::Type::toImplWithTypeCheck(isolate, value);
+  return MaybeSharedType(dom_typed_array);
+}
+
 }  // namespace blink
 
 #endif  // V8Binding_h
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_types.py b/third_party/WebKit/Source/bindings/scripts/v8_types.py
index fbb0dc8..7f71696 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_types.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_types.py
@@ -210,7 +210,10 @@
         return 'Flexible' + base_idl_type + 'View'
     if base_idl_type in ARRAY_BUFFER_VIEW_AND_TYPED_ARRAY_TYPES:
         if not used_in_cpp_sequence:
-            return cpp_template_type('NotShared', idl_type.implemented_as)
+            if 'AllowShared' in extended_attributes:
+                return cpp_template_type('MaybeShared', idl_type.implemented_as)
+            else:
+                return cpp_template_type('NotShared', idl_type.implemented_as)
     if idl_type.is_interface_type:
         implemented_as_class = idl_type.implemented_as
         if raw_type or (used_as_rvalue_type and idl_type.is_garbage_collected) or not used_in_cpp_sequence:
@@ -352,7 +355,7 @@
 INCLUDES_FOR_TYPE = {
     'object': set(),
     'ArrayBufferView': set(['bindings/core/v8/V8ArrayBufferView.h',
-                            'core/dom/NotShared.h',
+                            'core/dom/ArrayBufferViewHelpers.h',
                             'core/dom/FlexibleArrayBufferView.h']),
     'Dictionary': set(['bindings/core/v8/Dictionary.h']),
     'EventHandler': set(['bindings/core/v8/V8AbstractEventListener.h',
@@ -472,7 +475,7 @@
     if base_idl_type in INCLUDES_FOR_TYPE:
         includes_for_type.update(INCLUDES_FOR_TYPE[base_idl_type])
     if idl_type.is_array_buffer_view_or_typed_array:
-        return set(['core/dom/DOMTypedArray.h', 'core/dom/NotShared.h'])
+        return set(['core/dom/DOMTypedArray.h', 'core/dom/ArrayBufferViewHelpers.h'])
     return includes_for_type
 
 
@@ -593,6 +596,9 @@
             raise ValueError("Unrecognized base type for extended attribute 'FlexibleArrayBufferView': %s" % (idl_type.base_type))
         base_idl_type = 'FlexibleArrayBufferView'
 
+    if 'AllowShared' in extended_attributes and not idl_type.is_array_buffer_view_or_typed_array:
+        raise ValueError("Unrecognized base type for extended attribute 'AllowShared': %s" % (idl_type.base_type))
+
     if idl_type.is_integer_type:
         configuration = 'kNormalConversion'
         if 'EnforceRange' in extended_attributes:
@@ -612,8 +618,12 @@
             '{v8_value}->Is{idl_type}() ? '
             'V8{idl_type}::toImpl(v8::Local<v8::{idl_type}>::Cast({v8_value})) : 0')
     elif idl_type.is_array_buffer_view_or_typed_array:
-        this_cpp_type = idl_type.cpp_type
-        cpp_expression_format = ('ToNotShared<%s>({isolate}, {v8_value}, exceptionState)' % this_cpp_type)
+        this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attributes)
+        if 'AllowShared' in extended_attributes:
+            cpp_expression_format = ('ToMaybeShared<%s>({isolate}, {v8_value}, exceptionState)' % this_cpp_type)
+        else:
+            cpp_expression_format = ('ToNotShared<%s>({isolate}, {v8_value}, exceptionState)' % this_cpp_type)
+
     elif idl_type.is_union_type:
         nullable = 'UnionTypeConversionMode::kNullable' if idl_type.includes_nullable_type \
             else 'UnionTypeConversionMode::kNotNullable'
diff --git a/third_party/WebKit/Source/bindings/tests/idls/core/TestObject.idl b/third_party/WebKit/Source/bindings/tests/idls/core/TestObject.idl
index 704db79..f07e4d0 100644
--- a/third_party/WebKit/Source/bindings/tests/idls/core/TestObject.idl
+++ b/third_party/WebKit/Source/bindings/tests/idls/core/TestObject.idl
@@ -297,6 +297,8 @@
     void voidMethodFloat32ArrayArg(Float32Array float32ArrayArg);
     void voidMethodInt32ArrayArg(Int32Array int32ArrayArg);
     void voidMethodUint8ArrayArg(Uint8Array uint8ArrayArg);
+    void voidMethodAllowSharedArrayBufferViewArg([AllowShared] ArrayBufferView arrayBufferViewArg);
+    void voidMethodAllowSharedUint8ArrayArg([AllowShared] Uint8Array uint8ArrayArg);
     // Arrays
     long[] longArrayMethod();
     DOMString[] stringArrayMethod();
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/ArrayBufferOrArrayBufferViewOrDictionary.h b/third_party/WebKit/Source/bindings/tests/results/core/ArrayBufferOrArrayBufferViewOrDictionary.h
index 826a920b..020a15a 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/ArrayBufferOrArrayBufferViewOrDictionary.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/ArrayBufferOrArrayBufferViewOrDictionary.h
@@ -18,8 +18,8 @@
 #include "bindings/core/v8/V8ArrayBufferView.h"
 #include "bindings/core/v8/V8Binding.h"
 #include "core/CoreExport.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/FlexibleArrayBufferView.h"
-#include "core/dom/NotShared.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/StringOrArrayBufferOrArrayBufferView.h b/third_party/WebKit/Source/bindings/tests/results/core/StringOrArrayBufferOrArrayBufferView.h
index 9d3c93e..bdb09e2 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/StringOrArrayBufferOrArrayBufferView.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/StringOrArrayBufferOrArrayBufferView.h
@@ -18,8 +18,8 @@
 #include "bindings/core/v8/V8ArrayBufferView.h"
 #include "bindings/core/v8/V8Binding.h"
 #include "core/CoreExport.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/FlexibleArrayBufferView.h"
-#include "core/dom/NotShared.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h
index 3488b36..58166c5 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h
@@ -21,8 +21,8 @@
 #include "bindings/core/v8/TestInterface2OrUint8Array.h"
 #include "bindings/tests/idls/core/TestInterface2.h"
 #include "core/CoreExport.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "core/testing/InternalDictionary.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/Vector.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/TestInterface2OrUint8Array.h b/third_party/WebKit/Source/bindings/tests/results/core/TestInterface2OrUint8Array.h
index ae0f637..9be1c52 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/TestInterface2OrUint8Array.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/TestInterface2OrUint8Array.h
@@ -19,8 +19,8 @@
 #include "bindings/core/v8/V8Binding.h"
 #include "bindings/core/v8/V8Uint8Array.h"
 #include "core/CoreExport.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/FlexibleArrayBufferView.h"
-#include "core/dom/NotShared.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8DataView.h b/third_party/WebKit/Source/bindings/tests/results/core/V8DataView.h
index fa0df7c..0375909 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8DataView.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8DataView.h
@@ -22,8 +22,8 @@
 #include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestDataView.h"
 #include "core/CoreExport.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/FlexibleArrayBufferView.h"
-#include "core/dom/NotShared.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
index 536981b..e10b295 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
@@ -25,8 +25,8 @@
 #include "bindings/core/v8/V8TestInterfaceGarbageCollected.h"
 #include "bindings/core/v8/V8TestObject.h"
 #include "bindings/core/v8/V8Uint8Array.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/FlexibleArrayBufferView.h"
-#include "core/dom/NotShared.h"
 #include "core/frame/Deprecation.h"
 #include "platform/RuntimeEnabledFeatures.h"
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
index 2cbcbc5..2a049786 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
@@ -57,11 +57,11 @@
 #include "bindings/core/v8/V8Window.h"
 #include "bindings/core/v8/V8XPathNSResolver.h"
 #include "core/HTMLNames.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/ClassCollection.h"
 #include "core/dom/DOMArrayBufferBase.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/dom/FlexibleArrayBufferView.h"
-#include "core/dom/NotShared.h"
 #include "core/dom/TagCollection.h"
 #include "core/dom/custom/V0CustomElementProcessingStack.h"
 #include "core/frame/Deprecation.h"
@@ -4878,6 +4878,52 @@
   impl->voidMethodUint8ArrayArg(uint8ArrayArg);
 }
 
+static void voidMethodAllowSharedArrayBufferViewArgMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kExecutionContext, "TestObject", "voidMethodAllowSharedArrayBufferViewArg");
+
+  TestObject* impl = V8TestObject::toImpl(info.Holder());
+
+  if (UNLIKELY(info.Length() < 1)) {
+    exceptionState.ThrowTypeError(ExceptionMessages::NotEnoughArguments(1, info.Length()));
+    return;
+  }
+
+  MaybeShared<TestArrayBufferView> arrayBufferViewArg;
+  arrayBufferViewArg = ToMaybeShared<MaybeShared<TestArrayBufferView>>(info.GetIsolate(), info[0], exceptionState);
+  if (exceptionState.HadException())
+    return;
+  if (!arrayBufferViewArg) {
+    exceptionState.ThrowTypeError("parameter 1 is not of type 'ArrayBufferView'.");
+
+    return;
+  }
+
+  impl->voidMethodAllowSharedArrayBufferViewArg(arrayBufferViewArg);
+}
+
+static void voidMethodAllowSharedUint8ArrayArgMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kExecutionContext, "TestObject", "voidMethodAllowSharedUint8ArrayArg");
+
+  TestObject* impl = V8TestObject::toImpl(info.Holder());
+
+  if (UNLIKELY(info.Length() < 1)) {
+    exceptionState.ThrowTypeError(ExceptionMessages::NotEnoughArguments(1, info.Length()));
+    return;
+  }
+
+  MaybeShared<DOMUint8Array> uint8ArrayArg;
+  uint8ArrayArg = ToMaybeShared<MaybeShared<DOMUint8Array>>(info.GetIsolate(), info[0], exceptionState);
+  if (exceptionState.HadException())
+    return;
+  if (!uint8ArrayArg) {
+    exceptionState.ThrowTypeError("parameter 1 is not of type 'Uint8Array'.");
+
+    return;
+  }
+
+  impl->voidMethodAllowSharedUint8ArrayArg(uint8ArrayArg);
+}
+
 static void longArrayMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
@@ -11001,6 +11047,14 @@
   TestObjectV8Internal::voidMethodUint8ArrayArgMethod(info);
 }
 
+void V8TestObject::voidMethodAllowSharedArrayBufferViewArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  TestObjectV8Internal::voidMethodAllowSharedArrayBufferViewArgMethod(info);
+}
+
+void V8TestObject::voidMethodAllowSharedUint8ArrayArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  TestObjectV8Internal::voidMethodAllowSharedUint8ArrayArgMethod(info);
+}
+
 void V8TestObject::longArrayMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
   TestObjectV8Internal::longArrayMethodMethod(info);
 }
@@ -12076,6 +12130,8 @@
     {"voidMethodFloat32ArrayArg", V8TestObject::voidMethodFloat32ArrayArgMethodCallback, 1, v8::None, V8DOMConfiguration::kOnPrototype, V8DOMConfiguration::kCheckHolder, V8DOMConfiguration::kDoNotCheckAccess, V8DOMConfiguration::kAllWorlds},
     {"voidMethodInt32ArrayArg", V8TestObject::voidMethodInt32ArrayArgMethodCallback, 1, v8::None, V8DOMConfiguration::kOnPrototype, V8DOMConfiguration::kCheckHolder, V8DOMConfiguration::kDoNotCheckAccess, V8DOMConfiguration::kAllWorlds},
     {"voidMethodUint8ArrayArg", V8TestObject::voidMethodUint8ArrayArgMethodCallback, 1, v8::None, V8DOMConfiguration::kOnPrototype, V8DOMConfiguration::kCheckHolder, V8DOMConfiguration::kDoNotCheckAccess, V8DOMConfiguration::kAllWorlds},
+    {"voidMethodAllowSharedArrayBufferViewArg", V8TestObject::voidMethodAllowSharedArrayBufferViewArgMethodCallback, 1, v8::None, V8DOMConfiguration::kOnPrototype, V8DOMConfiguration::kCheckHolder, V8DOMConfiguration::kDoNotCheckAccess, V8DOMConfiguration::kAllWorlds},
+    {"voidMethodAllowSharedUint8ArrayArg", V8TestObject::voidMethodAllowSharedUint8ArrayArgMethodCallback, 1, v8::None, V8DOMConfiguration::kOnPrototype, V8DOMConfiguration::kCheckHolder, V8DOMConfiguration::kDoNotCheckAccess, V8DOMConfiguration::kAllWorlds},
     {"longArrayMethod", V8TestObject::longArrayMethodMethodCallback, 0, v8::None, V8DOMConfiguration::kOnPrototype, V8DOMConfiguration::kCheckHolder, V8DOMConfiguration::kDoNotCheckAccess, V8DOMConfiguration::kAllWorlds},
     {"stringArrayMethod", V8TestObject::stringArrayMethodMethodCallback, 0, v8::None, V8DOMConfiguration::kOnPrototype, V8DOMConfiguration::kCheckHolder, V8DOMConfiguration::kDoNotCheckAccess, V8DOMConfiguration::kAllWorlds},
     {"testInterfaceEmptyArrayMethod", V8TestObject::testInterfaceEmptyArrayMethodMethodCallback, 0, v8::None, V8DOMConfiguration::kOnPrototype, V8DOMConfiguration::kCheckHolder, V8DOMConfiguration::kDoNotCheckAccess, V8DOMConfiguration::kAllWorlds},
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.h
index aca0212..799cecf 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.h
@@ -438,6 +438,8 @@
   CORE_EXPORT static void voidMethodFloat32ArrayArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&);
   CORE_EXPORT static void voidMethodInt32ArrayArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&);
   CORE_EXPORT static void voidMethodUint8ArrayArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&);
+  CORE_EXPORT static void voidMethodAllowSharedArrayBufferViewArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&);
+  CORE_EXPORT static void voidMethodAllowSharedUint8ArrayArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&);
   CORE_EXPORT static void longArrayMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&);
   CORE_EXPORT static void stringArrayMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&);
   CORE_EXPORT static void testInterfaceEmptyArrayMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8Uint8ClampedArray.h b/third_party/WebKit/Source/bindings/tests/results/core/V8Uint8ClampedArray.h
index ac8e8e9..1397af3 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8Uint8ClampedArray.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8Uint8ClampedArray.h
@@ -21,9 +21,9 @@
 #include "bindings/core/v8/V8DOMWrapper.h"
 #include "bindings/core/v8/WrapperTypeInfo.h"
 #include "core/CoreExport.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
 #include "core/dom/FlexibleArrayBufferView.h"
-#include "core/dom/NotShared.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/build/scripts/json5_generator.py b/third_party/WebKit/Source/build/scripts/json5_generator.py
index 5b7184b..72a210f 100644
--- a/third_party/WebKit/Source/build/scripts/json5_generator.py
+++ b/third_party/WebKit/Source/build/scripts/json5_generator.py
@@ -162,8 +162,9 @@
                 raise Exception(
                     "Unknown parameter: '%s'\nKnown params: %s" %
                     (key, self.parameters.keys()))
-            if self.parameters[key]:
-                self._validate_parameter(self.parameters[key], value)
+            assert self.parameters[key] is not None, \
+                "Specification for parameter 'key' cannot be None. Use {} instead."
+            self._validate_parameter(self.parameters[key], value)
             entry[key] = value
         return entry
 
diff --git a/third_party/WebKit/Source/build/scripts/make_event_factory.py b/third_party/WebKit/Source/build/scripts/make_event_factory.py
index 5e7e933..3e4201b 100755
--- a/third_party/WebKit/Source/build/scripts/make_event_factory.py
+++ b/third_party/WebKit/Source/build/scripts/make_event_factory.py
@@ -101,8 +101,8 @@
 
 class EventFactoryWriter(json5_generator.Writer):
     default_parameters = {
-        'ImplementedAs': None,
-        'RuntimeEnabled': None,
+        'ImplementedAs': {},
+        'RuntimeEnabled': {},
     }
     default_metadata = {
         'export': '',
diff --git a/third_party/WebKit/Source/build/scripts/make_names.py b/third_party/WebKit/Source/build/scripts/make_names.py
index cfb1aa5..a7473850 100755
--- a/third_party/WebKit/Source/build/scripts/make_names.py
+++ b/third_party/WebKit/Source/build/scripts/make_names.py
@@ -45,10 +45,10 @@
 
 class MakeNamesWriter(json5_generator.Writer):
     default_parameters = {
-        'Conditional': None,  # FIXME: Add support for Conditional.
-        'ImplementedAs': None,
-        'RuntimeEnabled': None,  # What should we do for runtime-enabled features?
-        'Symbol': None,
+        'Conditional': {},  # FIXME: Add support for Conditional.
+        'ImplementedAs': {},
+        'RuntimeEnabled': {},  # What should we do for runtime-enabled features?
+        'Symbol': {},
     }
     default_metadata = {
         'export': '',
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn
index 4083f83d..12c7181b 100644
--- a/third_party/WebKit/Source/core/css/BUILD.gn
+++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -500,6 +500,8 @@
     "properties/CSSPropertyLengthUtils.h",
     "properties/CSSPropertyMarginUtils.cpp",
     "properties/CSSPropertyMarginUtils.h",
+    "properties/CSSPropertyOffsetPathUtils.cpp",
+    "properties/CSSPropertyOffsetPathUtils.h",
     "properties/CSSPropertyPositionUtils.h",
     "properties/CSSPropertyShapeUtils.cpp",
     "properties/CSSPropertyShapeUtils.h",
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index 5c3cfba..b112f80 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -1507,7 +1507,6 @@
       api_class: "CSSPropertyAPIPadding",
       api_methods: ["parseSingleValue"],
       converter: "ConvertLength",
-      initial: "InitialPadding",
       interpolable: true,
     },
     {
@@ -1515,7 +1514,6 @@
       api_class: "CSSPropertyAPIPadding",
       api_methods: ["parseSingleValue"],
       converter: "ConvertLength",
-      initial: "InitialPadding",
       interpolable: true,
     },
     {
@@ -1523,7 +1521,6 @@
       api_class: "CSSPropertyAPIPadding",
       api_methods: ["parseSingleValue"],
       converter: "ConvertLength",
-      initial: "InitialPadding",
       interpolable: true,
     },
     {
@@ -1531,7 +1528,6 @@
       api_class: "CSSPropertyAPIPadding",
       api_methods: ["parseSingleValue"],
       converter: "ConvertLength",
-      initial: "InitialPadding",
       interpolable: true,
     },
     {
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index 7abefdc..40c5a14 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -20,7 +20,6 @@
 #include "core/css/CSSIdentifierValue.h"
 #include "core/css/CSSInheritedValue.h"
 #include "core/css/CSSInitialValue.h"
-#include "core/css/CSSPathValue.h"
 #include "core/css/CSSPendingSubstitutionValue.h"
 #include "core/css/CSSPrimitiveValueMappings.h"
 #include "core/css/CSSQuadValue.h"
@@ -47,11 +46,11 @@
 #include "core/css/properties/CSSPropertyFontUtils.h"
 #include "core/css/properties/CSSPropertyLengthUtils.h"
 #include "core/css/properties/CSSPropertyMarginUtils.h"
+#include "core/css/properties/CSSPropertyOffsetPathUtils.h"
 #include "core/css/properties/CSSPropertyPositionUtils.h"
 #include "core/css/properties/CSSPropertyShapeUtils.h"
 #include "core/frame/UseCounter.h"
 #include "core/layout/LayoutTheme.h"
-#include "core/svg/SVGPathUtilities.h"
 #include "platform/wtf/text/StringBuilder.h"
 
 namespace blink {
@@ -708,39 +707,6 @@
   return list;
 }
 
-static CSSValue* ConsumePath(CSSParserTokenRange& range) {
-  // FIXME: Add support for <url>, <basic-shape>, <geometry-box>.
-  if (range.Peek().FunctionId() != CSSValuePath)
-    return nullptr;
-
-  CSSParserTokenRange function_range = range;
-  CSSParserTokenRange function_args = ConsumeFunction(function_range);
-
-  if (function_args.Peek().GetType() != kStringToken)
-    return nullptr;
-  String path_string =
-      function_args.ConsumeIncludingWhitespace().Value().ToString();
-
-  std::unique_ptr<SVGPathByteStream> byte_stream = SVGPathByteStream::Create();
-  if (BuildByteStreamFromString(path_string, *byte_stream) !=
-          SVGParseStatus::kNoError ||
-      !function_args.AtEnd())
-    return nullptr;
-
-  range = function_range;
-  if (byte_stream->IsEmpty())
-    return CSSIdentifierValue::Create(CSSValueNone);
-  return CSSPathValue::Create(std::move(byte_stream));
-}
-
-static CSSValue* ConsumePathOrNone(CSSParserTokenRange& range) {
-  CSSValueID id = range.Peek().Id();
-  if (id == CSSValueNone)
-    return ConsumeIdent(range);
-
-  return ConsumePath(range);
-}
-
 static CSSValue* ConsumeOffsetRotate(CSSParserTokenRange& range) {
   CSSValue* angle = ConsumeAngle(range);
   CSSValue* keyword = ConsumeIdent<CSSValueAuto, CSSValueReverse>(range);
@@ -758,25 +724,10 @@
   return list;
 }
 
-static CSSValue* ConsumeOffsetPath(CSSParserTokenRange& range,
-                                   const CSSParserContext* context,
-                                   bool is_motion_path) {
-  CSSValue* value = ConsumePathOrNone(range);
-
-  // Count when we receive a valid path other than 'none'.
-  if (value && !value->IsIdentifierValue()) {
-    if (is_motion_path) {
-      context->Count(UseCounter::kCSSMotionInEffect);
-    } else {
-      context->Count(UseCounter::kCSSOffsetInEffect);
-    }
-  }
-  return value;
-}
-
 // offset: <offset-path> <offset-distance> <offset-rotation>
 bool CSSPropertyParser::ConsumeOffsetShorthand(bool important) {
-  const CSSValue* offset_path = ConsumeOffsetPath(range_, context_, false);
+  const CSSValue* offset_path =
+      CSSPropertyOffsetPathUtils::ConsumeOffsetPath(range_, context_, false);
   const CSSValue* offset_distance =
       ConsumeLengthOrPercent(range_, context_->Mode(), kValueRangeAll);
   const CSSValue* offset_rotation = ConsumeOffsetRotate(range_);
@@ -1948,9 +1899,9 @@
     case CSSPropertyTextDecorationLine:
       return ConsumeTextDecorationLine(range_);
     case CSSPropertyD:
-      return ConsumePathOrNone(range_);
+      return CSSPropertyOffsetPathUtils::ConsumePathOrNone(range_);
     case CSSPropertyOffsetPath:
-      return ConsumeOffsetPath(
+      return CSSPropertyOffsetPathUtils::ConsumeOffsetPath(
           range_, context_, unresolved_property == CSSPropertyAliasMotionPath);
     case CSSPropertyOffsetDistance:
       return ConsumeLengthOrPercent(range_, context_->Mode(), kValueRangeAll);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyOffsetPathUtils.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyOffsetPathUtils.cpp
new file mode 100644
index 0000000..a6a31a68
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyOffsetPathUtils.cpp
@@ -0,0 +1,72 @@
+// 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 "core/css/properties/CSSPropertyOffsetPathUtils.h"
+
+#include "core/css/CSSPathValue.h"
+#include "core/css/parser/CSSParserContext.h"
+#include "core/css/parser/CSSPropertyParserHelpers.h"
+#include "core/svg/SVGPathByteStream.h"
+#include "core/svg/SVGPathUtilities.h"
+
+namespace blink {
+
+namespace {
+
+CSSValue* ConsumePath(CSSParserTokenRange& range) {
+  // FIXME: Add support for <url>, <basic-shape>, <geometry-box>.
+  if (range.Peek().FunctionId() != CSSValuePath)
+    return nullptr;
+
+  CSSParserTokenRange function_range = range;
+  CSSParserTokenRange function_args =
+      CSSPropertyParserHelpers::ConsumeFunction(function_range);
+
+  if (function_args.Peek().GetType() != kStringToken)
+    return nullptr;
+  String path_string =
+      function_args.ConsumeIncludingWhitespace().Value().ToString();
+
+  std::unique_ptr<SVGPathByteStream> byte_stream = SVGPathByteStream::Create();
+  if (BuildByteStreamFromString(path_string, *byte_stream) !=
+          SVGParseStatus::kNoError ||
+      !function_args.AtEnd()) {
+    return nullptr;
+  }
+
+  range = function_range;
+  if (byte_stream->IsEmpty())
+    return CSSIdentifierValue::Create(CSSValueNone);
+  return CSSPathValue::Create(std::move(byte_stream));
+}
+
+}  // namespace
+
+CSSValue* CSSPropertyOffsetPathUtils::ConsumeOffsetPath(
+    CSSParserTokenRange& range,
+    const CSSParserContext* context,
+    bool is_motion_path) {
+  CSSValue* value = ConsumePathOrNone(range);
+
+  // Count when we receive a valid path other than 'none'.
+  if (value && !value->IsIdentifierValue()) {
+    if (is_motion_path) {
+      context->Count(UseCounter::kCSSMotionInEffect);
+    } else {
+      context->Count(UseCounter::kCSSOffsetInEffect);
+    }
+  }
+  return value;
+}
+
+CSSValue* CSSPropertyOffsetPathUtils::ConsumePathOrNone(
+    CSSParserTokenRange& range) {
+  CSSValueID id = range.Peek().Id();
+  if (id == CSSValueNone)
+    return CSSPropertyParserHelpers::ConsumeIdent(range);
+
+  return ConsumePath(range);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyOffsetPathUtils.h b/third_party/WebKit/Source/core/css/properties/CSSPropertyOffsetPathUtils.h
new file mode 100644
index 0000000..dc00e53
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyOffsetPathUtils.h
@@ -0,0 +1,26 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSSPropertyOffsetPathUtils_h
+#define CSSPropertyOffsetPathUtils_h
+
+#include "platform/wtf/Allocator.h"
+
+namespace blink {
+
+class CSSParserContext;
+class CSSParserTokenRange;
+class CSSValue;
+
+class CSSPropertyOffsetPathUtils {
+  STATIC_ONLY(CSSPropertyOffsetPathUtils);
+  static CSSValue* ConsumeOffsetPath(CSSParserTokenRange&,
+                                     const CSSParserContext*,
+                                     bool);
+  static CSSValue* ConsumePathOrNone(CSSParserTokenRange&);
+};
+
+}  // namespace blink
+
+#endif  // CSSPropertyOffsetPathUtils_h
diff --git a/third_party/WebKit/Source/core/dom/ArrayBufferViewHelpers.h b/third_party/WebKit/Source/core/dom/ArrayBufferViewHelpers.h
new file mode 100644
index 0000000..0f3c71f
--- /dev/null
+++ b/third_party/WebKit/Source/core/dom/ArrayBufferViewHelpers.h
@@ -0,0 +1,120 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ArrayBufferViewHelpers_h
+#define ArrayBufferViewHelpers_h
+
+#include <type_traits>
+#include "core/dom/DOMArrayBufferView.h"
+#include "platform/heap/Handle.h"
+#include "platform/wtf/TypeTraits.h"
+
+namespace blink {
+
+// A wrapper template type that is used to ensure that a TypedArray is not
+// backed by a SharedArrayBuffer.
+//
+// Typically this is used as an annotation on C++ functions that are called by
+// the bindings layer, e.g.:
+//
+//   void Foo(NotShared<DOMUint32Array> param) {
+//     DOMUint32Array* array = param.View();
+//     ...
+//   }
+template <typename T>
+class NotShared {
+  static_assert(WTF::IsSubclass<typename std::remove_const<T>::type,
+                                DOMArrayBufferView>::value,
+                "NotShared<T> must have T as subclass of DOMArrayBufferView");
+  STACK_ALLOCATED();
+
+ public:
+  using TypedArrayType = T;
+
+  NotShared() {}
+
+  explicit NotShared(T* typedArray) : typed_array_(typedArray) {
+    DCHECK(!(typedArray && typedArray->View()->IsShared()));
+  }
+  NotShared(const NotShared& other) = default;
+  template <typename U>
+  NotShared(const NotShared<U>& other) : typed_array_(other.View()) {}
+  template <typename U>
+  NotShared(const Member<U>& other) {
+    DCHECK(!other->View()->IsShared());
+    typed_array_ = other.Get();
+  }
+
+  NotShared& operator=(const NotShared& other) = default;
+  template <typename U>
+  NotShared& operator=(const NotShared<U>& other) {
+    typed_array_ = other.View();
+    return *this;
+  }
+
+  T* View() const { return typed_array_.Get(); }
+
+  bool operator!() const { return !typed_array_; }
+  explicit operator bool() const { return !!typed_array_; }
+
+ private:
+  // Must use an untraced member here since this object may be constructed on a
+  // thread without a ThreadState (e.g. an Audio worklet). It is safe in that
+  // case because the pointed-to ArrayBuffer is being kept alive another way
+  // (e.g. CrossThreadPersistent).
+  //
+  // TODO(binji): update to using Member, see crbug.com/710295.
+  UntracedMember<T> typed_array_;
+};
+
+// A wrapper template type that specifies that a TypedArray may be backed by a
+// SharedArrayBuffer.
+//
+// Typically this is used as an annotation on C++ functions that are called by
+// the bindings layer, e.g.:
+//
+//   void Foo(MaybeShared<DOMUint32Array> param) {
+//     DOMUint32Array* array = param.View();
+//     ...
+//   }
+template <typename T>
+class MaybeShared {
+  static_assert(WTF::IsSubclass<typename std::remove_const<T>::type,
+                                DOMArrayBufferView>::value,
+                "MaybeShared<T> must have T as subclass of DOMArrayBufferView");
+  STACK_ALLOCATED();
+
+ public:
+  using TypedArrayType = T;
+
+  MaybeShared() {}
+
+  explicit MaybeShared(T* typedArray) : typed_array_(typedArray) {}
+  MaybeShared(const MaybeShared& other) = default;
+  template <typename U>
+  MaybeShared(const MaybeShared<U>& other) : typed_array_(other.View()) {}
+  template <typename U>
+  MaybeShared(const Member<U>& other) {
+    typed_array_ = other.Get();
+  }
+
+  MaybeShared& operator=(const MaybeShared& other) = default;
+  template <typename U>
+  MaybeShared& operator=(const MaybeShared<U>& other) {
+    typed_array_ = other.View();
+    return *this;
+  }
+
+  T* View() const { return typed_array_.Get(); }
+
+  bool operator!() const { return !typed_array_; }
+  explicit operator bool() const { return !!typed_array_; }
+
+ private:
+  Member<T> typed_array_;
+};
+
+}  // namespace blink
+
+#endif  // ArrayBufferViewHelpers_h
diff --git a/third_party/WebKit/Source/core/dom/DOMArrayBufferView.h b/third_party/WebKit/Source/core/dom/DOMArrayBufferView.h
index bd95bfd..fe318409 100644
--- a/third_party/WebKit/Source/core/dom/DOMArrayBufferView.h
+++ b/third_party/WebKit/Source/core/dom/DOMArrayBufferView.h
@@ -69,6 +69,10 @@
   void SetNeuterable(bool flag) { return View()->SetNeuterable(flag); }
   bool IsShared() const { return View()->IsShared(); }
 
+  void* BaseAddressMaybeShared() const {
+    return View()->BaseAddressMaybeShared();
+  }
+
   v8::Local<v8::Object> Wrap(v8::Isolate*,
                              v8::Local<v8::Object> creation_context) override {
     NOTREACHED();
diff --git a/third_party/WebKit/Source/core/dom/DOMTypedArray.h b/third_party/WebKit/Source/core/dom/DOMTypedArray.h
index eaa24d0..cc90fcd 100644
--- a/third_party/WebKit/Source/core/dom/DOMTypedArray.h
+++ b/third_party/WebKit/Source/core/dom/DOMTypedArray.h
@@ -68,6 +68,7 @@
   }
 
   ValueType* Data() const { return View()->Data(); }
+  ValueType* DataMaybeShared() const { return View()->DataMaybeShared(); }
   unsigned length() const { return View()->length(); }
   // Invoked by the indexed getter. Does not perform range checks; caller
   // is responsible for doing so and returning undefined as necessary.
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 019d228..132479ac3 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -3408,6 +3408,12 @@
   }
 }
 
+const KURL& Document::BaseURL() const {
+  if (!base_url_.IsNull())
+    return base_url_;
+  return BlankURL();
+}
+
 void Document::SetBaseURLOverride(const KURL& url) {
   base_url_override_ = url;
   UpdateBaseURL();
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 7ca96b5..94ddb81 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -609,7 +609,7 @@
 
   // To understand how these concepts relate to one another, please see the
   // comments surrounding their declaration.
-  const KURL& BaseURL() const { return base_url_; }
+  const KURL& BaseURL() const;
   void SetBaseURLOverride(const KURL&);
   const KURL& BaseURLOverride() const { return base_url_override_; }
   KURL ValidBaseElementURL() const;
diff --git a/third_party/WebKit/Source/core/dom/MockScriptElementBase.h b/third_party/WebKit/Source/core/dom/MockScriptElementBase.h
index f468804..3312913b 100644
--- a/third_party/WebKit/Source/core/dom/MockScriptElementBase.h
+++ b/third_party/WebKit/Source/core/dom/MockScriptElementBase.h
@@ -29,6 +29,7 @@
   MOCK_CONST_METHOD0(ForAttributeValue, String());
   MOCK_CONST_METHOD0(IntegrityAttributeValue, String());
   MOCK_CONST_METHOD0(LanguageAttributeValue, String());
+  MOCK_CONST_METHOD0(NomoduleAttributeValue, bool());
   MOCK_CONST_METHOD0(SourceAttributeValue, String());
   MOCK_CONST_METHOD0(TypeAttributeValue, String());
 
diff --git a/third_party/WebKit/Source/core/dom/ModulatorImpl.cpp b/third_party/WebKit/Source/core/dom/ModulatorImpl.cpp
index dbf2f24..b41d3a40 100644
--- a/third_party/WebKit/Source/core/dom/ModulatorImpl.cpp
+++ b/third_party/WebKit/Source/core/dom/ModulatorImpl.cpp
@@ -13,6 +13,7 @@
 #include "core/frame/LocalFrame.h"
 #include "core/loader/modulescript/ModuleScriptFetchRequest.h"
 #include "core/loader/modulescript/ModuleScriptLoaderRegistry.h"
+#include "core/loader/modulescript/ModuleTreeLinkerRegistry.h"
 #include "platform/loader/fetch/ResourceFetcher.h"
 
 namespace blink {
@@ -33,6 +34,7 @@
       fetcher_(fetcher),
       map_(this, ModuleMap::Create(this)),
       loader_registry_(ModuleScriptLoaderRegistry::Create()),
+      tree_linker_registry_(ModuleTreeLinkerRegistry::Create()),
       script_module_resolver_(ScriptModuleResolverImpl::Create(this)) {
   DCHECK(script_state_);
   DCHECK(task_runner_);
@@ -75,7 +77,7 @@
                                       const AncestorList& ancestor_list,
                                       ModuleGraphLevel level,
                                       ModuleTreeClient* client) {
-  NOTIMPLEMENTED();
+  tree_linker_registry_->Fetch(request, ancestor_list, level, this, client);
 }
 
 void ModulatorImpl::FetchSingle(const ModuleScriptFetchRequest& request,
@@ -141,6 +143,7 @@
   visitor->Trace(fetcher_);
   visitor->Trace(map_);
   visitor->Trace(loader_registry_);
+  visitor->Trace(tree_linker_registry_);
   visitor->Trace(script_module_resolver_);
 }
 
diff --git a/third_party/WebKit/Source/core/dom/ModulatorImpl.h b/third_party/WebKit/Source/core/dom/ModulatorImpl.h
index 711d4d7d..dd1b8db 100644
--- a/third_party/WebKit/Source/core/dom/ModulatorImpl.h
+++ b/third_party/WebKit/Source/core/dom/ModulatorImpl.h
@@ -18,6 +18,7 @@
 class ExecutionContext;
 class ModuleMap;
 class ModuleScriptLoaderRegistry;
+class ModuleTreeLinkerRegistry;
 class ResourceFetcher;
 class ScriptState;
 class WebTaskRunner;
@@ -71,6 +72,7 @@
   Member<ResourceFetcher> fetcher_;
   TraceWrapperMember<ModuleMap> map_;
   Member<ModuleScriptLoaderRegistry> loader_registry_;
+  Member<ModuleTreeLinkerRegistry> tree_linker_registry_;
   Member<ScriptModuleResolver> script_module_resolver_;
 };
 
diff --git a/third_party/WebKit/Source/core/dom/Node.idl b/third_party/WebKit/Source/core/dom/Node.idl
index d7e456ae..2c6837d9 100644
--- a/third_party/WebKit/Source/core/dom/Node.idl
+++ b/third_party/WebKit/Source/core/dom/Node.idl
@@ -38,7 +38,7 @@
     [ImplementedAs=getNodeType] readonly attribute unsigned short nodeType;
     readonly attribute DOMString nodeName;
 
-    readonly attribute DOMString? baseURI;
+    readonly attribute USVString baseURI;
 
     [Measure] readonly attribute boolean isConnected;
     [PerWorldBindings] readonly attribute Document? ownerDocument;
diff --git a/third_party/WebKit/Source/core/dom/NotShared.h b/third_party/WebKit/Source/core/dom/NotShared.h
deleted file mode 100644
index 69173aa..0000000
--- a/third_party/WebKit/Source/core/dom/NotShared.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NotShared_h
-#define NotShared_h
-
-// A wrapper template type that is used to ensure that a TypedArray is not
-// backed by a SharedArrayBuffer.
-//
-// Typically this is used as an annotation on C++ functions that are called by
-// the bindings layer, e.g.:
-//
-//   void Foo(NotShared<DOMUint32Array> param) {
-//     DOMUint32Array* array = param.View();
-//     ...
-//   }
-
-#include "platform/heap/Handle.h"
-
-namespace blink {
-
-template <typename T>
-class NotShared {
-  STACK_ALLOCATED();
-
- public:
-  using TypedArrayType = T;
-
-  NotShared() {}
-
-  explicit NotShared(T* typedArray) : typed_array_(typedArray) {
-    DCHECK(!(typedArray && typedArray->View()->IsShared()));
-  }
-  NotShared(const NotShared& other) = default;
-  template <typename U>
-  NotShared(const NotShared<U>& other) : typed_array_(other.View()) {}
-  template <typename U>
-  NotShared(const Member<U>& other) {
-    DCHECK(!other->View()->IsShared());
-    typed_array_ = other.Get();
-  }
-
-  NotShared& operator=(const NotShared& other) = default;
-  template <typename U>
-  NotShared& operator=(const NotShared<U>& other) {
-    typed_array_ = other.View();
-    return *this;
-  }
-
-  T* View() const { return typed_array_.Get(); }
-
-  bool operator!() const { return !typed_array_; }
-  explicit operator bool() const { return !!typed_array_; }
-
- private:
-  // Must use an untraced member here since this object may be constructed on a
-  // thread without a ThreadState (e.g. an Audio worklet). It is safe in that
-  // case because the pointed-to ArrayBuffer is being kept alive another way
-  // (e.g. CrossThreadPersistent).
-  //
-  // TODO(binji): update to using Member, see crbug.com/710295.
-  UntracedMember<T> typed_array_;
-};
-
-}  // namespace blink
-
-#endif  // NotShared_h
diff --git a/third_party/WebKit/Source/core/dom/ScriptElementBase.h b/third_party/WebKit/Source/core/dom/ScriptElementBase.h
index 8c8f107e..3c131c1 100644
--- a/third_party/WebKit/Source/core/dom/ScriptElementBase.h
+++ b/third_party/WebKit/Source/core/dom/ScriptElementBase.h
@@ -51,6 +51,7 @@
   virtual String ForAttributeValue() const = 0;
   virtual String IntegrityAttributeValue() const = 0;
   virtual String LanguageAttributeValue() const = 0;
+  virtual bool NomoduleAttributeValue() const = 0;
   virtual String SourceAttributeValue() const = 0;
   virtual String TypeAttributeValue() const = 0;
 
diff --git a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
index 35e2953..6fb2ab93 100644
--- a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
@@ -215,6 +215,11 @@
   return false;
 }
 
+bool ScriptLoader::BlockForNoModule(ScriptType script_type, bool nomodule) {
+  return nomodule && script_type == ScriptType::kClassic &&
+         RuntimeEnabledFeatures::moduleScriptsEnabled();
+}
+
 bool ScriptLoader::IsScriptTypeSupported(LegacyTypeSupport support_legacy_types,
                                          ScriptType& out_script_type) const {
   return IsValidScriptTypeAndLanguage(element_->TypeAttributeValue(),
@@ -296,7 +301,8 @@
   // 11. "If the script element has a nomodule content attribute
   //      and the script's type is "classic", then abort these steps.
   //      The script is not executed."
-  // TODO(japhet): Implement this step.
+  if (BlockForNoModule(script_type_, element_->NomoduleAttributeValue()))
+    return false;
 
   // 13.
   if (!IsScriptForEventSupported())
diff --git a/third_party/WebKit/Source/core/dom/ScriptLoader.h b/third_party/WebKit/Source/core/dom/ScriptLoader.h
index ec3032b..1188afd7 100644
--- a/third_party/WebKit/Source/core/dom/ScriptLoader.h
+++ b/third_party/WebKit/Source/core/dom/ScriptLoader.h
@@ -65,6 +65,8 @@
       LegacyTypeSupport support_legacy_types,
       ScriptType& out_script_type);
 
+  static bool BlockForNoModule(ScriptType, bool nomodule);
+
   // https://html.spec.whatwg.org/#prepare-a-script
   bool PrepareScript(const TextPosition& script_start_position =
                          TextPosition::MinimumPosition(),
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index dff0acd..fe63bf4 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -105,8 +105,8 @@
 #include "core/svg/SVGDocumentExtensions.h"
 #include "core/svg/SVGSVGElement.h"
 #include "platform/Histogram.h"
-#include "platform/HostWindow.h"
 #include "platform/Language.h"
+#include "platform/PlatformChromeClient.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/ScriptForbiddenScope.h"
 #include "platform/WebFrameScheduler.h"
@@ -398,7 +398,7 @@
   // Document::detachLayoutTree() is forbidden
   // now, so it's not clear if these edge cases can still happen.
   // However, for Oilpan, we still need to remove the native scrollbars before
-  // we lose the connection to the HostWindow, so we just unconditionally
+  // we lose the connection to the ChromeClient, so we just unconditionally
   // detach any scrollbars now.
   scrollbar_manager_.Dispose();
 
@@ -2125,7 +2125,7 @@
   }
 }
 
-HostWindow* FrameView::GetHostWindow() const {
+PlatformChromeClient* FrameView::GetChromeClient() const {
   Page* page = GetFrame().GetPage();
   if (!page)
     return nullptr;
@@ -2748,8 +2748,8 @@
 }
 
 bool FrameView::ScheduleAnimation() {
-  if (HostWindow* window = GetHostWindow()) {
-    window->ScheduleAnimation(frame_);
+  if (PlatformChromeClient* client = GetChromeClient()) {
+    client->ScheduleAnimation(frame_);
     return true;
   }
   return false;
@@ -4383,8 +4383,8 @@
 }
 
 void FrameView::ScrollContents(const IntSize& scroll_delta) {
-  HostWindow* window = GetHostWindow();
-  if (!window)
+  PlatformChromeClient* client = GetChromeClient();
+  if (!client)
     return;
 
   TRACE_EVENT0("blink", "FrameView::scrollContents");
@@ -4486,10 +4486,10 @@
 }
 
 IntRect FrameView::ContentsToScreen(const IntRect& rect) const {
-  HostWindow* window = GetHostWindow();
-  if (!window)
+  PlatformChromeClient* client = GetChromeClient();
+  if (!client)
     return IntRect();
-  return window->ViewportToScreen(ContentsToViewport(rect), this);
+  return client->ViewportToScreen(ContentsToViewport(rect), this);
 }
 
 IntPoint FrameView::SoonToBeRemovedUnscaledViewportToContents(
@@ -5353,7 +5353,7 @@
 }
 
 LayoutUnit FrameView::CaretWidth() const {
-  return LayoutUnit(GetHostWindow()->WindowToViewportScalar(1));
+  return LayoutUnit(GetChromeClient()->WindowToViewportScalar(1));
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h
index 613d917..d054ea66 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.h
+++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -467,7 +467,7 @@
 
   // The window that hosts the FrameView. The FrameView will communicate scrolls
   // and repaints to the host window in the window's coordinate space.
-  HostWindow* GetHostWindow() const;
+  PlatformChromeClient* GetChromeClient() const;
 
   typedef HeapHashSet<Member<FrameViewBase>> ChildrenSet;
   typedef HeapHashSet<Member<PluginView>> PluginsSet;
diff --git a/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp b/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp
index 236f764..ee56bd1 100644
--- a/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp
+++ b/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp
@@ -427,8 +427,8 @@
   return LayoutViewport().ScrollAnimatorEnabled();
 }
 
-HostWindow* RootFrameViewport::GetHostWindow() const {
-  return LayoutViewport().GetHostWindow();
+PlatformChromeClient* RootFrameViewport::GetChromeClient() const {
+  return LayoutViewport().GetChromeClient();
 }
 
 void RootFrameViewport::ServiceScrollAnimations(double monotonic_time) {
diff --git a/third_party/WebKit/Source/core/frame/RootFrameViewport.h b/third_party/WebKit/Source/core/frame/RootFrameViewport.h
index f2b69039..ccd1761e 100644
--- a/third_party/WebKit/Source/core/frame/RootFrameViewport.h
+++ b/third_party/WebKit/Source/core/frame/RootFrameViewport.h
@@ -93,7 +93,7 @@
           kIgnorePlatformOverlayScrollbarSize) const override;
   ScrollResult UserScroll(ScrollGranularity, const FloatSize&) override;
   bool ScrollAnimatorEnabled() const override;
-  HostWindow* GetHostWindow() const override;
+  PlatformChromeClient* GetChromeClient() const override;
   void ServiceScrollAnimations(double) override;
   void UpdateCompositorScrollAnimations() override;
   void CancelProgrammaticScrollAnimation() override;
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.cpp b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
index cc225129..fd74773 100644
--- a/third_party/WebKit/Source/core/frame/VisualViewport.cpp
+++ b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
@@ -494,7 +494,7 @@
   return GetPage().GetSettings().GetScrollAnimatorEnabled();
 }
 
-HostWindow* VisualViewport::GetHostWindow() const {
+PlatformChromeClient* VisualViewport::GetChromeClient() const {
   return &GetPage().GetChromeClient();
 }
 
@@ -675,8 +675,8 @@
 }
 
 bool VisualViewport::ScheduleAnimation() {
-  if (HostWindow* window = GetHostWindow()) {
-    window->ScheduleAnimation(MainFrame());
+  if (PlatformChromeClient* client = GetChromeClient()) {
+    client->ScheduleAnimation(MainFrame());
     return true;
   }
   return false;
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.h b/third_party/WebKit/Source/core/frame/VisualViewport.h
index 25531fb..e633fa2 100644
--- a/third_party/WebKit/Source/core/frame/VisualViewport.h
+++ b/third_party/WebKit/Source/core/frame/VisualViewport.h
@@ -181,7 +181,7 @@
   IntPoint RootFrameToViewport(const IntPoint&) const;
 
   // ScrollableArea implementation
-  HostWindow* GetHostWindow() const override;
+  PlatformChromeClient* GetChromeClient() const override;
   bool ShouldUseIntegerScrollOffset() const override;
   void SetScrollOffset(const ScrollOffset&,
                        ScrollType,
diff --git a/third_party/WebKit/Source/core/geometry/DOMMatrix.h b/third_party/WebKit/Source/core/geometry/DOMMatrix.h
index eede89ef..c80fbf7 100644
--- a/third_party/WebKit/Source/core/geometry/DOMMatrix.h
+++ b/third_party/WebKit/Source/core/geometry/DOMMatrix.h
@@ -6,7 +6,7 @@
 #define DOMMatrix_h
 
 #include "bindings/core/v8/ExceptionState.h"
-#include "core/dom/NotShared.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/geometry/DOMMatrixInit.h"
 #include "core/geometry/DOMMatrixReadOnly.h"
 
diff --git a/third_party/WebKit/Source/core/geometry/DOMMatrixReadOnly.h b/third_party/WebKit/Source/core/geometry/DOMMatrixReadOnly.h
index 708a07e..55627b7 100644
--- a/third_party/WebKit/Source/core/geometry/DOMMatrixReadOnly.h
+++ b/third_party/WebKit/Source/core/geometry/DOMMatrixReadOnly.h
@@ -8,8 +8,8 @@
 #include <memory>
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/ScriptWrappable.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "platform/heap/Handle.h"
 #include "platform/transforms/TransformationMatrix.h"
 
diff --git a/third_party/WebKit/Source/core/html/HTMLAttributeNames.json5 b/third_party/WebKit/Source/core/html/HTMLAttributeNames.json5
index c09bc0b4..4fccbc9 100644
--- a/third_party/WebKit/Source/core/html/HTMLAttributeNames.json5
+++ b/third_party/WebKit/Source/core/html/HTMLAttributeNames.json5
@@ -176,6 +176,7 @@
     "muted",
     "name",
     "nohref",
+    "nomodule",
     "nonce",
     "noresize",
     "noshade",
diff --git a/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp b/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp
index ce37590..3d79462 100644
--- a/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp
@@ -152,6 +152,10 @@
   return getAttribute(languageAttr).GetString();
 }
 
+bool HTMLScriptElement::NomoduleAttributeValue() const {
+  return FastHasAttribute(nomoduleAttr);
+}
+
 String HTMLScriptElement::ForAttributeValue() const {
   return getAttribute(forAttr).GetString();
 }
diff --git a/third_party/WebKit/Source/core/html/HTMLScriptElement.h b/third_party/WebKit/Source/core/html/HTMLScriptElement.h
index 9475dfad..b3a17fa 100644
--- a/third_party/WebKit/Source/core/html/HTMLScriptElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLScriptElement.h
@@ -79,6 +79,7 @@
   String CharsetAttributeValue() const override;
   String TypeAttributeValue() const override;
   String LanguageAttributeValue() const override;
+  bool NomoduleAttributeValue() const override;
   String ForAttributeValue() const override;
   String EventAttributeValue() const override;
   String CrossOriginAttributeValue() const override;
diff --git a/third_party/WebKit/Source/core/html/HTMLScriptElement.idl b/third_party/WebKit/Source/core/html/HTMLScriptElement.idl
index 20fa012..795f2231 100644
--- a/third_party/WebKit/Source/core/html/HTMLScriptElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLScriptElement.idl
@@ -22,6 +22,7 @@
 interface HTMLScriptElement : HTMLElement {
     [CEReactions, Reflect, URL] attribute DOMString src;
     [CEReactions, Reflect] attribute DOMString type;
+    [CEReactions, Reflect, RuntimeEnabled=ModuleScripts] attribute boolean noModule;
     [CEReactions, Reflect] attribute DOMString charset;
     [CEReactions] attribute boolean async;
     [CEReactions, Reflect] attribute boolean defer;
diff --git a/third_party/WebKit/Source/core/html/ImageData.h b/third_party/WebKit/Source/core/html/ImageData.h
index b4d4f75..be0b419ef 100644
--- a/third_party/WebKit/Source/core/html/ImageData.h
+++ b/third_party/WebKit/Source/core/html/ImageData.h
@@ -32,8 +32,8 @@
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "bindings/core/v8/Uint8ClampedArrayOrUint16ArrayOrFloat32Array.h"
 #include "core/CoreExport.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "core/html/ImageDataColorSettings.h"
 #include "core/html/canvas/CanvasRenderingContext.h"
 #include "core/imagebitmap/ImageBitmapSource.h"
diff --git a/third_party/WebKit/Source/core/html/ImageDocument.cpp b/third_party/WebKit/Source/core/html/ImageDocument.cpp
index 742b68e..f9a12ad 100644
--- a/third_party/WebKit/Source/core/html/ImageDocument.cpp
+++ b/third_party/WebKit/Source/core/html/ImageDocument.cpp
@@ -50,7 +50,7 @@
 #include "core/loader/FrameLoader.h"
 #include "core/loader/resource/ImageResource.h"
 #include "core/page/Page.h"
-#include "platform/HostWindow.h"
+#include "platform/PlatformChromeClient.h"
 #include "platform/wtf/text/StringBuilder.h"
 
 namespace {
@@ -313,7 +313,7 @@
   // We want to pretend the viewport is larger when the user has zoomed the
   // page in (but not when the zoom is coming from device scale).
   const float manual_zoom =
-      zoom / view->GetHostWindow()->WindowToViewportScalar(1.f);
+      zoom / view->GetChromeClient()->WindowToViewportScalar(1.f);
   float width_scale =
       view->Width() * manual_zoom / image_size.Width().ToFloat();
   float height_scale =
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
index ac9f576..afbd3748 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
@@ -144,6 +144,7 @@
         link_is_import_(false),
         matched_(true),
         input_is_image_(false),
+        nomodule_attribute_value_(false),
         source_size_(0),
         source_size_set_(false),
         defer_(FetchParameters::kNoDefer),
@@ -289,6 +290,8 @@
       type_attribute_value_ = attribute_value;
     else if (Match(attribute_name, languageAttr))
       language_attribute_value_ = attribute_value;
+    else if (Match(attribute_name, nomoduleAttr))
+      nomodule_attribute_value_ = true;
   }
 
   template <typename NameType>
@@ -521,12 +524,17 @@
       return ShouldPreloadLink(type);
     if (Match(tag_impl_, inputTag) && !input_is_image_)
       return false;
-    ScriptType script_type = ScriptType::kClassic;
-    if (Match(tag_impl_, scriptTag) &&
-        !ScriptLoader::IsValidScriptTypeAndLanguage(
-            type_attribute_value_, language_attribute_value_,
-            ScriptLoader::kAllowLegacyTypeInTypeAttribute, script_type)) {
-      return false;
+    if (Match(tag_impl_, scriptTag)) {
+      ScriptType script_type = ScriptType::kClassic;
+      if (!ScriptLoader::IsValidScriptTypeAndLanguage(
+              type_attribute_value_, language_attribute_value_,
+              ScriptLoader::kAllowLegacyTypeInTypeAttribute, script_type)) {
+        return false;
+      }
+      if (ScriptLoader::BlockForNoModule(script_type,
+                                         nomodule_attribute_value_)) {
+        return false;
+      }
     }
     return true;
   }
@@ -556,6 +564,7 @@
   String as_attribute_value_;
   String type_attribute_value_;
   String language_attribute_value_;
+  bool nomodule_attribute_value_;
   float source_size_;
   bool source_size_set_;
   FetchParameters::DeferOption defer_;
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index 1add0ab..bce0f9f 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -1851,7 +1851,7 @@
   IntPoint location_in_viewport =
       visual_viewport.RootFrameToViewport(location_in_root_frame);
   IntPoint global_position =
-      view->GetHostWindow()
+      view->GetChromeClient()
           ->ViewportToScreen(IntRect(location_in_viewport, IntSize()),
                              frame_->View())
           .Location();
diff --git a/third_party/WebKit/Source/core/inspector/BUILD.gn b/third_party/WebKit/Source/core/inspector/BUILD.gn
index 417c1c2..66150a0 100644
--- a/third_party/WebKit/Source/core/inspector/BUILD.gn
+++ b/third_party/WebKit/Source/core/inspector/BUILD.gn
@@ -148,12 +148,12 @@
     "inspector/protocol/Memory.h",
     "inspector/protocol/Network.cpp",
     "inspector/protocol/Network.h",
+    "inspector/protocol/Overlay.cpp",
+    "inspector/protocol/Overlay.h",
     "inspector/protocol/Page.cpp",
     "inspector/protocol/Page.h",
     "inspector/protocol/Protocol.cpp",
     "inspector/protocol/Protocol.h",
-    "inspector/protocol/Rendering.cpp",
-    "inspector/protocol/Rendering.h",
     "inspector/protocol/Runtime.h",
     "inspector/protocol/Security.cpp",
     "inspector/protocol/Security.h",
diff --git a/third_party/WebKit/Source/core/inspector/DevToolsHost.cpp b/third_party/WebKit/Source/core/inspector/DevToolsHost.cpp
index 541f0969..7e7b0c39 100644
--- a/third_party/WebKit/Source/core/inspector/DevToolsHost.cpp
+++ b/third_party/WebKit/Source/core/inspector/DevToolsHost.cpp
@@ -49,7 +49,7 @@
 #include "core/page/Page.h"
 #include "platform/ContextMenu.h"
 #include "platform/ContextMenuItem.h"
-#include "platform/HostWindow.h"
+#include "platform/PlatformChromeClient.h"
 #include "platform/ScriptForbiddenScope.h"
 #include "platform/SharedBuffer.h"
 #include "platform/UserGestureIndicator.h"
@@ -159,8 +159,9 @@
   float zoom_factor = frontend_frame_->PageZoomFactor();
   // Cancel the device scale factor applied to the zoom factor in
   // use-zoom-for-dsf mode.
-  const HostWindow* host_window = frontend_frame_->View()->GetHostWindow();
-  float window_to_viewport_ratio = host_window->WindowToViewportScalar(1.0f);
+  const PlatformChromeClient* client =
+      frontend_frame_->View()->GetChromeClient();
+  float window_to_viewport_ratio = client->WindowToViewportScalar(1.0f);
   return zoom_factor / window_to_viewport_ratio;
 }
 
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
index a9a2e62..9a66426 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
@@ -77,6 +77,7 @@
 #include "core/page/Page.h"
 #include "core/xml/DocumentXPathEvaluator.h"
 #include "core/xml/XPathResult.h"
+#include "platform/graphics/Color.h"
 #include "platform/wtf/ListHashSet.h"
 #include "platform/wtf/PtrUtil.h"
 #include "platform/wtf/text/CString.h"
@@ -97,38 +98,6 @@
 const size_t kMaxTextSize = 10000;
 const UChar kEllipsisUChar[] = {0x2026, 0};
 
-Color ParseColor(protocol::DOM::RGBA* rgba) {
-  if (!rgba)
-    return Color::kTransparent;
-
-  int r = rgba->getR();
-  int g = rgba->getG();
-  int b = rgba->getB();
-  if (!rgba->hasA())
-    return Color(r, g, b);
-
-  double a = rgba->getA(1);
-  // Clamp alpha to the [0..1] range.
-  if (a < 0)
-    a = 0;
-  else if (a > 1)
-    a = 1;
-
-  return Color(r, g, b, static_cast<int>(a * 255));
-}
-
-bool ParseQuad(std::unique_ptr<protocol::Array<double>> quad_array,
-               FloatQuad* quad) {
-  const size_t kCoordinatesInQuad = 8;
-  if (!quad_array || quad_array->length() != kCoordinatesInQuad)
-    return false;
-  quad->SetP1(FloatPoint(quad_array->get(0), quad_array->get(1)));
-  quad->SetP2(FloatPoint(quad_array->get(2), quad_array->get(3)));
-  quad->SetP3(FloatPoint(quad_array->get(4), quad_array->get(5)));
-  quad->SetP4(FloatPoint(quad_array->get(6), quad_array->get(7)));
-  return true;
-}
-
 }  // namespace
 
 class InspectorRevalidateDOMTask final
@@ -234,20 +203,38 @@
   }
 }
 
+// static
+Color InspectorDOMAgent::ParseColor(protocol::DOM::RGBA* rgba) {
+  if (!rgba)
+    return Color::kTransparent;
+
+  int r = rgba->getR();
+  int g = rgba->getG();
+  int b = rgba->getB();
+  if (!rgba->hasA())
+    return Color(r, g, b);
+
+  double a = rgba->getA(1);
+  // Clamp alpha to the [0..1] range.
+  if (a < 0)
+    a = 0;
+  else if (a > 1)
+    a = 1;
+
+  return Color(r, g, b, static_cast<int>(a * 255));
+}
+
 InspectorDOMAgent::InspectorDOMAgent(
     v8::Isolate* isolate,
     InspectedFrames* inspected_frames,
-    v8_inspector::V8InspectorSession* v8_session,
-    Client* client)
+    v8_inspector::V8InspectorSession* v8_session)
     : isolate_(isolate),
       inspected_frames_(inspected_frames),
       v8_session_(v8_session),
-      client_(client),
       dom_listener_(nullptr),
       document_node_to_id_map_(new NodeToIdMap()),
       last_node_id_(1),
-      suppress_attribute_modified_event_(false),
-      backend_node_id_to_inspect_(0) {}
+      suppress_attribute_modified_event_(false) {}
 
 InspectorDOMAgent::~InspectorDOMAgent() {}
 
@@ -438,9 +425,6 @@
   dom_editor_ = new DOMEditor(history_.Get());
   document_ = inspected_frames_->Root()->GetDocument();
   instrumenting_agents_->addInspectorDOMAgent(this);
-  if (backend_node_id_to_inspect_)
-    GetFrontend()->inspectNodeRequested(backend_node_id_to_inspect_);
-  backend_node_id_to_inspect_ = 0;
 }
 
 Response InspectorDOMAgent::enable() {
@@ -457,7 +441,6 @@
   if (!Enabled())
     return Response::Error("DOM agent hasn't been enabled");
   state_->setBoolean(DOMAgentState::kDomAgentEnabled, false);
-  SetSearchingForNode(kNotSearching, Maybe<protocol::DOM::HighlightConfig>());
   instrumenting_agents_->removeInspectorDOMAgent(this);
   history_.Clear();
   dom_editor_.Clear();
@@ -1124,155 +1107,8 @@
   return Response::OK();
 }
 
-void InspectorDOMAgent::Inspect(Node* inspected_node) {
-  if (!inspected_node)
-    return;
-
-  Node* node = inspected_node;
-  while (node && !node->IsElementNode() && !node->IsDocumentNode() &&
-         !node->IsDocumentFragment())
-    node = node->ParentOrShadowHostNode();
-  if (!node)
-    return;
-
-  int backend_node_id = DOMNodeIds::IdForNode(node);
-  if (!GetFrontend() || !Enabled()) {
-    backend_node_id_to_inspect_ = backend_node_id;
-    return;
-  }
-
-  GetFrontend()->inspectNodeRequested(backend_node_id);
-}
-
-void InspectorDOMAgent::NodeHighlightedInOverlay(Node* node) {
-  if (!GetFrontend() || !Enabled())
-    return;
-
-  while (node && !node->IsElementNode() && !node->IsDocumentNode() &&
-         !node->IsDocumentFragment())
-    node = node->ParentOrShadowHostNode();
-
-  if (!node)
-    return;
-
-  int node_id = PushNodePathToFrontend(node);
-  GetFrontend()->nodeHighlightRequested(node_id);
-}
-
-Response InspectorDOMAgent::SetSearchingForNode(
-    SearchMode search_mode,
-    Maybe<protocol::DOM::HighlightConfig> highlight_inspector_object) {
-  if (!client_)
-    return Response::OK();
-  if (search_mode == kNotSearching) {
-    client_->SetInspectMode(kNotSearching, nullptr);
-    return Response::OK();
-  }
-  std::unique_ptr<InspectorHighlightConfig> config;
-  Response response = HighlightConfigFromInspectorObject(
-      std::move(highlight_inspector_object), &config);
-  if (!response.isSuccess())
-    return response;
-  client_->SetInspectMode(search_mode, std::move(config));
-  return Response::OK();
-}
-
-Response InspectorDOMAgent::HighlightConfigFromInspectorObject(
-    Maybe<protocol::DOM::HighlightConfig> highlight_inspector_object,
-    std::unique_ptr<InspectorHighlightConfig>* out_config) {
-  if (!highlight_inspector_object.isJust()) {
-    return Response::Error(
-        "Internal error: highlight configuration parameter is missing");
-  }
-
-  protocol::DOM::HighlightConfig* config =
-      highlight_inspector_object.fromJust();
-  std::unique_ptr<InspectorHighlightConfig> highlight_config =
-      WTF::MakeUnique<InspectorHighlightConfig>();
-  highlight_config->show_info = config->getShowInfo(false);
-  highlight_config->show_rulers = config->getShowRulers(false);
-  highlight_config->show_extension_lines = config->getShowExtensionLines(false);
-  highlight_config->display_as_material = config->getDisplayAsMaterial(false);
-  highlight_config->content = ParseColor(config->getContentColor(nullptr));
-  highlight_config->padding = ParseColor(config->getPaddingColor(nullptr));
-  highlight_config->border = ParseColor(config->getBorderColor(nullptr));
-  highlight_config->margin = ParseColor(config->getMarginColor(nullptr));
-  highlight_config->event_target =
-      ParseColor(config->getEventTargetColor(nullptr));
-  highlight_config->shape = ParseColor(config->getShapeColor(nullptr));
-  highlight_config->shape_margin =
-      ParseColor(config->getShapeMarginColor(nullptr));
-  highlight_config->selector_list = config->getSelectorList("");
-
-  *out_config = std::move(highlight_config);
-  return Response::OK();
-}
-
-Response InspectorDOMAgent::setInspectMode(
-    const String& mode,
-    Maybe<protocol::DOM::HighlightConfig> highlight_config) {
-  SearchMode search_mode;
-  if (mode == protocol::DOM::InspectModeEnum::SearchForNode) {
-    search_mode = kSearchingForNormal;
-  } else if (mode == protocol::DOM::InspectModeEnum::SearchForUAShadowDOM) {
-    search_mode = kSearchingForUAShadow;
-  } else if (mode == protocol::DOM::InspectModeEnum::None) {
-    search_mode = kNotSearching;
-  } else {
-    return Response::Error(
-        String("Unknown mode \"" + mode + "\" was provided."));
-  }
-
-  if (search_mode != kNotSearching) {
-    Response response = PushDocumentUponHandlelessOperation();
-    if (!response.isSuccess())
-      return response;
-  }
-
-  return SetSearchingForNode(search_mode, std::move(highlight_config));
-}
-
-Response InspectorDOMAgent::highlightRect(
-    int x,
-    int y,
-    int width,
-    int height,
-    Maybe<protocol::DOM::RGBA> color,
-    Maybe<protocol::DOM::RGBA> outline_color) {
-  std::unique_ptr<FloatQuad> quad =
-      WTF::WrapUnique(new FloatQuad(FloatRect(x, y, width, height)));
-  InnerHighlightQuad(std::move(quad), std::move(color),
-                     std::move(outline_color));
-  return Response::OK();
-}
-
-Response InspectorDOMAgent::highlightQuad(
-    std::unique_ptr<protocol::Array<double>> quad_array,
-    Maybe<protocol::DOM::RGBA> color,
-    Maybe<protocol::DOM::RGBA> outline_color) {
-  std::unique_ptr<FloatQuad> quad = WTF::MakeUnique<FloatQuad>();
-  if (!ParseQuad(std::move(quad_array), quad.get()))
-    return Response::Error("Invalid Quad format");
-  InnerHighlightQuad(std::move(quad), std::move(color),
-                     std::move(outline_color));
-  return Response::OK();
-}
-
-void InspectorDOMAgent::InnerHighlightQuad(
-    std::unique_ptr<FloatQuad> quad,
-    Maybe<protocol::DOM::RGBA> color,
-    Maybe<protocol::DOM::RGBA> outline_color) {
-  std::unique_ptr<InspectorHighlightConfig> highlight_config =
-      WTF::MakeUnique<InspectorHighlightConfig>();
-  highlight_config->content = ParseColor(color.fromMaybe(nullptr));
-  highlight_config->content_outline =
-      ParseColor(outline_color.fromMaybe(nullptr));
-  if (client_)
-    client_->HighlightQuad(std::move(quad), *highlight_config);
-}
-
-Response InspectorDOMAgent::NodeForRemoteId(const String& object_id,
-                                            Node*& node) {
+Response InspectorDOMAgent::NodeForRemoteObjectId(const String& object_id,
+                                                  Node*& node) {
   v8::HandleScope handles(isolate_);
   v8::Local<v8::Value> value;
   v8::Local<v8::Context> context;
@@ -1290,66 +1126,6 @@
   return Response::OK();
 }
 
-Response InspectorDOMAgent::highlightNode(
-    std::unique_ptr<protocol::DOM::HighlightConfig> highlight_inspector_object,
-    Maybe<int> node_id,
-    Maybe<int> backend_node_id,
-    Maybe<String> object_id) {
-  Node* node = nullptr;
-  Response response;
-  if (node_id.isJust()) {
-    response = AssertNode(node_id.fromJust(), node);
-  } else if (backend_node_id.isJust()) {
-    node = DOMNodeIds::NodeForId(backend_node_id.fromJust());
-    response = !node ? Response::Error("No node found for given backend id")
-                     : Response::OK();
-  } else if (object_id.isJust()) {
-    response = NodeForRemoteId(object_id.fromJust(), node);
-  } else {
-    response = Response::Error("Either nodeId or objectId must be specified");
-  }
-
-  if (!response.isSuccess())
-    return response;
-
-  std::unique_ptr<InspectorHighlightConfig> highlight_config;
-  response = HighlightConfigFromInspectorObject(
-      std::move(highlight_inspector_object), &highlight_config);
-  if (!response.isSuccess())
-    return response;
-
-  if (client_)
-    client_->HighlightNode(node, *highlight_config, false);
-  return Response::OK();
-}
-
-Response InspectorDOMAgent::highlightFrame(
-    const String& frame_id,
-    Maybe<protocol::DOM::RGBA> color,
-    Maybe<protocol::DOM::RGBA> outline_color) {
-  LocalFrame* frame =
-      IdentifiersFactory::FrameById(inspected_frames_, frame_id);
-  // FIXME: Inspector doesn't currently work cross process.
-  if (frame && frame->DeprecatedLocalOwner()) {
-    std::unique_ptr<InspectorHighlightConfig> highlight_config =
-        WTF::MakeUnique<InspectorHighlightConfig>();
-    highlight_config->show_info = true;  // Always show tooltips for frames.
-    highlight_config->content = ParseColor(color.fromMaybe(nullptr));
-    highlight_config->content_outline =
-        ParseColor(outline_color.fromMaybe(nullptr));
-    if (client_)
-      client_->HighlightNode(frame->DeprecatedLocalOwner(), *highlight_config,
-                             false);
-  }
-  return Response::OK();
-}
-
-Response InspectorDOMAgent::hideHighlight() {
-  if (client_)
-    client_->HideHighlight();
-  return Response::OK();
-}
-
 Response InspectorDOMAgent::copyTo(int node_id,
                                    int target_element_id,
                                    Maybe<int> anchor_node_id,
@@ -1540,7 +1316,7 @@
 
 Response InspectorDOMAgent::requestNode(const String& object_id, int* node_id) {
   Node* node = nullptr;
-  Response response = NodeForRemoteId(object_id, node);
+  Response response = NodeForRemoteObjectId(object_id, node);
   if (!response.isSuccess())
     return response;
   *node_id = PushNodePathToFrontend(node);
@@ -2354,18 +2130,6 @@
   return Response::OK();
 }
 
-Response InspectorDOMAgent::getHighlightObjectForTest(
-    int node_id,
-    std::unique_ptr<protocol::DictionaryValue>* result) {
-  Node* node = nullptr;
-  Response response = AssertNode(node_id, node);
-  if (!response.isSuccess())
-    return response;
-  InspectorHighlight highlight(node, InspectorHighlight::DefaultConfig(), true);
-  *result = highlight.AsProtocolValue();
-  return Response::OK();
-}
-
 std::unique_ptr<v8_inspector::protocol::Runtime::API::RemoteObject>
 InspectorDOMAgent::ResolveNode(Node* node, const String& object_group) {
   Document* document =
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
index 1e1680f..37b076c 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
@@ -34,7 +34,6 @@
 #include "core/CoreExport.h"
 #include "core/events/EventListenerMap.h"
 #include "core/inspector/InspectorBaseAgent.h"
-#include "core/inspector/InspectorHighlight.h"
 #include "core/inspector/protocol/DOM.h"
 #include "core/style/ComputedStyleConstants.h"
 #include "platform/geometry/FloatQuad.h"
@@ -48,6 +47,7 @@
 namespace blink {
 
 class CharacterData;
+class Color;
 class DOMEditor;
 class Document;
 class DocumentLoader;
@@ -77,33 +77,14 @@
     virtual void DidModifyDOMAttr(Element*) = 0;
   };
 
-  enum SearchMode {
-    kNotSearching,
-    kSearchingForNormal,
-    kSearchingForUAShadow,
-  };
-
-  class Client {
-   public:
-    virtual ~Client() {}
-    virtual void HideHighlight() {}
-    virtual void HighlightNode(Node*,
-                               const InspectorHighlightConfig&,
-                               bool omit_tooltip) {}
-    virtual void HighlightQuad(std::unique_ptr<FloatQuad>,
-                               const InspectorHighlightConfig&) {}
-    virtual void SetInspectMode(SearchMode search_mode,
-                                std::unique_ptr<InspectorHighlightConfig>) {}
-  };
-
   static protocol::Response ToResponse(ExceptionState&);
   static bool GetPseudoElementType(PseudoId, String*);
   static ShadowRoot* UserAgentShadowRoot(Node*);
+  static Color ParseColor(protocol::DOM::RGBA*);
 
   InspectorDOMAgent(v8::Isolate*,
                     InspectedFrames*,
-                    v8_inspector::V8InspectorSession*,
-                    Client*);
+                    v8_inspector::V8InspectorSession*);
   ~InspectorDOMAgent() override;
   DECLARE_VIRTUAL_TRACE();
 
@@ -165,30 +146,6 @@
   protocol::Response discardSearchResults(const String& search_id) override;
   protocol::Response requestNode(const String& object_id,
                                  int* out_node_id) override;
-  protocol::Response setInspectMode(
-      const String& mode,
-      protocol::Maybe<protocol::DOM::HighlightConfig>) override;
-  protocol::Response highlightRect(
-      int x,
-      int y,
-      int width,
-      int height,
-      protocol::Maybe<protocol::DOM::RGBA> color,
-      protocol::Maybe<protocol::DOM::RGBA> outline_color) override;
-  protocol::Response highlightQuad(
-      std::unique_ptr<protocol::Array<double>> quad,
-      protocol::Maybe<protocol::DOM::RGBA> color,
-      protocol::Maybe<protocol::DOM::RGBA> outline_color) override;
-  protocol::Response highlightNode(
-      std::unique_ptr<protocol::DOM::HighlightConfig>,
-      protocol::Maybe<int> node_id,
-      protocol::Maybe<int> backend_node_id,
-      protocol::Maybe<String> object_id) override;
-  protocol::Response hideHighlight() override;
-  protocol::Response highlightFrame(
-      const String& frame_id,
-      protocol::Maybe<protocol::DOM::RGBA> content_color,
-      protocol::Maybe<protocol::DOM::RGBA> content_outline_color) override;
   protocol::Response pushNodeByPathToFrontend(const String& path,
                                               int* out_node_id) override;
   protocol::Response pushNodesByBackendIdsToFrontend(
@@ -228,9 +185,6 @@
       int* out_node_id) override;
   protocol::Response getRelayoutBoundary(int node_id,
                                          int* out_node_id) override;
-  protocol::Response getHighlightObjectForTest(
-      int node_id,
-      std::unique_ptr<protocol::DictionaryValue>* highlight) override;
 
   bool Enabled() const;
   void ReleaseDanglingNodes();
@@ -261,9 +215,10 @@
   Node* NodeForId(int node_id);
   int BoundNodeId(Node*);
   void SetDOMListener(DOMListener*);
-  void Inspect(Node*);
-  void NodeHighlightedInOverlay(Node*);
   int PushNodePathToFrontend(Node*);
+  protocol::Response PushDocumentUponHandlelessOperation();
+  protocol::Response NodeForRemoteObjectId(const String& remote_object_id,
+                                           Node*&);
 
   static String DocumentURLString(Document*);
 
@@ -296,14 +251,6 @@
   void SetDocument(Document*);
   void InnerEnable();
 
-  protocol::Response SetSearchingForNode(
-      SearchMode,
-      protocol::Maybe<protocol::DOM::HighlightConfig>);
-  protocol::Response HighlightConfigFromInspectorObject(
-      protocol::Maybe<protocol::DOM::HighlightConfig>
-          highlight_inspector_object,
-      std::unique_ptr<InspectorHighlightConfig>*);
-
   // Node-related methods.
   typedef HeapHashMap<Member<Node>, int> NodeToIdMap;
   int Bind(Node*, NodeToIdMap*);
@@ -345,22 +292,14 @@
   BuildDistributedNodesForSlot(HTMLSlotElement*);
 
   Node* NodeForPath(const String& path);
-  protocol::Response NodeForRemoteId(const String& id, Node*&);
 
   void DiscardFrontendBindings();
 
-  void InnerHighlightQuad(std::unique_ptr<FloatQuad>,
-                          protocol::Maybe<protocol::DOM::RGBA> color,
-                          protocol::Maybe<protocol::DOM::RGBA> outline_color);
-
-  protocol::Response PushDocumentUponHandlelessOperation();
-
   InspectorRevalidateDOMTask* RevalidateTask();
 
   v8::Isolate* isolate_;
   Member<InspectedFrames> inspected_frames_;
   v8_inspector::V8InspectorSession* v8_session_;
-  Client* client_;
   Member<DOMListener> dom_listener_;
   Member<NodeToIdMap> document_node_to_id_map_;
   // Owns node mappings for dangling nodes.
@@ -378,7 +317,6 @@
   Member<InspectorHistory> history_;
   Member<DOMEditor> dom_editor_;
   bool suppress_attribute_modified_event_;
-  int backend_node_id_to_inspect_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorHighlight.cpp b/third_party/WebKit/Source/core/inspector/InspectorHighlight.cpp
index 4565010..fc3d16bc 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorHighlight.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorHighlight.cpp
@@ -12,7 +12,7 @@
 #include "core/layout/LayoutObject.h"
 #include "core/layout/shapes/ShapeOutsideInfo.h"
 #include "core/style/ComputedStyleConstants.h"
-#include "platform/HostWindow.h"
+#include "platform/PlatformChromeClient.h"
 #include "platform/graphics/Path.h"
 
 namespace blink {
@@ -253,7 +253,7 @@
       scale_(1.f) {
   FrameView* frame_view = node->GetDocument().View();
   if (frame_view)
-    scale_ = 1.f / frame_view->GetHostWindow()->WindowToViewportScalar(1.f);
+    scale_ = 1.f / frame_view->GetChromeClient()->WindowToViewportScalar(1.f);
   AppendPathsForShapeOutside(node, highlight_config);
   AppendNodeHighlight(node, highlight_config);
   if (append_element_info && node->IsElementNode())
diff --git a/third_party/WebKit/Source/core/inspector/InspectorOverlayHost.cpp b/third_party/WebKit/Source/core/inspector/InspectorOverlayHost.cpp
index 8054b7ba..2db1b96 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorOverlayHost.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorOverlayHost.cpp
@@ -30,7 +30,8 @@
 
 namespace blink {
 
-InspectorOverlayHost::InspectorOverlayHost() : listener_(nullptr) {}
+InspectorOverlayHost::InspectorOverlayHost(Listener* listener)
+    : listener_(listener) {}
 
 void InspectorOverlayHost::resume() {
   if (listener_)
diff --git a/third_party/WebKit/Source/core/inspector/InspectorOverlayHost.h b/third_party/WebKit/Source/core/inspector/InspectorOverlayHost.h
index 0d5d4be..167833c 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorOverlayHost.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorOverlayHost.h
@@ -40,23 +40,20 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static InspectorOverlayHost* Create() { return new InspectorOverlayHost(); }
-  DECLARE_TRACE();
-
-  void resume();
-  void stepOver();
-
   class Listener : public GarbageCollectedMixin {
    public:
     virtual ~Listener() {}
     virtual void OverlayResumed() = 0;
     virtual void OverlaySteppedOver() = 0;
   };
-  void SetListener(Listener* listener) { listener_ = listener; }
+
+  explicit InspectorOverlayHost(Listener*);
+  DECLARE_TRACE();
+
+  void resume();
+  void stepOver();
 
  private:
-  InspectorOverlayHost();
-
   Member<Listener> listener_;
 };
 
diff --git a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
index 428dba6e..2e2a503f 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
@@ -81,8 +81,6 @@
     "pageAgentScriptsToEvaluateOnLoad";
 static const char kScreencastEnabled[] = "screencastEnabled";
 static const char kAutoAttachToCreatedPages[] = "autoAttachToCreatedPages";
-static const char kOverlaySuspended[] = "overlaySuspended";
-static const char kOverlayMessage[] = "overlayMessage";
 }
 
 namespace {
@@ -376,13 +374,6 @@
 void InspectorPageAgent::Restore() {
   if (state_->booleanProperty(PageAgentState::kPageAgentEnabled, false))
     enable();
-  if (client_) {
-    String overlay_message;
-    state_->getString(PageAgentState::kOverlayMessage, &overlay_message);
-    client_->ConfigureOverlay(
-        state_->booleanProperty(PageAgentState::kOverlaySuspended, false),
-        overlay_message);
-  }
 }
 
 Response InspectorPageAgent::enable() {
@@ -403,7 +394,6 @@
       resource_content_loader_client_id_);
 
   stopScreencast();
-  configureOverlay(false, String());
 
   FinishReload();
   return Response::OK();
@@ -864,18 +854,6 @@
   return Response::OK();
 }
 
-Response InspectorPageAgent::configureOverlay(Maybe<bool> suspended,
-                                              Maybe<String> message) {
-  state_->setBoolean(PageAgentState::kOverlaySuspended,
-                     suspended.fromMaybe(false));
-  state_->setString(PageAgentState::kOverlaySuspended,
-                    message.fromMaybe(String()));
-  if (client_)
-    client_->ConfigureOverlay(suspended.fromMaybe(false),
-                              message.fromMaybe(String()));
-  return Response::OK();
-}
-
 Response InspectorPageAgent::getLayoutMetrics(
     std::unique_ptr<protocol::Page::LayoutViewport>* out_layout_viewport,
     std::unique_ptr<protocol::Page::VisualViewport>* out_visual_viewport,
diff --git a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
index 0080aa1..48ec089b 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
@@ -66,7 +66,6 @@
    public:
     virtual ~Client() {}
     virtual void PageLayoutInvalidated(bool resized) {}
-    virtual void ConfigureOverlay(bool suspended, const String& message) {}
     virtual void WaitForCreateWindow(LocalFrame*) {}
   };
 
@@ -139,8 +138,6 @@
                                      Maybe<int> max_height,
                                      Maybe<int> every_nth_frame) override;
   protocol::Response stopScreencast() override;
-  protocol::Response configureOverlay(Maybe<bool> suspended,
-                                      Maybe<String> message) override;
   protocol::Response getLayoutMetrics(
       std::unique_ptr<protocol::Page::LayoutViewport>*,
       std::unique_ptr<protocol::Page::VisualViewport>*,
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.json b/third_party/WebKit/Source/core/inspector/browser_protocol.json
index cca3bc9..ccc2d2b3b 100644
--- a/third_party/WebKit/Source/core/inspector/browser_protocol.json
+++ b/third_party/WebKit/Source/core/inspector/browser_protocol.json
@@ -469,15 +469,6 @@
                 ]
             },
             {
-                "name": "configureOverlay",
-                "parameters": [
-                    { "name": "suspended", "type": "boolean", "optional": true, "description": "Whether overlay should be suspended and not consume any resources." },
-                    { "name": "message", "type": "string", "optional": true, "description": "Overlay message to display." }
-                ],
-                "experimental": true,
-                "description": "Configures overlay."
-            },
-            {
                 "name": "getAppManifest",
                 "experimental": true,
                 "returns": [
@@ -645,11 +636,50 @@
         ]
     },
     {
-        "domain": "Rendering",
-        "description": "This domain allows to control rendering of the page.",
+        "domain": "Overlay",
+        "description": "This domain provides various functionality related to drawing atop the inspected page.",
+        "dependencies": ["DOM", "Page", "Runtime"],
         "experimental": true,
+        "types": [
+            {
+                "id": "HighlightConfig",
+                "type": "object",
+                "properties": [
+                    { "name": "showInfo", "type": "boolean", "optional": true, "description": "Whether the node info tooltip should be shown (default: false)." },
+                    { "name": "showRulers", "type": "boolean", "optional": true, "description": "Whether the rulers should be shown (default: false)." },
+                    { "name": "showExtensionLines", "type": "boolean", "optional": true, "description": "Whether the extension lines from node to the rulers should be shown (default: false)." },
+                    { "name": "displayAsMaterial", "type": "boolean", "optional": true},
+                    { "name": "contentColor", "$ref": "DOM.RGBA", "optional": true, "description": "The content box highlight fill color (default: transparent)." },
+                    { "name": "paddingColor", "$ref": "DOM.RGBA", "optional": true, "description": "The padding highlight fill color (default: transparent)." },
+                    { "name": "borderColor", "$ref": "DOM.RGBA", "optional": true, "description": "The border highlight fill color (default: transparent)." },
+                    { "name": "marginColor", "$ref": "DOM.RGBA", "optional": true, "description": "The margin highlight fill color (default: transparent)." },
+                    { "name": "eventTargetColor", "$ref": "DOM.RGBA", "optional": true, "description": "The event target element highlight fill color (default: transparent)." },
+                    { "name": "shapeColor", "$ref": "DOM.RGBA", "optional": true, "description": "The shape outside fill color (default: transparent)." },
+                    { "name": "shapeMarginColor", "$ref": "DOM.RGBA", "optional": true, "description": "The shape margin fill color (default: transparent)." },
+                    { "name": "selectorList", "type": "string", "optional": true, "description": "Selectors to highlight relevant nodes."}
+                ],
+                "description": "Configuration data for the highlighting of page elements."
+            },
+            {
+                "id": "InspectMode",
+                "type": "string",
+                "enum": [
+                    "searchForNode",
+                    "searchForUAShadowDOM",
+                    "none"
+                ]
+            }
+        ],
         "commands": [
             {
+                "name": "enable",
+                "description": "Enables domain notifications."
+            },
+            {
+                "name": "disable",
+                "description": "Disables domain notifications."
+            },
+            {
                 "name": "setShowPaintRects",
                 "description": "Requests that backend shows paint rectangles",
                 "parameters": [
@@ -683,6 +713,96 @@
                 "parameters": [
                     { "name": "show", "type": "boolean", "description": "Whether to paint size or not." }
                 ]
+            },
+            {
+                "name": "setPausedInDebuggerMessage",
+                "parameters": [
+                    { "name": "message", "type": "string", "optional": true, "description": "The message to display, also triggers resume and step over controls." }
+                ]
+            },
+            {
+                "name": "setSuspended",
+                "parameters": [
+                    { "name": "suspended", "type": "boolean", "description": "Whether overlay should be suspended and not consume any resources until resumed." }
+                ]
+            },
+            {
+                "name": "setInspectMode",
+                "description": "Enters the 'inspect' mode. In this mode, elements that user is hovering over are highlighted. Backend then generates 'inspectNodeRequested' event upon element selection.",
+                "parameters": [
+                    { "name": "mode", "$ref": "InspectMode", "description": "Set an inspection mode." },
+                    { "name": "highlightConfig", "$ref": "HighlightConfig", "optional": true, "description": "A descriptor for the highlight appearance of hovered-over nodes. May be omitted if <code>enabled == false</code>." }
+                ]
+            },
+            {
+                "name": "highlightRect",
+                "description": "Highlights given rectangle. Coordinates are absolute with respect to the main frame viewport.",
+                "parameters": [
+                    { "name": "x", "type": "integer", "description": "X coordinate" },
+                    { "name": "y", "type": "integer", "description": "Y coordinate" },
+                    { "name": "width", "type": "integer", "description": "Rectangle width" },
+                    { "name": "height", "type": "integer", "description": "Rectangle height" },
+                    { "name": "color", "$ref": "DOM.RGBA", "optional": true, "description": "The highlight fill color (default: transparent)." },
+                    { "name": "outlineColor", "$ref": "DOM.RGBA", "optional": true, "description": "The highlight outline color (default: transparent)." }
+                ]
+            },
+            {
+                "name": "highlightQuad",
+                "description": "Highlights given quad. Coordinates are absolute with respect to the main frame viewport.",
+                "parameters": [
+                    { "name": "quad", "$ref": "DOM.Quad", "description": "Quad to highlight" },
+                    { "name": "color", "$ref": "DOM.RGBA", "optional": true, "description": "The highlight fill color (default: transparent)." },
+                    { "name": "outlineColor", "$ref": "DOM.RGBA", "optional": true, "description": "The highlight outline color (default: transparent)." }
+                ]
+            },
+            {
+                "name": "highlightNode",
+                "description": "Highlights DOM node with given id or with the given JavaScript object wrapper. Either nodeId or objectId must be specified.",
+                "parameters": [
+                    { "name": "highlightConfig", "$ref": "HighlightConfig",  "description": "A descriptor for the highlight appearance." },
+                    { "name": "nodeId", "$ref": "DOM.NodeId", "optional": true, "description": "Identifier of the node to highlight." },
+                    { "name": "backendNodeId", "$ref": "DOM.BackendNodeId", "optional": true, "description": "Identifier of the backend node to highlight." },
+                    { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "optional": true, "description": "JavaScript object id of the node to be highlighted." }
+                ]
+            },
+            {
+                "name": "highlightFrame",
+                "description": "Highlights owner element of the frame with given id.",
+                "parameters": [
+                    { "name": "frameId", "$ref": "Page.FrameId", "description": "Identifier of the frame to highlight." },
+                    { "name": "contentColor", "$ref": "DOM.RGBA", "optional": true, "description": "The content box highlight fill color (default: transparent)." },
+                    { "name": "contentOutlineColor", "$ref": "DOM.RGBA", "optional": true, "description": "The content box highlight outline color (default: transparent)." }
+                ]
+            },
+            {
+                "name": "hideHighlight",
+                "description": "Hides any highlight."
+            },
+            {
+                "name": "getHighlightObjectForTest",
+                "description": "For testing.",
+                "parameters": [
+                    { "name": "nodeId", "$ref": "DOM.NodeId", "description": "Id of the node to get highlight object for." }
+                ],
+                "returns": [
+                    { "name": "highlight", "type": "object", "description": "Highlight data for the node." }
+                ]
+            }
+        ],
+        "events": [
+            {
+                "name": "nodeHighlightRequested",
+                "description": "Fired when the node should be highlighted. This happens after call to <code>setInspectMode</code>.",
+                "parameters": [
+                    { "name": "nodeId", "$ref": "DOM.NodeId" }
+                ]
+            },
+            {
+                "name": "inspectNodeRequested",
+                "description": "Fired when the node should be inspected. This happens after call to <code>setInspectMode</code> or when user manually inspects an element.",
+                "parameters": [
+                    { "name": "backendNodeId", "$ref": "DOM.BackendNodeId", "description": "Id of the node to inspect." }
+                ]
             }
         ]
     },
@@ -2138,35 +2258,6 @@
                     { "name": "height", "type": "number", "description": "Rectangle height" }
                 ],
                 "description": "Rectangle."
-            },
-            {
-                "id": "HighlightConfig",
-                "type": "object",
-                "properties": [
-                    { "name": "showInfo", "type": "boolean", "optional": true, "description": "Whether the node info tooltip should be shown (default: false)." },
-                    { "name": "showRulers", "type": "boolean", "optional": true, "description": "Whether the rulers should be shown (default: false)." },
-                    { "name": "showExtensionLines", "type": "boolean", "optional": true, "description": "Whether the extension lines from node to the rulers should be shown (default: false)." },
-                    { "name": "displayAsMaterial", "type": "boolean", "optional": true, "experimental": true},
-                    { "name": "contentColor", "$ref": "RGBA", "optional": true, "description": "The content box highlight fill color (default: transparent)." },
-                    { "name": "paddingColor", "$ref": "RGBA", "optional": true, "description": "The padding highlight fill color (default: transparent)." },
-                    { "name": "borderColor", "$ref": "RGBA", "optional": true, "description": "The border highlight fill color (default: transparent)." },
-                    { "name": "marginColor", "$ref": "RGBA", "optional": true, "description": "The margin highlight fill color (default: transparent)." },
-                    { "name": "eventTargetColor", "$ref": "RGBA", "optional": true, "experimental": true, "description": "The event target element highlight fill color (default: transparent)." },
-                    { "name": "shapeColor", "$ref": "RGBA", "optional": true, "experimental": true, "description": "The shape outside fill color (default: transparent)." },
-                    { "name": "shapeMarginColor", "$ref": "RGBA", "optional": true, "experimental": true, "description": "The shape margin fill color (default: transparent)." },
-                    { "name": "selectorList", "type": "string", "optional": true, "description": "Selectors to highlight relevant nodes."}
-                ],
-                "description": "Configuration data for the highlighting of page elements."
-            },
-            {
-                "id": "InspectMode",
-                "type": "string",
-                "experimental": true,
-                "enum": [
-                    "searchForNode",
-                    "searchForUAShadowDOM",
-                    "none"
-                ]
             }
         ],
         "commands": [
@@ -2357,59 +2448,19 @@
                 "description": "Requests that the node is sent to the caller given the JavaScript node object reference. All nodes that form the path from the node to the root are also sent to the client as a series of <code>setChildNodes</code> notifications."
             },
             {
-                "name": "setInspectMode",
-                "experimental": true,
-                "parameters": [
-                    { "name": "mode", "$ref": "InspectMode", "description": "Set an inspection mode." },
-                    { "name": "highlightConfig", "$ref": "HighlightConfig", "optional": true, "description": "A descriptor for the highlight appearance of hovered-over nodes. May be omitted if <code>enabled == false</code>." }
-                ],
-                "description": "Enters the 'inspect' mode. In this mode, elements that user is hovering over are highlighted. Backend then generates 'inspectNodeRequested' event upon element selection."
-            },
-            {
                 "name": "highlightRect",
-                "parameters": [
-                    { "name": "x", "type": "integer", "description": "X coordinate" },
-                    { "name": "y", "type": "integer", "description": "Y coordinate" },
-                    { "name": "width", "type": "integer", "description": "Rectangle width" },
-                    { "name": "height", "type": "integer", "description": "Rectangle height" },
-                    { "name": "color", "$ref": "RGBA", "optional": true, "description": "The highlight fill color (default: transparent)." },
-                    { "name": "outlineColor", "$ref": "RGBA", "optional": true, "description": "The highlight outline color (default: transparent)." }
-                ],
-                "description": "Highlights given rectangle. Coordinates are absolute with respect to the main frame viewport."
-            },
-            {
-                "name": "highlightQuad",
-                "parameters": [
-                    { "name": "quad", "$ref": "Quad", "description": "Quad to highlight" },
-                    { "name": "color", "$ref": "RGBA", "optional": true, "description": "The highlight fill color (default: transparent)." },
-                    { "name": "outlineColor", "$ref": "RGBA", "optional": true, "description": "The highlight outline color (default: transparent)." }
-                ],
-                "description": "Highlights given quad. Coordinates are absolute with respect to the main frame viewport.",
-                "experimental": true
+                "description": "Highlights given rectangle.",
+                "redirect": "Overlay"
             },
             {
                 "name": "highlightNode",
-                "parameters": [
-                    { "name": "highlightConfig", "$ref": "HighlightConfig",  "description": "A descriptor for the highlight appearance." },
-                    { "name": "nodeId", "$ref": "NodeId", "optional": true, "description": "Identifier of the node to highlight." },
-                    { "name": "backendNodeId", "$ref": "BackendNodeId", "optional": true, "description": "Identifier of the backend node to highlight." },
-                    { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "optional": true, "description": "JavaScript object id of the node to be highlighted.", "experimental": true }
-                ],
-                "description": "Highlights DOM node with given id or with the given JavaScript object wrapper. Either nodeId or objectId must be specified."
+                "description": "Highlights DOM node.",
+                "redirect": "Overlay"
             },
             {
                 "name": "hideHighlight",
-                "description": "Hides DOM node highlight."
-            },
-            {
-                "name": "highlightFrame",
-                "parameters": [
-                    { "name": "frameId", "$ref": "Page.FrameId", "description": "Identifier of the frame to highlight." },
-                    { "name": "contentColor", "$ref": "RGBA", "optional": true, "description": "The content box highlight fill color (default: transparent)." },
-                    { "name": "contentOutlineColor", "$ref": "RGBA", "optional": true, "description": "The content box highlight outline color (default: transparent)." }
-                ],
-                "description": "Highlights owner element of the frame with given id.",
-                "experimental": true
+                "description": "Hides any highlight.",
+                "redirect": "Overlay"
             },
             {
                 "name": "pushNodeByPathToFrontend",
@@ -2553,17 +2604,6 @@
                 ],
                 "description": "Returns the id of the nearest ancestor that is a relayout boundary.",
                 "experimental": true
-            },
-            {
-                "name": "getHighlightObjectForTest",
-                "parameters": [
-                    { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to get highlight object for." }
-                ],
-                "returns": [
-                    { "name": "highlight", "type": "object", "description": "Highlight data for the node." }
-                ],
-                "description": "For testing.",
-                "experimental": true
             }
         ],
         "events": [
@@ -2572,14 +2612,6 @@
                 "description": "Fired when <code>Document</code> has been totally updated. Node ids are no longer valid."
             },
             {
-                "name": "inspectNodeRequested",
-                "parameters": [
-                    { "name": "backendNodeId", "$ref": "BackendNodeId", "description": "Id of the node to inspect." }
-                ],
-                "description": "Fired when the node should be inspected. This happens after call to <code>setInspectMode</code>.",
-                "experimental" : true
-            },
-            {
                 "name": "setChildNodes",
                 "parameters": [
                     { "name": "parentId", "$ref": "NodeId", "description": "Parent node id to populate with children." },
@@ -2689,13 +2721,6 @@
                 ],
                 "description": "Called when distrubution is changed.",
                 "experimental": true
-            },
-            {
-                "name": "nodeHighlightRequested",
-                "parameters": [
-                    {"name": "nodeId", "$ref": "NodeId"}
-                ],
-                "experimental": true
             }
         ]
     },
diff --git a/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json
index 21048f15..4fb3f5b6 100644
--- a/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json
+++ b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json
@@ -51,7 +51,7 @@
                 "domain": "Log"
             },
             {
-                "domain": "Rendering"
+                "domain": "Overlay"
             },
             {
                 "domain": "Input",
diff --git a/third_party/WebKit/Source/core/layout/LayoutMenuList.cpp b/third_party/WebKit/Source/core/layout/LayoutMenuList.cpp
index b61f73c..1e210c4 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMenuList.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMenuList.cpp
@@ -99,9 +99,10 @@
 
   Length padding_start = Length(
       LayoutTheme::GetTheme().PopupInternalPaddingStart(StyleRef()), kFixed);
-  Length padding_end = Length(LayoutTheme::GetTheme().PopupInternalPaddingEnd(
-                                  GetFrameView()->GetHostWindow(), StyleRef()),
-                              kFixed);
+  Length padding_end =
+      Length(LayoutTheme::GetTheme().PopupInternalPaddingEnd(
+                 GetFrameView()->GetChromeClient(), StyleRef()),
+             kFixed);
   inner_style.SetPaddingLeft(StyleRef().Direction() == TextDirection::kLtr
                                  ? padding_start
                                  : padding_end);
diff --git a/third_party/WebKit/Source/core/layout/LayoutTheme.h b/third_party/WebKit/Source/core/layout/LayoutTheme.h
index f76768d..e87c075 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTheme.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTheme.h
@@ -41,9 +41,9 @@
 class ComputedStyle;
 class Element;
 class FileList;
-class HostWindow;
 class HTMLInputElement;
 class LayoutObject;
+class PlatformChromeClient;
 class Theme;
 class ThemePainter;
 
@@ -172,7 +172,7 @@
   virtual int PopupInternalPaddingStart(const ComputedStyle&) const {
     return 0;
   }
-  virtual int PopupInternalPaddingEnd(const HostWindow*,
+  virtual int PopupInternalPaddingEnd(const PlatformChromeClient*,
                                       const ComputedStyle&) const {
     return 0;
   }
diff --git a/third_party/WebKit/Source/core/layout/LayoutThemeDefault.cpp b/third_party/WebKit/Source/core/layout/LayoutThemeDefault.cpp
index fc2e27b7..11c221b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutThemeDefault.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutThemeDefault.cpp
@@ -28,8 +28,8 @@
 #include "core/layout/LayoutThemeFontProvider.h"
 #include "core/paint/MediaControlsPainter.h"
 #include "core/style/ComputedStyle.h"
-#include "platform/HostWindow.h"
 #include "platform/LayoutTestSupport.h"
+#include "platform/PlatformChromeClient.h"
 #include "platform/PlatformResourceLoader.h"
 #include "platform/graphics/Color.h"
 #include "platform/wtf/text/StringBuilder.h"
@@ -318,12 +318,12 @@
 }
 
 int LayoutThemeDefault::PopupInternalPaddingEnd(
-    const HostWindow* host,
+    const PlatformChromeClient* client,
     const ComputedStyle& style) const {
   if (style.Appearance() == kNoControlPart)
     return 0;
   return 1 * style.EffectiveZoom() +
-         ClampedMenuListArrowPaddingSize(host, style);
+         ClampedMenuListArrowPaddingSize(client, style);
 }
 
 int LayoutThemeDefault::PopupInternalPaddingTop(
@@ -345,7 +345,7 @@
 }
 
 float LayoutThemeDefault::ClampedMenuListArrowPaddingSize(
-    const HostWindow* host,
+    const PlatformChromeClient* client,
     const ComputedStyle& style) const {
   if (cached_menu_list_arrow_padding_size_ > 0 &&
       style.EffectiveZoom() == cached_menu_list_arrow_zoom_level_)
@@ -353,7 +353,7 @@
   cached_menu_list_arrow_zoom_level_ = style.EffectiveZoom();
   int original_size = MenuListArrowWidthInDIP();
   int scaled_size =
-      host ? host->WindowToViewportScalar(original_size) : original_size;
+      client ? client->WindowToViewportScalar(original_size) : original_size;
   // The result should not be samller than the scrollbar thickness in order to
   // secure space for scrollbar in popup.
   float device_scale = 1.0f * scaled_size / original_size;
diff --git a/third_party/WebKit/Source/core/layout/LayoutThemeDefault.h b/third_party/WebKit/Source/core/layout/LayoutThemeDefault.h
index 7401d98..3fce86c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutThemeDefault.h
+++ b/third_party/WebKit/Source/core/layout/LayoutThemeDefault.h
@@ -111,7 +111,7 @@
 
   // These methods define the padding for the MenuList's inner block.
   int PopupInternalPaddingStart(const ComputedStyle&) const override;
-  int PopupInternalPaddingEnd(const HostWindow*,
+  int PopupInternalPaddingEnd(const PlatformChromeClient*,
                               const ComputedStyle&) const override;
   int PopupInternalPaddingTop(const ComputedStyle&) const override;
   int PopupInternalPaddingBottom(const ComputedStyle&) const override;
@@ -120,7 +120,7 @@
   // thickness, which is 3px or 4px, and we use the value from the default Aura
   // theme.
   int MenuListArrowWidthInDIP() const;
-  float ClampedMenuListArrowPaddingSize(const HostWindow*,
+  float ClampedMenuListArrowPaddingSize(const PlatformChromeClient*,
                                         const ComputedStyle&) const;
 
   // Provide a way to pass the default font size from the Settings object
diff --git a/third_party/WebKit/Source/core/layout/LayoutThemeMac.h b/third_party/WebKit/Source/core/layout/LayoutThemeMac.h
index 1dc2d21..beab13d6 100644
--- a/third_party/WebKit/Source/core/layout/LayoutThemeMac.h
+++ b/third_party/WebKit/Source/core/layout/LayoutThemeMac.h
@@ -76,7 +76,7 @@
   int SliderTickOffsetFromTrackCenter() const override;
 
   int PopupInternalPaddingStart(const ComputedStyle&) const override;
-  int PopupInternalPaddingEnd(const HostWindow*,
+  int PopupInternalPaddingEnd(const PlatformChromeClient*,
                               const ComputedStyle&) const override;
   int PopupInternalPaddingTop(const ComputedStyle&) const override;
   int PopupInternalPaddingBottom(const ComputedStyle&) const override;
diff --git a/third_party/WebKit/Source/core/layout/LayoutThemeMac.mm b/third_party/WebKit/Source/core/layout/LayoutThemeMac.mm
index f5ab055f..8f1d73f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutThemeMac.mm
+++ b/third_party/WebKit/Source/core/layout/LayoutThemeMac.mm
@@ -759,7 +759,7 @@
   return 0;
 }
 
-int LayoutThemeMac::PopupInternalPaddingEnd(const HostWindow*,
+int LayoutThemeMac::PopupInternalPaddingEnd(const PlatformChromeClient*,
                                             const ComputedStyle& style) const {
   if (style.Appearance() == kMenulistPart)
     return PopupButtonPadding(
diff --git a/third_party/WebKit/Source/core/page/ChromeClient.cpp b/third_party/WebKit/Source/core/page/ChromeClient.cpp
index 3c21443..972b1db 100644
--- a/third_party/WebKit/Source/core/page/ChromeClient.cpp
+++ b/third_party/WebKit/Source/core/page/ChromeClient.cpp
@@ -40,7 +40,7 @@
 
 DEFINE_TRACE(ChromeClient) {
   visitor->Trace(last_mouse_over_node_);
-  HostWindow::Trace(visitor);
+  PlatformChromeClient::Trace(visitor);
 }
 
 void ChromeClient::SetWindowRectWithAdjustment(const IntRect& pending_rect,
diff --git a/third_party/WebKit/Source/core/page/ChromeClient.h b/third_party/WebKit/Source/core/page/ChromeClient.h
index e2cb1bb..ccec9cfd 100644
--- a/third_party/WebKit/Source/core/page/ChromeClient.h
+++ b/third_party/WebKit/Source/core/page/ChromeClient.h
@@ -33,7 +33,7 @@
 #include "core/loader/NavigationPolicy.h"
 #include "core/style/ComputedStyleConstants.h"
 #include "platform/Cursor.h"
-#include "platform/HostWindow.h"
+#include "platform/PlatformChromeClient.h"
 #include "platform/PopupMenu.h"
 #include "platform/heap/Handle.h"
 #include "platform/scroll/ScrollTypes.h"
@@ -86,7 +86,7 @@
 struct WebScreenInfo;
 struct WindowFeatures;
 
-class CORE_EXPORT ChromeClient : public HostWindow {
+class CORE_EXPORT ChromeClient : public PlatformChromeClient {
  public:
   virtual void ChromeDestroyed() = 0;
 
@@ -181,10 +181,10 @@
 
   virtual void* WebView() const = 0;
 
-  // Methods used by HostWindow.
+  // Methods used by PlatformChromeClient.
   virtual WebScreenInfo GetScreenInfo() const = 0;
   virtual void SetCursor(const Cursor&, LocalFrame* local_root) = 0;
-  // End methods used by HostWindow.
+  // End methods used by PlatformChromeClient.
 
   virtual Cursor LastSetCursorForTesting() const = 0;
   Node* LastSetTooltipNodeForTesting() const {
diff --git a/third_party/WebKit/Source/core/page/SpatialNavigation.cpp b/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
index ea4018c31..76fef104d 100644
--- a/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
+++ b/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
@@ -160,7 +160,7 @@
   // If the container has overflow:hidden, we cannot scroll, so we do not pass
   // direction and we do not adjust for scrolling.
   int pixels_per_line_step =
-      ScrollableArea::PixelsPerLineStep(frame_view->GetHostWindow());
+      ScrollableArea::PixelsPerLineStep(frame_view->GetChromeClient());
   switch (type) {
     case kWebFocusTypeLeft:
       container_viewport_rect.SetX(container_viewport_rect.X() -
@@ -204,7 +204,7 @@
     int dx = 0;
     int dy = 0;
     int pixels_per_line_step =
-        ScrollableArea::PixelsPerLineStep(frame->View()->GetHostWindow());
+        ScrollableArea::PixelsPerLineStep(frame->View()->GetChromeClient());
     switch (type) {
       case kWebFocusTypeLeft:
         dx = -pixels_per_line_step;
@@ -243,7 +243,7 @@
     // TODO(leviw): Why are these values truncated (toInt) instead of rounding?
     FrameView* frame_view = container->GetDocument().View();
     int pixels_per_line_step = ScrollableArea::PixelsPerLineStep(
-        frame_view ? frame_view->GetHostWindow() : nullptr);
+        frame_view ? frame_view->GetChromeClient() : nullptr);
     switch (type) {
       case kWebFocusTypeLeft:
         dx = -pixels_per_line_step;
diff --git a/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp
index ecf9e80a..4f2740e7 100644
--- a/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp
+++ b/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp
@@ -12,7 +12,7 @@
 #include "core/paint/FindPaintOffsetAndVisualRectNeedingUpdate.h"
 #include "core/paint/PaintInvalidator.h"
 #include "core/paint/PaintLayer.h"
-#include "platform/HostWindow.h"
+#include "platform/PlatformChromeClient.h"
 #include "platform/graphics/GraphicsLayer.h"
 
 namespace blink {
@@ -297,8 +297,8 @@
   if (paint_rect.IsEmpty())
     return;
 
-  if (HostWindow* window = frame_view->GetHostWindow())
-    window->InvalidateRect(frame_view->ContentsToRootFrame(paint_rect));
+  if (PlatformChromeClient* client = frame_view->GetChromeClient())
+    client->InvalidateRect(frame_view->ContentsToRootFrame(paint_rect));
 }
 
 void ObjectPaintInvalidator::SetBackingNeedsPaintInvalidationInRect(
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index 4e4ff7a..a172946 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -203,7 +203,7 @@
   ScrollableArea::Trace(visitor);
 }
 
-HostWindow* PaintLayerScrollableArea::GetHostWindow() const {
+PlatformChromeClient* PaintLayerScrollableArea::GetChromeClient() const {
   if (Page* page = Box().GetFrame()->GetPage())
     return &page->GetChromeClient();
   return nullptr;
@@ -1902,8 +1902,8 @@
 }
 
 bool PaintLayerScrollableArea::ScheduleAnimation() {
-  if (HostWindow* window = GetHostWindow()) {
-    window->ScheduleAnimation(Box().GetFrame());
+  if (PlatformChromeClient* client = GetChromeClient()) {
+    client->ScheduleAnimation(Box().GetFrame());
     return true;
   }
   return false;
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
index 7c27f3c..e2ee422 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
@@ -238,7 +238,7 @@
     return scrollbar_manager_.VerticalScrollbar();
   }
 
-  HostWindow* GetHostWindow() const override;
+  PlatformChromeClient* GetChromeClient() const override;
 
   // For composited scrolling, we allocate an extra GraphicsLayer to hold
   // onto the scrolling content. The layer can be shifted on the GPU and
diff --git a/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp b/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
index 67cd37d..ef25cdf1 100644
--- a/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
@@ -13,7 +13,7 @@
 #include "core/paint/PaintLayerScrollableArea.h"
 #include "core/paint/ScrollbarPainter.h"
 #include "core/paint/TransformRecorder.h"
-#include "platform/HostWindow.h"
+#include "platform/PlatformChromeClient.h"
 #include "platform/graphics/GraphicsContext.h"
 #include "platform/graphics/GraphicsContextStateSaver.h"
 #include "platform/graphics/paint/ClipRecorder.h"
@@ -77,7 +77,7 @@
   // value of 1 in the call for |windowToViewportScalar|. Since zoom-for-dsf is
   // disabled on MAC, |windowToViewportScalar| will be a no-op on it.
   float device_scale_factor =
-      GetScrollableArea().GetHostWindow()->WindowToViewportScalar(
+      GetScrollableArea().GetChromeClient()->WindowToViewportScalar(
           old_device_scale_factor);
 
   RefPtr<Image> resize_corner_image;
diff --git a/third_party/WebKit/Source/core/paint/ThemePainterDefault.cpp b/third_party/WebKit/Source/core/paint/ThemePainterDefault.cpp
index b3d37907..0cf2f4e 100644
--- a/third_party/WebKit/Source/core/paint/ThemePainterDefault.cpp
+++ b/third_party/WebKit/Source/core/paint/ThemePainterDefault.cpp
@@ -290,7 +290,7 @@
 
   extra_params.menu_list.arrow_y = middle;
   float arrow_box_width = theme_.ClampedMenuListArrowPaddingSize(
-      box.GetFrameView()->GetHostWindow(), box.StyleRef());
+      box.GetFrameView()->GetChromeClient(), box.StyleRef());
   float arrow_scale_factor = arrow_box_width / theme_.MenuListArrowWidthInDIP();
   if (UseMockTheme()) {
     // The size and position of the drop-down button is different between
diff --git a/third_party/WebKit/Source/core/paint/ThemePainterMac.mm b/third_party/WebKit/Source/core/paint/ThemePainterMac.mm
index 79c9b558..b67c711 100644
--- a/third_party/WebKit/Source/core/paint/ThemePainterMac.mm
+++ b/third_party/WebKit/Source/core/paint/ThemePainterMac.mm
@@ -239,28 +239,20 @@
   track_info.reserved = 0;
   track_info.filler1 = 0;
 
-  std::unique_ptr<ImageBuffer> image_buffer = ImageBuffer::Create(rect.Size());
-  if (!image_buffer)
-    return true;
-
-  IntRect clip_rect = IntRect(IntPoint(), rect.Size());
-  LocalCurrentGraphicsContext local_context(image_buffer->Canvas(), 1,
-                                            clip_rect);
-  CGContextRef cg_context = local_context.CgContext();
-  HIThemeDrawTrack(&track_info, 0, cg_context, kHIThemeOrientationNormal);
-
   GraphicsContextStateSaver state_saver(paint_info.context);
+  paint_info.context.Translate(rect.X(), rect.Y());
 
   if (!layout_progress.StyleRef().IsLeftToRightDirection()) {
-    paint_info.context.Translate(2 * rect.X() + rect.Width(), 0);
+    paint_info.context.Translate(rect.Width(), 0);
     paint_info.context.Scale(-1, 1);
   }
 
-  if (!paint_info.context.ContextDisabled())
-    image_buffer->Draw(
-        paint_info.context,
-        FloatRect(rect.Location(), FloatSize(image_buffer->size())), nullptr,
-        SkBlendMode::kSrcOver);
+  IntRect clip_rect = IntRect(IntPoint(), rect.Size());
+  LocalCurrentGraphicsContext local_context(paint_info.context, clip_rect);
+
+  CGContextRef cg_context = local_context.CgContext();
+  HIThemeDrawTrack(&track_info, 0, cg_context, kHIThemeOrientationNormal);
+
   return false;
 }
 
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h
index 1c86397..5c953f7e 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -1295,27 +1295,30 @@
   }
 
   // Padding properties.
-  static Length InitialPadding() { return Length(kFixed); }
 
   // padding-bottom
+  static Length InitialPaddingBottom() { return Length(kFixed); }
   const Length& PaddingBottom() const { return surround_->padding_.Bottom(); }
   void SetPaddingBottom(const Length& v) {
     SET_VAR(surround_, padding_.bottom_, v);
   }
 
   // padding-left
+  static Length InitialPaddingLeft() { return Length(kFixed); }
   const Length& PaddingLeft() const { return surround_->padding_.Left(); }
   void SetPaddingLeft(const Length& v) {
     SET_VAR(surround_, padding_.left_, v);
   }
 
   // padding-right
+  static Length InitialPaddingRight() { return Length(kFixed); }
   const Length& PaddingRight() const { return surround_->padding_.Right(); }
   void SetPaddingRight(const Length& v) {
     SET_VAR(surround_, padding_.right_, v);
   }
 
   // padding-top
+  static Length InitialPaddingTop() { return Length(kFixed); }
   const Length& PaddingTop() const { return surround_->padding_.Top(); }
   void SetPaddingTop(const Length& v) { SET_VAR(surround_, padding_.top_, v); }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGScriptElement.h b/third_party/WebKit/Source/core/svg/SVGScriptElement.h
index 69588b8c..398887d5 100644
--- a/third_party/WebKit/Source/core/svg/SVGScriptElement.h
+++ b/third_party/WebKit/Source/core/svg/SVGScriptElement.h
@@ -77,6 +77,7 @@
   String ForAttributeValue() const { return String(); }
   String IntegrityAttributeValue() const { return String(); }
   String LanguageAttributeValue() const { return String(); }
+  bool NomoduleAttributeValue() const { return false; }
   String SourceAttributeValue() const override;
   String TypeAttributeValue() const override;
   String TextFromChildren() override;
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn
index 1a4bec2e..c15e36f 100644
--- a/third_party/WebKit/Source/devtools/BUILD.gn
+++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -292,7 +292,6 @@
   "front_end/main/GCActionDelegate.js",
   "front_end/main/Main.js",
   "front_end/main/module.json",
-  "front_end/main/OverlayController.js",
   "front_end/main/remoteDebuggingTerminatedScreen.css",
   "front_end/main/renderingOptions.css",
   "front_end/main/RenderingOptions.js",
@@ -473,6 +472,7 @@
   "front_end/sdk/module.json",
   "front_end/sdk/NetworkManager.js",
   "front_end/sdk/NetworkRequest.js",
+  "front_end/sdk/OverlayModel.js",
   "front_end/sdk/PaintProfiler.js",
   "front_end/sdk/ProfileTreeModel.js",
   "front_end/sdk/RemoteObject.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js
index fc69390e..884dd30 100644
--- a/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js
+++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js
@@ -157,7 +157,7 @@
       if (!this.node())
         return;
       // Highlight and scroll into view the currently inspected node.
-      this.node().domModel().nodeHighlightRequested(this.node().id);
+      this.node().domModel().overlayModel().nodeHighlightRequested(this.node().id);
     }
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js
index 5fe56b5..87dd668 100644
--- a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js
@@ -156,7 +156,7 @@
     this.deferredDOMNode().resolvePromise().then(node => {
       if (!node)
         return;
-      node.domModel().nodeHighlightRequested(node.id);
+      node.domModel().overlayModel().nodeHighlightRequested(node.id);
     });
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/common/Color.js b/third_party/WebKit/Source/devtools/front_end/common/Color.js
index ed25f69a..10db609 100644
--- a/third_party/WebKit/Source/devtools/front_end/common/Color.js
+++ b/third_party/WebKit/Source/devtools/front_end/common/Color.js
@@ -614,6 +614,16 @@
     rgba[3] = alpha;
     return new Common.Color(rgba, Common.Color.Format.RGBA);
   }
+
+  /**
+   * @param {!Common.Color} fgColor
+   * @return {!Common.Color}
+   */
+  blendWith(fgColor) {
+    var rgba = [];
+    Common.Color.blendColors(fgColor._rgba, this._rgba, rgba);
+    return new Common.Color(rgba, Common.Color.Format.RGBA);
+  }
 };
 
 /** @type {!RegExp} */
diff --git a/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js b/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js
index 960c9e1..71ab24c 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js
@@ -117,7 +117,7 @@
 
   link.addEventListener('click', Common.Revealer.reveal.bind(Common.Revealer, node, undefined), false);
   link.addEventListener('mouseover', node.highlight.bind(node, undefined, undefined), false);
-  link.addEventListener('mouseleave', SDK.DOMModel.hideDOMNodeHighlight.bind(SDK.DOMModel), false);
+  link.addEventListener('mouseleave', () => SDK.OverlayModel.hideDOMNodeHighlight(), false);
 
   return root;
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsBreadcrumbs.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsBreadcrumbs.js
index 67bca2f..24a45c6 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsBreadcrumbs.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsBreadcrumbs.js
@@ -56,7 +56,7 @@
 
   _mouseMovedOutOfCrumbs(event) {
     if (this._currentDOMNode)
-      SDK.DOMModel.hideDOMNodeHighlight();
+      SDK.OverlayModel.hideDOMNodeHighlight();
   }
 
 
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
index aba07ef..3f3c33d 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
@@ -330,7 +330,7 @@
   willHide() {
     UI.context.setFlavor(Elements.ElementsPanel, null);
 
-    SDK.DOMModel.hideDOMNodeHighlight();
+    SDK.OverlayModel.hideDOMNodeHighlight();
     for (var i = 0; i < this._treeOutlines.length; ++i) {
       var treeOutline = this._treeOutlines[i];
       treeOutline.setVisible(false);
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElementHighlighter.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElementHighlighter.js
index f8d7034..7b7e454 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElementHighlighter.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElementHighlighter.js
@@ -15,8 +15,9 @@
     this._treeOutline.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._clearState, this);
     this._treeOutline.addEventListener(Elements.ElementsTreeOutline.Events.SelectedNodeChanged, this._clearState, this);
     SDK.targetManager.addModelListener(
-        SDK.DOMModel, SDK.DOMModel.Events.NodeHighlightedInOverlay, this._highlightNode, this);
-    this._treeOutline.domModel().addEventListener(SDK.DOMModel.Events.InspectModeWillBeToggled, this._clearState, this);
+        SDK.OverlayModel, SDK.OverlayModel.Events.HighlightNodeRequested, this._highlightNode, this);
+    this._treeOutline.domModel().overlayModel().addEventListener(
+        SDK.OverlayModel.Events.InspectModeWillBeToggled, this._clearState, this);
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js
index ad4fbca..a0c0471 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js
@@ -620,20 +620,20 @@
     this.setHoverEffect(element);
 
     if (element instanceof Elements.ElementsTreeElement) {
-      this._domModel.highlightDOMNodeWithConfig(
+      this._domModel.overlayModel().highlightDOMNodeWithConfig(
           element.node().id, {mode: 'all', showInfo: !UI.KeyboardShortcut.eventHasCtrlOrMeta(event)});
       return;
     }
 
     if (element instanceof Elements.ElementsTreeOutline.ShortcutTreeElement) {
-      this._domModel.highlightDOMNodeWithConfig(
+      this._domModel.overlayModel().highlightDOMNodeWithConfig(
           undefined, {mode: 'all', showInfo: !UI.KeyboardShortcut.eventHasCtrlOrMeta(event)}, element.backendNodeId());
     }
   }
 
   _onmouseleave(event) {
     this.setHoverEffect(null);
-    SDK.DOMModel.hideDOMNodeHighlight();
+    SDK.OverlayModel.hideDOMNodeHighlight();
   }
 
   _ondragstart(event) {
@@ -653,7 +653,7 @@
     event.dataTransfer.effectAllowed = 'copyMove';
     this._treeElementBeingDragged = treeElement;
 
-    SDK.DOMModel.hideDOMNodeHighlight();
+    SDK.OverlayModel.hideDOMNodeHighlight();
 
     return true;
   }
@@ -971,7 +971,7 @@
     this.selectDOMNode(null, false);
     this._popoverHelper.hidePopover();
     delete this._clipboardNodeData;
-    SDK.DOMModel.hideDOMNodeHighlight();
+    SDK.OverlayModel.hideDOMNodeHighlight();
     this._updateRecords.clear();
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/InspectElementModeController.js b/third_party/WebKit/Source/devtools/front_end/elements/InspectElementModeController.js
index 63fe1ce..0eee986 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/InspectElementModeController.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/InspectElementModeController.js
@@ -26,46 +26,46 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 /**
- * @implements {SDK.SDKModelObserver<!SDK.DOMModel>}
+ * @implements {SDK.SDKModelObserver<!SDK.OverlayModel>}
  * @unrestricted
  */
 Elements.InspectElementModeController = class {
   constructor() {
     this._toggleSearchAction = UI.actionRegistry.action('elements.toggle-element-search');
-    this._mode = Protocol.DOM.InspectMode.None;
+    this._mode = Protocol.Overlay.InspectMode.None;
     SDK.targetManager.addEventListener(SDK.TargetManager.Events.SuspendStateChanged, this._suspendStateChanged, this);
-    SDK.targetManager.observeModels(SDK.DOMModel, this);
+    SDK.targetManager.observeModels(SDK.OverlayModel, this);
   }
 
   /**
    * @override
-   * @param {!SDK.DOMModel} domModel
+   * @param {!SDK.OverlayModel} overlayModel
    */
-  modelAdded(domModel) {
+  modelAdded(overlayModel) {
     // When DevTools are opening in the inspect element mode, the first target comes in
     // much later than the InspectorFrontendAPI.enterInspectElementMode event.
-    if (this._mode === Protocol.DOM.InspectMode.None)
+    if (this._mode === Protocol.Overlay.InspectMode.None)
       return;
-    domModel.setInspectMode(this._mode);
+    overlayModel.setInspectMode(this._mode);
   }
 
   /**
    * @override
-   * @param {!SDK.DOMModel} domModel
+   * @param {!SDK.OverlayModel} overlayModel
    */
-  modelRemoved(domModel) {
+  modelRemoved(overlayModel) {
   }
 
   /**
    * @return {boolean}
    */
   isInInspectElementMode() {
-    return this._mode === Protocol.DOM.InspectMode.SearchForNode ||
-        this._mode === Protocol.DOM.InspectMode.SearchForUAShadowDOM;
+    return this._mode === Protocol.Overlay.InspectMode.SearchForNode ||
+        this._mode === Protocol.Overlay.InspectMode.SearchForUAShadowDOM;
   }
 
   stopInspection() {
-    if (this._mode && this._mode !== Protocol.DOM.InspectMode.None)
+    if (this._mode && this._mode !== Protocol.Overlay.InspectMode.None)
       this._toggleInspectMode();
   }
 
@@ -75,22 +75,22 @@
 
     var mode;
     if (this.isInInspectElementMode()) {
-      mode = Protocol.DOM.InspectMode.None;
+      mode = Protocol.Overlay.InspectMode.None;
     } else {
-      mode = Common.moduleSetting('showUAShadowDOM').get() ? Protocol.DOM.InspectMode.SearchForUAShadowDOM :
-                                                             Protocol.DOM.InspectMode.SearchForNode;
+      mode = Common.moduleSetting('showUAShadowDOM').get() ? Protocol.Overlay.InspectMode.SearchForUAShadowDOM :
+                                                             Protocol.Overlay.InspectMode.SearchForNode;
     }
 
     this._setMode(mode);
   }
 
   /**
-   * @param {!Protocol.DOM.InspectMode} mode
+   * @param {!Protocol.Overlay.InspectMode} mode
    */
   _setMode(mode) {
     this._mode = mode;
-    for (var domModel of SDK.targetManager.models(SDK.DOMModel))
-      domModel.setInspectMode(mode);
+    for (var overlayModel of SDK.targetManager.models(SDK.OverlayModel))
+      overlayModel.setInspectMode(mode);
     this._toggleSearchAction.setToggled(this.isInInspectElementMode());
   }
 
@@ -98,7 +98,7 @@
     if (!SDK.targetManager.allTargetsSuspended())
       return;
 
-    this._mode = Protocol.DOM.InspectMode.None;
+    this._mode = Protocol.Overlay.InspectMode.None;
     this._toggleSearchAction.setToggled(false);
   }
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/MetricsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/elements/MetricsSidebarPane.js
index d9cba702..8e3a2b2 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/MetricsSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/MetricsSidebarPane.js
@@ -124,7 +124,7 @@
       this.node().highlight(mode);
     } else {
       delete this._highlightMode;
-      SDK.DOMModel.hideDOMNodeHighlight();
+      SDK.OverlayModel.hideDOMNodeHighlight();
     }
 
     for (var i = 0; this._boxElements && i < this._boxElements.length; ++i) {
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
index 155b4ca..2c8f9e32 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
@@ -815,7 +815,7 @@
   _onMouseOutSelector() {
     if (this._hoverTimer)
       clearTimeout(this._hoverTimer);
-    SDK.DOMModel.hideDOMNodeHighlight();
+    SDK.OverlayModel.hideDOMNodeHighlight();
   }
 
   _onMouseEnterSelector() {
@@ -825,11 +825,11 @@
   }
 
   _highlight() {
-    SDK.DOMModel.hideDOMNodeHighlight();
+    SDK.OverlayModel.hideDOMNodeHighlight();
     var node = this._parentPane.node();
-    var domModel = node.domModel();
     var selectors = this._style.parentRule ? this._style.parentRule.selectorText() : undefined;
-    domModel.highlightDOMNodeWithConfig(node.id, {mode: 'all', showInfo: undefined, selectors: selectors});
+    node.domModel().overlayModel().highlightDOMNodeWithConfig(
+        node.id, {mode: 'all', showInfo: undefined, selectors: selectors});
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js
index 8f3b059..c56410ef 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js
@@ -472,8 +472,9 @@
               this._uaSetting.get() === Emulation.DeviceModeModel.UA.Mobile,
           this._uaSetting.get() === Emulation.DeviceModeModel.UA.Mobile);
     }
-    if (this._target)
-      this._target.renderingAgent().setShowViewportSizeOnResize(this._type === Emulation.DeviceModeModel.Type.None);
+    var overlayModel = this._target ? this._target.model(SDK.OverlayModel) : null;
+    if (overlayModel)
+      overlayModel.setShowViewportSizeOnResize(this._type === Emulation.DeviceModeModel.Type.None);
     this._updateCallback.call(null);
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeView.js b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeView.js
index 04e9011..828ea98 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeView.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeView.js
@@ -363,9 +363,9 @@
    * @return {!Promise}
    */
   async captureScreenshot() {
-    SDK.DOMModel.muteHighlight();
+    SDK.OverlayModel.muteHighlight();
     var screenshot = await this._model.captureScreenshot(false);
-    SDK.DOMModel.unmuteHighlight();
+    SDK.OverlayModel.unmuteHighlight();
     if (screenshot === null)
       return;
 
@@ -398,9 +398,9 @@
    * @return {!Promise}
    */
   async captureFullSizeScreenshot() {
-    SDK.DOMModel.muteHighlight();
+    SDK.OverlayModel.muteHighlight();
     var screenshot = await this._model.captureScreenshot(true);
-    SDK.DOMModel.unmuteHighlight();
+    SDK.OverlayModel.unmuteHighlight();
     if (screenshot === null)
       return;
 
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/TouchModel.js b/third_party/WebKit/Source/devtools/front_end/emulation/TouchModel.js
index ce997a4..883ccf6 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/TouchModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/TouchModel.js
@@ -54,8 +54,8 @@
     if (this._customTouchEnabled)
       current = {enabled: true, configuration: 'mobile'};
 
-    var domModel = target.model(SDK.DOMModel);
-    var inspectModeEnabled = domModel ? domModel.inspectModeEnabled() : false;
+    var overlayModel = target.model(SDK.OverlayModel);
+    var inspectModeEnabled = overlayModel ? overlayModel.inspectModeEnabled() : false;
     if (inspectModeEnabled)
       current = {enabled: false, configuration: 'mobile'};
 
@@ -107,8 +107,8 @@
    * @param {!Common.Event} event
    */
   _inspectModeToggled(event) {
-    var domModel = /** @type {!SDK.DOMModel} */ (event.data);
-    this._applyToTarget(domModel.target());
+    var overlayModel = /** @type {!SDK.OverlayModel} */ (event.data);
+    this._applyToTarget(overlayModel.target());
   }
 
   /**
@@ -116,9 +116,9 @@
    * @param {!SDK.Target} target
    */
   targetAdded(target) {
-    var domModel = target.model(SDK.DOMModel);
-    if (domModel)
-      domModel.addEventListener(SDK.DOMModel.Events.InspectModeWillBeToggled, this._inspectModeToggled, this);
+    var overlayModel = target.model(SDK.OverlayModel);
+    if (overlayModel)
+      overlayModel.addEventListener(SDK.OverlayModel.Events.InspectModeWillBeToggled, this._inspectModeToggled, this);
     this._applyToTarget(target);
   }
 
@@ -127,9 +127,11 @@
    * @param {!SDK.Target} target
    */
   targetRemoved(target) {
-    var domModel = target.model(SDK.DOMModel);
-    if (domModel)
-      domModel.removeEventListener(SDK.DOMModel.Events.InspectModeWillBeToggled, this._inspectModeToggled, this);
+    var overlayModel = target.model(SDK.OverlayModel);
+    if (overlayModel) {
+      overlayModel.removeEventListener(
+          SDK.OverlayModel.Events.InspectModeWillBeToggled, this._inspectModeToggled, this);
+    }
   }
 };
 
diff --git a/third_party/WebKit/Source/devtools/front_end/layer_viewer/LayerViewHost.js b/third_party/WebKit/Source/devtools/front_end/layer_viewer/LayerViewHost.js
index ff3ac68..7ea875e9 100644
--- a/third_party/WebKit/Source/devtools/front_end/layer_viewer/LayerViewHost.js
+++ b/third_party/WebKit/Source/devtools/front_end/layer_viewer/LayerViewHost.js
@@ -255,6 +255,6 @@
       node.highlightForTwoSeconds();
       return;
     }
-    SDK.DOMModel.hideDOMNodeHighlight();
+    SDK.OverlayModel.hideDOMNodeHighlight();
   }
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js
index 3bde351..72eb0a9 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/Main.js
+++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -197,7 +197,6 @@
     Persistence.persistence =
         new Persistence.Persistence(Workspace.workspace, Bindings.breakpointManager, Workspace.fileSystemMapping);
 
-    new Main.OverlayController();
     new Main.ExecutionContextSelector(SDK.targetManager, UI.context);
     Bindings.blackboxManager = new Bindings.BlackboxManager(Bindings.debuggerWorkspaceBinding);
 
@@ -797,7 +796,8 @@
  */
 Main.Main.InspectedNodeRevealer = class {
   constructor() {
-    SDK.targetManager.addModelListener(SDK.DOMModel, SDK.DOMModel.Events.NodeInspected, this._inspectNode, this);
+    SDK.targetManager.addModelListener(
+        SDK.OverlayModel, SDK.OverlayModel.Events.InspectNodeRequested, this._inspectNode, this);
   }
 
   /**
@@ -933,7 +933,6 @@
    */
   targetAdded(target) {
     this._updateTarget(target);
-    target.renderingAgent().setShowViewportSizeOnResize(true);
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/main/OverlayController.js b/third_party/WebKit/Source/devtools/front_end/main/OverlayController.js
deleted file mode 100644
index e6800ce..0000000
--- a/third_party/WebKit/Source/devtools/front_end/main/OverlayController.js
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Main.OverlayController = class {
-  constructor() {
-    Common.moduleSetting('disablePausedStateOverlay').addChangeListener(this._updateAllOverlays, this);
-    SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._updateOverlay, this);
-    SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerResumed, this._updateOverlay, this);
-    // TODO(dgozman): we should get DebuggerResumed on navigations instead of listening to GlobalObjectCleared.
-    SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.GlobalObjectCleared, this._updateOverlay, this);
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.SuspendStateChanged, this._updateAllOverlays, this);
-  }
-
-  _updateAllOverlays() {
-    for (var debuggerModel of SDK.targetManager.models(SDK.DebuggerModel))
-      this._updateTargetOverlay(debuggerModel);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _updateOverlay(event) {
-    this._updateTargetOverlay(/** @type {!SDK.DebuggerModel} */ (event.data));
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  _updateTargetOverlay(debuggerModel) {
-    if (!debuggerModel.target().hasBrowserCapability())
-      return;
-    var message = debuggerModel.isPaused() && !Common.moduleSetting('disablePausedStateOverlay').get() ?
-        Common.UIString('Paused in debugger') :
-        undefined;
-    debuggerModel.target().pageAgent().configureOverlay(SDK.targetManager.allTargetsSuspended(), message);
-  }
-};
diff --git a/third_party/WebKit/Source/devtools/front_end/main/RenderingOptions.js b/third_party/WebKit/Source/devtools/front_end/main/RenderingOptions.js
index 8613dec..521a8a8 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/RenderingOptions.js
+++ b/third_party/WebKit/Source/devtools/front_end/main/RenderingOptions.js
@@ -36,35 +36,22 @@
     super(true);
     this.registerRequiredCSS('main/renderingOptions.css');
 
-    /** @type {!Map.<string, !Element>} */
-    this._settings = new Map();
-
-    var options = [
-      {
-        label: Common.UIString('Paint Flashing'),
-        subtitle: Common.UIString('Highlights areas of the page (green) that need to be repainted'),
-        setterName: 'setShowPaintRects'
-      },
-      {
-        label: Common.UIString('Layer Borders'),
-        subtitle: Common.UIString('Shows layer borders (orange/olive) and tiles (cyan)'),
-        setterName: 'setShowDebugBorders'
-      },
-      {
-        label: Common.UIString('FPS Meter'),
-        subtitle: Common.UIString('Plots frames per second, frame rate distribution, and GPU memory'),
-        setterName: 'setShowFPSCounter'
-      },
-      {
-        label: Common.UIString('Scrolling Performance Issues'),
-        subtitle: Common.UIString(
+    this._appendCheckbox(
+        Common.UIString('Paint Flashing'),
+        Common.UIString('Highlights areas of the page (green) that need to be repainted'),
+        Common.moduleSetting('showPaintRects'));
+    this._appendCheckbox(
+        Common.UIString('Layer Borders'), Common.UIString('Shows layer borders (orange/olive) and tiles (cyan)'),
+        Common.moduleSetting('showDebugBorders'));
+    this._appendCheckbox(
+        Common.UIString('FPS Meter'),
+        Common.UIString('Plots frames per second, frame rate distribution, and GPU memory'),
+        Common.moduleSetting('showFPSCounter'));
+    this._appendCheckbox(
+        Common.UIString('Scrolling Performance Issues'),
+        Common.UIString(
             'Highlights elements (teal) that can slow down scrolling, including touch & wheel event handlers and other main-thread scrolling situations.'),
-        setterName: 'setShowScrollBottleneckRects'
-      }
-    ];
-    for (var i = 0; i < options.length; i++)
-      this._appendCheckbox(options[i].label, options[i].setterName, options[i].subtitle);
-
+        Common.moduleSetting('showScrollBottleneckRects'));
     this.contentElement.createChild('div').classList.add('panel-section-separator');
 
     var cssMediaSubtitle = Common.UIString('Forces media type for testing print and screen styles');
@@ -80,7 +67,7 @@
     this._mediaSelect.addEventListener('change', this._mediaToggled.bind(this), false);
     this._mediaSelect.disabled = true;
 
-    SDK.targetManager.observeTargets(this, SDK.Target.Capability.Browser);
+    SDK.targetManager.observeTargets(this);
   }
 
   /**
@@ -94,35 +81,21 @@
 
   /**
    * @param {string} label
-   * @param {string} setterName
-   * @param {string=} subtitle
+   * @param {string} subtitle
+   * @param {!Common.Setting} setting
    */
-  _appendCheckbox(label, setterName, subtitle) {
+  _appendCheckbox(label, subtitle, setting) {
     var checkboxLabel = UI.CheckboxLabel.create(label, false, subtitle);
-    this._settings.set(setterName, checkboxLabel.checkboxElement);
-    checkboxLabel.checkboxElement.addEventListener('click', this._settingToggled.bind(this, setterName));
+    UI.SettingsUI.bindCheckbox(checkboxLabel.checkboxElement, setting);
     this.contentElement.appendChild(checkboxLabel);
   }
 
   /**
-   * @param {string} setterName
-   */
-  _settingToggled(setterName) {
-    var enabled = this._settings.get(setterName).checked;
-    for (var target of SDK.targetManager.targets(SDK.Target.Capability.Browser))
-      target.renderingAgent()[setterName](enabled);
-  }
-
-  /**
    * @override
    * @param {!SDK.Target} target
    */
   targetAdded(target) {
-    for (var setterName of this._settings.keysArray()) {
-      if (this._settings.get(setterName).checked)
-        target.renderingAgent()[setterName](true);
-    }
-    if (this._mediaCheckbox.checked)
+    if (this._mediaCheckbox.checked && target.hasBrowserCapability())
       this._applyPrintMediaOverride(target);
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/main/module.json b/third_party/WebKit/Source/devtools/front_end/main/module.json
index 9e5a909..c07180d6 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/main/module.json
@@ -450,7 +450,6 @@
     "scripts": [
         "RenderingOptions.js",
         "SimpleApp.js",
-        "OverlayController.js",
         "GCActionDelegate.js",
         "RequestAppBannerActionDelegate.js",
         "ExecutionContextSelector.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkWaterfallColumn.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkWaterfallColumn.js
index ed370ad2..d20bf03 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/NetworkWaterfallColumn.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkWaterfallColumn.js
@@ -50,12 +50,12 @@
     this._updateRequestID;
 
     var colorUsage = UI.ThemeSupport.ColorUsage;
-    this._rowNavigationRequestColor = UI.themeSupport.patchColor('#def', colorUsage.Background);
-    this._rowStripeColor = UI.themeSupport.patchColor('#f5f5f5', colorUsage.Background);
-    this._rowHoverColor = UI.themeSupport.patchColor(
+    this._rowNavigationRequestColor = UI.themeSupport.patchColorText('#def', colorUsage.Background);
+    this._rowStripeColor = UI.themeSupport.patchColorText('#f5f5f5', colorUsage.Background);
+    this._rowHoverColor = UI.themeSupport.patchColorText(
         '#ebf2fc', /** @type {!UI.ThemeSupport.ColorUsage} */ (colorUsage.Background | colorUsage.Selection));
-    this._parentInitiatorColor = UI.themeSupport.patchColor('hsla(120, 68%, 54%, 0.2)', colorUsage.Background);
-    this._initiatedColor = UI.themeSupport.patchColor('hsla(0, 68%, 54%, 0.2)', colorUsage.Background);
+    this._parentInitiatorColor = UI.themeSupport.patchColorText('hsla(120, 68%, 54%, 0.2)', colorUsage.Background);
+    this._initiatedColor = UI.themeSupport.patchColorText('hsla(0, 68%, 54%, 0.2)', colorUsage.Background);
 
     this.element.addEventListener('mousemove', this._onMouseMove.bind(this), true);
     this.element.addEventListener('mouseleave', event => this._setHoveredNode(null, false), true);
@@ -68,7 +68,7 @@
     /** @type {!Map<!Common.ResourceType, !Network.NetworkWaterfallColumn._LayerStyle>} */
     this._styleForDownloadingResourceType = resourceStyleTuple[1];
 
-    var baseLineColor = UI.themeSupport.patchColor('#a5a5a5', UI.ThemeSupport.ColorUsage.Foreground);
+    var baseLineColor = UI.themeSupport.patchColorText('#a5a5a5', UI.ThemeSupport.ColorUsage.Foreground);
     /** @type {!Network.NetworkWaterfallColumn._LayerStyle} */
     this._wiskerStyle = {borderColor: baseLineColor, lineWidth: 1};
     /** @type {!Network.NetworkWaterfallColumn._LayerStyle} */
@@ -391,7 +391,7 @@
     this._drawLayers(context);
 
     context.save();
-    context.fillStyle = UI.themeSupport.patchColor('#888', UI.ThemeSupport.ColorUsage.Foreground);
+    context.fillStyle = UI.themeSupport.patchColorText('#888', UI.ThemeSupport.ColorUsage.Foreground);
     for (var textData of this._textLayers)
       context.fillText(textData.text, textData.x, textData.y);
     context.restore();
diff --git a/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPopoverHelper.js b/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPopoverHelper.js
index 29c1533..40ed2d4 100644
--- a/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPopoverHelper.js
+++ b/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPopoverHelper.js
@@ -40,7 +40,7 @@
 
   dispose() {
     if (this._resultHighlightedAsDOM)
-      SDK.DOMModel.hideDOMNodeHighlight();
+      SDK.OverlayModel.hideDOMNodeHighlight();
     if (this._linkifier)
       this._linkifier.dispose();
   }
@@ -131,7 +131,7 @@
       var linkifier = null;
       var resultHighlightedAsDOM = false;
       if (result.subtype === 'node') {
-        SDK.DOMModel.highlightObjectAsDOMNode(result);
+        SDK.OverlayModel.highlightObjectAsDOMNode(result);
         resultHighlightedAsDOM = true;
       }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPropertiesSection.js b/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPropertiesSection.js
index f0558a0..abc625e 100644
--- a/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPropertiesSection.js
+++ b/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPropertiesSection.js
@@ -306,8 +306,8 @@
         Common.Revealer.reveal(value);
         event.consume(true);
       }, false);
-      valueElement.addEventListener('mousemove', () => SDK.DOMModel.highlightObjectAsDOMNode(value), false);
-      valueElement.addEventListener('mouseleave', () => SDK.DOMModel.hideDOMNodeHighlight(), false);
+      valueElement.addEventListener('mousemove', () => SDK.OverlayModel.highlightObjectAsDOMNode(value), false);
+      valueElement.addEventListener('mouseleave', () => SDK.OverlayModel.hideDOMNodeHighlight(), false);
       return valueElement;
     }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/perf_ui/FlameChart.js b/third_party/WebKit/Source/devtools/front_end/perf_ui/FlameChart.js
index 4347207..dd67521a 100644
--- a/third_party/WebKit/Source/devtools/front_end/perf_ui/FlameChart.js
+++ b/third_party/WebKit/Source/devtools/front_end/perf_ui/FlameChart.js
@@ -740,7 +740,7 @@
     var defaultFont = '11px ' + Host.fontFamily();
     context.font = defaultFont;
 
-    context.fillStyle = UI.themeSupport.patchColor('#fff', colorUsage.Background);
+    context.fillStyle = UI.themeSupport.patchColorText('#fff', colorUsage.Background);
     forEachGroup.call(this, (offset, index, group) => {
       var paddingHeight = group.style.padding;
       if (paddingHeight < 5)
@@ -750,7 +750,7 @@
     if (groups.length && lastGroupOffset < top + height)
       context.fillRect(0, lastGroupOffset + 2, width, top + height - lastGroupOffset);
 
-    context.strokeStyle = UI.themeSupport.patchColor('#eee', colorUsage.Background);
+    context.strokeStyle = UI.themeSupport.patchColorText('#eee', colorUsage.Background);
     context.beginPath();
     forEachGroup.call(this, (offset, index, group, isFirst) => {
       if (isFirst || group.style.padding < 4)
@@ -794,7 +794,7 @@
     });
     context.restore();
 
-    context.fillStyle = UI.themeSupport.patchColor('#6e6e6e', colorUsage.Foreground);
+    context.fillStyle = UI.themeSupport.patchColorText('#6e6e6e', colorUsage.Foreground);
     context.beginPath();
     forEachGroup.call(this, (offset, index, group) => {
       if (this._isGroupCollapsible(index)) {
@@ -805,7 +805,7 @@
     });
     context.fill();
 
-    context.strokeStyle = UI.themeSupport.patchColor('#ddd', colorUsage.Background);
+    context.strokeStyle = UI.themeSupport.patchColorText('#ddd', colorUsage.Background);
     context.beginPath();
     context.stroke();
 
diff --git a/third_party/WebKit/Source/devtools/front_end/perf_ui/TimelineGrid.js b/third_party/WebKit/Source/devtools/front_end/perf_ui/TimelineGrid.js
index 7d25f63..612cea9 100644
--- a/third_party/WebKit/Source/devtools/front_end/perf_ui/TimelineGrid.js
+++ b/third_party/WebKit/Source/devtools/front_end/perf_ui/TimelineGrid.js
@@ -111,12 +111,13 @@
     var precision = dividersData.precision;
 
     if (headerHeight) {
-      context.fillStyle = UI.themeSupport.patchColor('rgba(255, 255, 255, 0.5)', UI.ThemeSupport.ColorUsage.Background);
+      context.fillStyle =
+          UI.themeSupport.patchColorText('rgba(255, 255, 255, 0.5)', UI.ThemeSupport.ColorUsage.Background);
       context.fillRect(0, 0, width, headerHeight);
     }
 
-    context.fillStyle = UI.themeSupport.patchColor('#333', UI.ThemeSupport.ColorUsage.Foreground);
-    context.strokeStyle = UI.themeSupport.patchColor('rgba(0, 0, 0, 0.1)', UI.ThemeSupport.ColorUsage.Foreground);
+    context.fillStyle = UI.themeSupport.patchColorText('#333', UI.ThemeSupport.ColorUsage.Foreground);
+    context.strokeStyle = UI.themeSupport.patchColorText('rgba(0, 0, 0, 0.1)', UI.ThemeSupport.ColorUsage.Foreground);
     context.textBaseline = 'hanging';
     context.font = '11px ' + Host.fontFamily();
     context.lineWidth = 1;
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/ResourcesSection.js b/third_party/WebKit/Source/devtools/front_end/resources/ResourcesSection.js
index 047cb83..2ffe0362 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/ResourcesSection.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/ResourcesSection.js
@@ -155,18 +155,17 @@
     this._panel.showCategoryView(this.titleAsText());
 
     this.listItemElement.classList.remove('hovered');
-    SDK.DOMModel.hideDOMNodeHighlight();
+    SDK.OverlayModel.hideDOMNodeHighlight();
     return false;
   }
 
   set hovered(hovered) {
     if (hovered) {
       this.listItemElement.classList.add('hovered');
-      var domModel = this._frame.resourceTreeModel().domModel();
-      domModel.highlightFrame(this._frameId);
+      this._frame.resourceTreeModel().domModel().overlayModel().highlightFrame(this._frameId);
     } else {
       this.listItemElement.classList.remove('hovered');
-      SDK.DOMModel.hideDOMNodeHighlight();
+      SDK.OverlayModel.hideDOMNodeHighlight();
     }
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastView.js b/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastView.js
index 91bbe66..a1250e9 100644
--- a/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastView.js
+++ b/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastView.js
@@ -28,7 +28,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 /**
- * @implements {SDK.DOMNodeHighlighter}
+ * @implements {SDK.OverlayModel.Highlighter}
  * @unrestricted
  */
 Screencast.ScreencastView = class extends UI.VBox {
@@ -39,6 +39,7 @@
     super();
     this._screenCaptureModel = screenCaptureModel;
     this._domModel = screenCaptureModel.target().model(SDK.DOMModel);
+    this._overlayModel = screenCaptureModel.target().model(SDK.OverlayModel);
     this._resourceTreeModel = screenCaptureModel.target().model(SDK.ResourceTreeModel);
     this._networkManager = screenCaptureModel.target().model(SDK.NetworkManager);
     this._inputModel = screenCaptureModel.target().model(Screencast.InputModel);
@@ -130,8 +131,8 @@
         Math.floor(Math.min(maxImageDimension, dimensions.height)), undefined, this._screencastFrame.bind(this),
         this._screencastVisibilityChanged.bind(this));
     Emulation.MultitargetTouchModel.instance().setCustomTouchEnabled(true);
-    if (this._domModel)
-      this._domModel.setHighlighter(this);
+    if (this._overlayModel)
+      this._overlayModel.setHighlighter(this);
   }
 
   _stopCasting() {
@@ -140,8 +141,8 @@
     this._isCasting = false;
     this._screenCaptureModel.stopScreencast();
     Emulation.MultitargetTouchModel.instance().setCustomTouchEnabled(false);
-    if (this._domModel)
-      this._domModel.setHighlighter(null);
+    if (this._overlayModel)
+      this._overlayModel.setHighlighter(null);
   }
 
   /**
@@ -245,7 +246,7 @@
         return;
       if (event.type === 'mousemove') {
         this.highlightDOMNode(node, this._inspectModeConfig);
-        this._domModel.nodeHighlightRequested(node.id);
+        this._domModel.overlayModel().nodeHighlightRequested(node.id);
       } else if (event.type === 'click') {
         Common.Revealer.reveal(node);
       }
@@ -316,7 +317,7 @@
   /**
    * @override
    * @param {?SDK.DOMNode} node
-   * @param {?Protocol.DOM.HighlightConfig} config
+   * @param {?Protocol.Overlay.HighlightConfig} config
    * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
    * @param {!Protocol.Runtime.RemoteObjectId=} objectId
    */
@@ -569,14 +570,13 @@
 
   /**
    * @override
-   * @param {!Protocol.DOM.InspectMode} mode
-   * @param {!Protocol.DOM.HighlightConfig} config
-   * @param {function(?Protocol.Error)=} callback
+   * @param {!Protocol.Overlay.InspectMode} mode
+   * @param {!Protocol.Overlay.HighlightConfig} config
+   * @return {!Promise}
    */
-  setInspectMode(mode, config, callback) {
-    this._inspectModeConfig = mode !== Protocol.DOM.InspectMode.None ? config : null;
-    if (callback)
-      callback(null);
+  setInspectMode(mode, config) {
+    this._inspectModeConfig = mode !== Protocol.Overlay.InspectMode.None ? config : null;
+    return Promise.resolve();
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js
index 47b664b9..9eb2626 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js
@@ -840,11 +840,11 @@
    * @param {!Protocol.Runtime.RemoteObjectId=} objectId
    */
   highlight(mode, objectId) {
-    this._domModel.highlightDOMNode(this.id, mode, undefined, objectId);
+    this._domModel.overlayModel().highlightDOMNode(this.id, mode, undefined, objectId);
   }
 
   highlightForTwoSeconds() {
-    this._domModel.highlightDOMNodeForTwoSeconds(this.id);
+    this._domModel.overlayModel().highlightDOMNodeForTwoSeconds(this.id);
   }
 
   /**
@@ -1011,7 +1011,7 @@
 
   highlight() {
     if (this._domModel)
-      this._domModel.highlightDOMNode(undefined, undefined, this._backendNodeId);
+      this._domModel.overlayModel().highlightDOMNode(undefined, undefined, this._backendNodeId);
   }
 };
 
@@ -1068,12 +1068,8 @@
     this._attributeLoadNodeIds = {};
     target.registerDOMDispatcher(new SDK.DOMDispatcher(this));
 
-    this._inspectModeEnabled = false;
     this._runtimeModel = /** @type {!SDK.RuntimeModel} */ (target.model(SDK.RuntimeModel));
 
-    this._defaultHighlighter = new SDK.DefaultDOMNodeHighlighter(this._agent);
-    this._highlighter = this._defaultHighlighter;
-
     this._agent.enable();
   }
 
@@ -1092,26 +1088,10 @@
   }
 
   /**
-   * @param {!SDK.RemoteObject} object
+   * @return {!SDK.OverlayModel}
    */
-  static highlightObjectAsDOMNode(object) {
-    var domModel = object.runtimeModel().target().model(SDK.DOMModel);
-    if (domModel)
-      domModel.highlightDOMNode(undefined, undefined, undefined, object.objectId);
-  }
-
-  static hideDOMNodeHighlight() {
-    for (var domModel of SDK.targetManager.models(SDK.DOMModel))
-      domModel.highlightDOMNode(0);
-  }
-
-  static muteHighlight() {
-    SDK.DOMModel.hideDOMNodeHighlight();
-    SDK.DOMModel._highlightDisabled = true;
-  }
-
-  static unmuteHighlight() {
-    SDK.DOMModel._highlightDisabled = false;
+  overlayModel() {
+    return /** @type {!SDK.OverlayModel} */ (this.target().model(SDK.OverlayModel));
   }
 
   static cancelSearch() {
@@ -1541,14 +1521,6 @@
   }
 
   /**
-   * @param {!Protocol.DOM.BackendNodeId} backendNodeId
-   */
-  _inspectNodeRequested(backendNodeId) {
-    var deferredNode = new SDK.DeferredDOMNode(this.target(), backendNodeId);
-    this.dispatchEventToListeners(SDK.DOMModel.Events.NodeInspected, deferredNode);
-  }
-
-  /**
    * @param {string} query
    * @param {boolean} includeUserAgentShadowDOM
    * @param {function(number)} searchCallback
@@ -1679,107 +1651,6 @@
   }
 
   /**
-   * @param {!Protocol.DOM.NodeId=} nodeId
-   * @param {string=} mode
-   * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
-   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
-   */
-  highlightDOMNode(nodeId, mode, backendNodeId, objectId) {
-    this.highlightDOMNodeWithConfig(nodeId, {mode: mode}, backendNodeId, objectId);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId=} nodeId
-   * @param {!{mode: (string|undefined), showInfo: (boolean|undefined), selectors: (string|undefined)}=} config
-   * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
-   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
-   */
-  highlightDOMNodeWithConfig(nodeId, config, backendNodeId, objectId) {
-    if (SDK.DOMModel._highlightDisabled)
-      return;
-    config = config || {mode: 'all', showInfo: undefined, selectors: undefined};
-    if (this._hideDOMNodeHighlightTimeout) {
-      clearTimeout(this._hideDOMNodeHighlightTimeout);
-      delete this._hideDOMNodeHighlightTimeout;
-    }
-    var highlightConfig = this._buildHighlightConfig(config.mode);
-    if (typeof config.showInfo !== 'undefined')
-      highlightConfig.showInfo = config.showInfo;
-    if (typeof config.selectors !== 'undefined')
-      highlightConfig.selectorList = config.selectors;
-    this._highlighter.highlightDOMNode(this.nodeForId(nodeId || 0), highlightConfig, backendNodeId, objectId);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   */
-  highlightDOMNodeForTwoSeconds(nodeId) {
-    this.highlightDOMNode(nodeId);
-    this._hideDOMNodeHighlightTimeout = setTimeout(SDK.DOMModel.hideDOMNodeHighlight.bind(SDK.DOMModel), 2000);
-  }
-
-  /**
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  highlightFrame(frameId) {
-    if (SDK.DOMModel._highlightDisabled)
-      return;
-    this._highlighter.highlightFrame(frameId);
-  }
-
-  /**
-   * @param {!Protocol.DOM.InspectMode} mode
-   * @param {function(?Protocol.Error)=} callback
-   */
-  setInspectMode(mode, callback) {
-    /**
-     * @this {SDK.DOMModel}
-     */
-    function onDocumentAvailable() {
-      this._inspectModeEnabled = mode !== Protocol.DOM.InspectMode.None;
-      this.dispatchEventToListeners(SDK.DOMModel.Events.InspectModeWillBeToggled, this);
-      this._highlighter.setInspectMode(mode, this._buildHighlightConfig(), callback);
-    }
-    this.requestDocument(onDocumentAvailable.bind(this));
-  }
-
-  /**
-   * @return {boolean}
-   */
-  inspectModeEnabled() {
-    return this._inspectModeEnabled;
-  }
-
-  /**
-   * @param {string=} mode
-   * @return {!Protocol.DOM.HighlightConfig}
-   */
-  _buildHighlightConfig(mode) {
-    mode = mode || 'all';
-    var showRulers = Common.moduleSetting('showMetricsRulers').get();
-    var highlightConfig = {showInfo: mode === 'all', showRulers: showRulers, showExtensionLines: showRulers};
-    if (mode === 'all' || mode === 'content')
-      highlightConfig.contentColor = Common.Color.PageHighlight.Content.toProtocolRGBA();
-
-    if (mode === 'all' || mode === 'padding')
-      highlightConfig.paddingColor = Common.Color.PageHighlight.Padding.toProtocolRGBA();
-
-    if (mode === 'all' || mode === 'border')
-      highlightConfig.borderColor = Common.Color.PageHighlight.Border.toProtocolRGBA();
-
-    if (mode === 'all' || mode === 'margin')
-      highlightConfig.marginColor = Common.Color.PageHighlight.Margin.toProtocolRGBA();
-
-    if (mode === 'all') {
-      highlightConfig.eventTargetColor = Common.Color.PageHighlight.EventTarget.toProtocolRGBA();
-      highlightConfig.shapeColor = Common.Color.PageHighlight.Shape.toProtocolRGBA();
-      highlightConfig.shapeMarginColor = Common.Color.PageHighlight.ShapeMargin.toProtocolRGBA();
-      highlightConfig.displayAsMaterial = true;
-    }
-    return highlightConfig;
-  }
-
-  /**
    * @param {!SDK.DOMNode} node
    * @param {function(?Protocol.Error, ...)=} callback
    * @return {function(...)}
@@ -1819,13 +1690,6 @@
   }
 
   /**
-   * @param {?SDK.DOMNodeHighlighter} highlighter
-   */
-  setHighlighter(highlighter) {
-    this._highlighter = highlighter || this._defaultHighlighter;
-  }
-
-  /**
    * @param {number} x
    * @param {number} y
    * @param {boolean} includeUserAgentShadowDOM
@@ -1900,17 +1764,6 @@
       this._agent.enable(fulfill);
     }
   }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   */
-  nodeHighlightRequested(nodeId) {
-    var node = this.nodeForId(nodeId);
-    if (!node)
-      return;
-
-    this.dispatchEventToListeners(SDK.DOMModel.Events.NodeHighlightedInOverlay, node);
-  }
 };
 
 SDK.SDKModel.register(SDK.DOMModel, SDK.Target.Capability.DOM, true);
@@ -1922,13 +1775,10 @@
   CharacterDataModified: Symbol('CharacterDataModified'),
   DOMMutated: Symbol('DOMMutated'),
   NodeInserted: Symbol('NodeInserted'),
-  NodeInspected: Symbol('NodeInspected'),
-  NodeHighlightedInOverlay: Symbol('NodeHighlightedInOverlay'),
   NodeRemoved: Symbol('NodeRemoved'),
   DocumentUpdated: Symbol('DocumentUpdated'),
   ChildNodeCountUpdated: Symbol('ChildNodeCountUpdated'),
   DistributedNodesChanged: Symbol('DistributedNodesChanged'),
-  InspectModeWillBeToggled: Symbol('InspectModeWillBeToggled'),
   MarkersChanged: Symbol('MarkersChanged')
 };
 
@@ -1955,14 +1805,6 @@
   /**
    * @override
    * @param {!Protocol.DOM.NodeId} nodeId
-   */
-  inspectNodeRequested(nodeId) {
-    this._domModel._inspectNodeRequested(nodeId);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} nodeId
    * @param {string} name
    * @param {string} value
    */
@@ -2077,86 +1919,4 @@
   distributedNodesUpdated(insertionPointId, distributedNodes) {
     this._domModel._distributedNodesUpdated(insertionPointId, distributedNodes);
   }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} nodeId
-   */
-  nodeHighlightRequested(nodeId) {
-    this._domModel.nodeHighlightRequested(nodeId);
-  }
-};
-
-/**
- * @interface
- */
-SDK.DOMNodeHighlighter = function() {};
-
-SDK.DOMNodeHighlighter.prototype = {
-  /**
-   * @param {?SDK.DOMNode} node
-   * @param {!Protocol.DOM.HighlightConfig} config
-   * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
-   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
-   */
-  highlightDOMNode(node, config, backendNodeId, objectId) {},
-
-  /**
-   * @param {!Protocol.DOM.InspectMode} mode
-   * @param {!Protocol.DOM.HighlightConfig} config
-   * @param {function(?Protocol.Error)=} callback
-   */
-  setInspectMode(mode, config, callback) {},
-
-  /**
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  highlightFrame(frameId) {}
-};
-
-/**
- * @implements {SDK.DOMNodeHighlighter}
- * @unrestricted
- */
-SDK.DefaultDOMNodeHighlighter = class {
-  /**
-   * @param {!Protocol.DOMAgent} agent
-   */
-  constructor(agent) {
-    this._agent = agent;
-  }
-
-  /**
-   * @override
-   * @param {?SDK.DOMNode} node
-   * @param {!Protocol.DOM.HighlightConfig} config
-   * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
-   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
-   */
-  highlightDOMNode(node, config, backendNodeId, objectId) {
-    if (objectId || node || backendNodeId)
-      this._agent.highlightNode(config, (objectId || backendNodeId) ? undefined : node.id, backendNodeId, objectId);
-    else
-      this._agent.hideHighlight();
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.InspectMode} mode
-   * @param {!Protocol.DOM.HighlightConfig} config
-   * @param {function(?Protocol.Error)=} callback
-   */
-  setInspectMode(mode, config, callback) {
-    this._agent.setInspectMode(mode, config, callback);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  highlightFrame(frameId) {
-    this._agent.highlightFrame(
-        frameId, Common.Color.PageHighlight.Content.toProtocolRGBA(),
-        Common.Color.PageHighlight.ContentOutline.toProtocolRGBA());
-  }
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/OverlayModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/OverlayModel.js
new file mode 100644
index 0000000..de8d729
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/OverlayModel.js
@@ -0,0 +1,320 @@
+// 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.
+
+/**
+ * @implements {Protocol.OverlayDispatcher}
+ */
+SDK.OverlayModel = class extends SDK.SDKModel {
+  /**
+   * @param {!SDK.Target} target
+   */
+  constructor(target) {
+    super(target);
+    this._domModel = /** @type {!SDK.DOMModel} */ (target.model(SDK.DOMModel));
+
+    target.registerOverlayDispatcher(this);
+    this._overlayAgent = target.overlayAgent();
+    this._overlayAgent.enable();
+    this._overlayAgent.setShowViewportSizeOnResize(true);
+
+    this._debuggerModel = target.model(SDK.DebuggerModel);
+    if (this._debuggerModel) {
+      Common.moduleSetting('disablePausedStateOverlay').addChangeListener(this._updatePausedInDebuggerMessage, this);
+      this._debuggerModel.addEventListener(
+          SDK.DebuggerModel.Events.DebuggerPaused, this._updatePausedInDebuggerMessage, this);
+      this._debuggerModel.addEventListener(
+          SDK.DebuggerModel.Events.DebuggerResumed, this._updatePausedInDebuggerMessage, this);
+      // TODO(dgozman): we should get DebuggerResumed on navigations instead of listening to GlobalObjectCleared.
+      this._debuggerModel.addEventListener(
+          SDK.DebuggerModel.Events.GlobalObjectCleared, this._updatePausedInDebuggerMessage, this);
+    }
+
+    this._inspectModeEnabled = false;
+    this._hideHighlightTimeout = null;
+    this._defaultHighlighter = new SDK.OverlayModel.DefaultHighlighter(this);
+    this._highlighter = this._defaultHighlighter;
+
+    this._showPaintRectsSetting = Common.moduleSetting('showPaintRects');
+    this._showPaintRectsSetting.addChangeListener(
+        () => this._overlayAgent.setShowPaintRects(this._showPaintRectsSetting.get()));
+    if (this._showPaintRectsSetting.get())
+      this._overlayAgent.setShowPaintRects(true);
+
+    this._showDebugBordersSetting = Common.moduleSetting('showDebugBorders');
+    this._showDebugBordersSetting.addChangeListener(
+        () => this._overlayAgent.setShowDebugBorders(this._showDebugBordersSetting.get()));
+    if (this._showDebugBordersSetting.get())
+      this._overlayAgent.setShowDebugBorders(true);
+
+    this._showFPSCounterSetting = Common.moduleSetting('showFPSCounter');
+    this._showFPSCounterSetting.addChangeListener(
+        () => this._overlayAgent.setShowFPSCounter(this._showFPSCounterSetting.get()));
+    if (this._showFPSCounterSetting.get())
+      this._overlayAgent.setShowFPSCounter(true);
+
+    this._showScrollBottleneckRectsSetting = Common.moduleSetting('showScrollBottleneckRects');
+    this._showScrollBottleneckRectsSetting.addChangeListener(
+        () => this._overlayAgent.setShowScrollBottleneckRects(this._showScrollBottleneckRectsSetting.get()));
+    if (this._showScrollBottleneckRectsSetting.get())
+      this._overlayAgent.setShowScrollBottleneckRects(true);
+  }
+
+  /**
+   * @param {!SDK.RemoteObject} object
+   */
+  static highlightObjectAsDOMNode(object) {
+    var domModel = object.runtimeModel().target().model(SDK.DOMModel);
+    if (domModel)
+      domModel.overlayModel().highlightDOMNode(undefined, undefined, undefined, object.objectId);
+  }
+
+  static hideDOMNodeHighlight() {
+    for (var overlayModel of SDK.targetManager.models(SDK.OverlayModel))
+      overlayModel.highlightDOMNode(0);
+  }
+
+  static muteHighlight() {
+    SDK.OverlayModel.hideDOMNodeHighlight();
+    SDK.OverlayModel._highlightDisabled = true;
+  }
+
+  static unmuteHighlight() {
+    SDK.OverlayModel._highlightDisabled = false;
+  }
+
+  /**
+   * @override
+   * @return {!Promise}
+   */
+  suspendModel() {
+    return this._overlayAgent.setSuspended(true);
+  }
+
+  /**
+   * @override
+   * @return {!Promise}
+   */
+  resumeModel() {
+    return this._overlayAgent.setSuspended(false);
+  }
+
+  setShowViewportSizeOnResize(show) {
+    this._overlayAgent.setShowViewportSizeOnResize(show);
+  }
+
+  _updatePausedInDebuggerMessage() {
+    var message = this._debuggerModel.isPaused() && !Common.moduleSetting('disablePausedStateOverlay').get() ?
+        Common.UIString('Paused in debugger') :
+        undefined;
+    this._overlayAgent.setPausedInDebuggerMessage(message);
+  }
+
+  /**
+   * @param {?SDK.OverlayModel.Highlighter} highlighter
+   */
+  setHighlighter(highlighter) {
+    this._highlighter = highlighter || this._defaultHighlighter;
+  }
+
+  /**
+   * @param {!Protocol.Overlay.InspectMode} mode
+   * @return {!Promise}
+   */
+  setInspectMode(mode) {
+    var requestDocumentPromise = new Promise(fulfill => this._domModel.requestDocument(fulfill));
+    return requestDocumentPromise.then(() => {
+      this._inspectModeEnabled = mode !== Protocol.Overlay.InspectMode.None;
+      this.dispatchEventToListeners(SDK.OverlayModel.Events.InspectModeWillBeToggled, this);
+      return this._highlighter.setInspectMode(mode, this._buildHighlightConfig());
+    });
+  }
+
+  /**
+   * @return {boolean}
+   */
+  inspectModeEnabled() {
+    return this._inspectModeEnabled;
+  }
+
+  /**
+   * @param {!Protocol.DOM.NodeId=} nodeId
+   * @param {string=} mode
+   * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
+   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
+   */
+  highlightDOMNode(nodeId, mode, backendNodeId, objectId) {
+    this.highlightDOMNodeWithConfig(nodeId, {mode: mode}, backendNodeId, objectId);
+  }
+
+  /**
+   * @param {!Protocol.DOM.NodeId=} nodeId
+   * @param {!{mode: (string|undefined), showInfo: (boolean|undefined), selectors: (string|undefined)}=} config
+   * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
+   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
+   */
+  highlightDOMNodeWithConfig(nodeId, config, backendNodeId, objectId) {
+    if (SDK.OverlayModel._highlightDisabled)
+      return;
+    config = config || {mode: 'all', showInfo: undefined, selectors: undefined};
+    if (this._hideHighlightTimeout) {
+      clearTimeout(this._hideHighlightTimeout);
+      this._hideHighlightTimeout = null;
+    }
+    var highlightConfig = this._buildHighlightConfig(config.mode);
+    if (typeof config.showInfo !== 'undefined')
+      highlightConfig.showInfo = config.showInfo;
+    if (typeof config.selectors !== 'undefined')
+      highlightConfig.selectorList = config.selectors;
+    this._highlighter.highlightDOMNode(this._domModel.nodeForId(nodeId || 0), highlightConfig, backendNodeId, objectId);
+  }
+
+  /**
+   * @param {!Protocol.DOM.NodeId} nodeId
+   */
+  highlightDOMNodeForTwoSeconds(nodeId) {
+    this.highlightDOMNode(nodeId);
+    this._hideHighlightTimeout = setTimeout(() => this.highlightDOMNode(0), 2000);
+  }
+
+  /**
+   * @param {!Protocol.Page.FrameId} frameId
+   */
+  highlightFrame(frameId) {
+    if (SDK.OverlayModel._highlightDisabled)
+      return;
+    this._highlighter.highlightFrame(frameId);
+  }
+
+  /**
+   * @param {string=} mode
+   * @return {!Protocol.Overlay.HighlightConfig}
+   */
+  _buildHighlightConfig(mode) {
+    mode = mode || 'all';
+    var showRulers = Common.moduleSetting('showMetricsRulers').get();
+    var highlightConfig = {showInfo: mode === 'all', showRulers: showRulers, showExtensionLines: showRulers};
+    if (mode === 'all' || mode === 'content')
+      highlightConfig.contentColor = Common.Color.PageHighlight.Content.toProtocolRGBA();
+
+    if (mode === 'all' || mode === 'padding')
+      highlightConfig.paddingColor = Common.Color.PageHighlight.Padding.toProtocolRGBA();
+
+    if (mode === 'all' || mode === 'border')
+      highlightConfig.borderColor = Common.Color.PageHighlight.Border.toProtocolRGBA();
+
+    if (mode === 'all' || mode === 'margin')
+      highlightConfig.marginColor = Common.Color.PageHighlight.Margin.toProtocolRGBA();
+
+    if (mode === 'all') {
+      highlightConfig.eventTargetColor = Common.Color.PageHighlight.EventTarget.toProtocolRGBA();
+      highlightConfig.shapeColor = Common.Color.PageHighlight.Shape.toProtocolRGBA();
+      highlightConfig.shapeMarginColor = Common.Color.PageHighlight.ShapeMargin.toProtocolRGBA();
+      highlightConfig.displayAsMaterial = true;
+    }
+    return highlightConfig;
+  }
+
+  /**
+   * @override
+   * @param {!Protocol.DOM.NodeId} nodeId
+   */
+  nodeHighlightRequested(nodeId) {
+    var node = this._domModel.nodeForId(nodeId);
+    if (node)
+      this.dispatchEventToListeners(SDK.OverlayModel.Events.HighlightNodeRequested, node);
+  }
+
+  /**
+   * @override
+   * @param {!Protocol.DOM.BackendNodeId} backendNodeId
+   */
+  inspectNodeRequested(backendNodeId) {
+    var deferredNode = new SDK.DeferredDOMNode(this.target(), backendNodeId);
+    this.dispatchEventToListeners(SDK.OverlayModel.Events.InspectNodeRequested, deferredNode);
+  }
+};
+
+SDK.SDKModel.register(SDK.OverlayModel, SDK.Target.Capability.DOM, true);
+
+/** @enum {symbol} */
+SDK.OverlayModel.Events = {
+  InspectModeWillBeToggled: Symbol('InspectModeWillBeToggled'),
+  HighlightNodeRequested: Symbol('HighlightNodeRequested'),
+  InspectNodeRequested: Symbol('InspectNodeRequested'),
+};
+
+/**
+ * @interface
+ */
+SDK.OverlayModel.Highlighter = function() {};
+
+SDK.OverlayModel.Highlighter.prototype = {
+  /**
+   * @param {?SDK.DOMNode} node
+   * @param {!Protocol.Overlay.HighlightConfig} config
+   * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
+   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
+   */
+  highlightDOMNode(node, config, backendNodeId, objectId) {},
+
+  /**
+   * @param {!Protocol.Overlay.InspectMode} mode
+   * @param {!Protocol.Overlay.HighlightConfig} config
+   * @return {!Promise}
+   */
+  setInspectMode(mode, config) {},
+
+  /**
+   * @param {!Protocol.Page.FrameId} frameId
+   */
+  highlightFrame(frameId) {}
+};
+
+/**
+ * @implements {SDK.OverlayModel.Highlighter}
+ */
+SDK.OverlayModel.DefaultHighlighter = class {
+  /**
+   * @param {!SDK.OverlayModel} model
+   */
+  constructor(model) {
+    this._model = model;
+  }
+
+  /**
+   * @override
+   * @param {?SDK.DOMNode} node
+   * @param {!Protocol.Overlay.HighlightConfig} config
+   * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
+   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
+   */
+  highlightDOMNode(node, config, backendNodeId, objectId) {
+    if (objectId || node || backendNodeId) {
+      this._model._overlayAgent.highlightNode(
+          config, (objectId || backendNodeId) ? undefined : node.id, backendNodeId, objectId);
+    } else {
+      this._model._overlayAgent.hideHighlight();
+    }
+  }
+
+  /**
+   * @override
+   * @param {!Protocol.Overlay.InspectMode} mode
+   * @param {!Protocol.Overlay.HighlightConfig} config
+   * @return {!Promise}
+   */
+  setInspectMode(mode, config) {
+    return this._model._overlayAgent.setInspectMode(mode, config);
+  }
+
+  /**
+   * @override
+   * @param {!Protocol.Page.FrameId} frameId
+   */
+  highlightFrame(frameId) {
+    this._model._overlayAgent.highlightFrame(
+        frameId, Common.Color.PageHighlight.Content.toProtocolRGBA(),
+        Common.Color.PageHighlight.ContentOutline.toProtocolRGBA());
+  }
+};
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/module.json b/third_party/WebKit/Source/devtools/front_end/sdk/module.json
index 8bb5fab..e4c2be3 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/module.json
@@ -84,6 +84,34 @@
         },
         {
             "type": "setting",
+            "settingName": "showPaintRects",
+            "settingType": "boolean",
+            "storageType": "session",
+            "defaultValue": false
+        },
+        {
+            "type": "setting",
+            "settingName": "showDebugBorders",
+            "settingType": "boolean",
+            "storageType": "session",
+            "defaultValue": false
+        },
+        {
+            "type": "setting",
+            "settingName": "showFPSCounter",
+            "settingType": "boolean",
+            "storageType": "session",
+            "defaultValue": false
+        },
+        {
+            "type": "setting",
+            "settingName": "showScrollBottleneckRects",
+            "settingType": "boolean",
+            "storageType": "session",
+            "defaultValue": false
+        },
+        {
+            "type": "setting",
             "category": "Console",
             "title": "Enable custom formatters",
             "settingName": "customFormatters",
@@ -137,6 +165,7 @@
         "ServiceWorkerManager.js",
         "TracingManager.js",
         "TracingModel.js",
+        "OverlayModel.js",
         "RuntimeModel.js",
         "ScreenCaptureModel.js",
         "Script.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
index a1ce9bf7..6d4c06d 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
@@ -436,11 +436,11 @@
      */
     function hoverCallback(hovered) {
       if (hovered) {
-        var domModel = target.model(SDK.DOMModel);
-        if (domModel)
-          domModel.highlightFrame(frame.id);
+        var overlayModel = target.model(SDK.OverlayModel);
+        if (overlayModel)
+          overlayModel.highlightFrame(frame.id);
       } else {
-        SDK.DOMModel.hideDOMNodeHighlight();
+        SDK.OverlayModel.hideDOMNodeHighlight();
       }
     }
     return frameNode;
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js
index be44c2e..c29d53583 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js
@@ -57,8 +57,8 @@
       padding: 4,
       height: 17,
       collapsible: true,
-      color: UI.themeSupport.patchColor('#222', UI.ThemeSupport.ColorUsage.Foreground),
-      backgroundColor: UI.themeSupport.patchColor('white', UI.ThemeSupport.ColorUsage.Background),
+      color: UI.themeSupport.patchColorText('#222', UI.ThemeSupport.ColorUsage.Foreground),
+      backgroundColor: UI.themeSupport.patchColorText('white', UI.ThemeSupport.ColorUsage.Background),
       font: this._font,
       nestingLevel: 0,
       shareHeaderLine: true
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartNetworkDataProvider.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartNetworkDataProvider.js
index d066c15..60c966bd 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartNetworkDataProvider.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartNetworkDataProvider.js
@@ -14,9 +14,9 @@
       padding: 4,
       height: 17,
       collapsible: true,
-      color: UI.themeSupport.patchColor('#222', UI.ThemeSupport.ColorUsage.Foreground),
+      color: UI.themeSupport.patchColorText('#222', UI.ThemeSupport.ColorUsage.Foreground),
       font: this._font,
-      backgroundColor: UI.themeSupport.patchColor('white', UI.ThemeSupport.ColorUsage.Background),
+      backgroundColor: UI.themeSupport.patchColorText('white', UI.ThemeSupport.ColorUsage.Background),
       nestingLevel: 0,
       useFirstLineForOverview: false,
       useDecoratorsForOverview: true,
@@ -205,7 +205,7 @@
 
     context.fillStyle = 'hsla(0, 100%, 100%, 0.8)';
     context.fillRect(sendStart + 0.5, barY + 0.5, headersEnd - sendStart - 0.5, barHeight - 2);
-    context.fillStyle = UI.themeSupport.patchColor('white', UI.ThemeSupport.ColorUsage.Background);
+    context.fillStyle = UI.themeSupport.patchColorText('white', UI.ThemeSupport.ColorUsage.Background);
     context.fillRect(barX, barY - 0.5, sendStart - barX, barHeight);
     context.fillRect(finish, barY - 0.5, barX + barWidth - finish, barHeight);
 
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js
index 8a1df75..81d5220 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js
@@ -154,7 +154,7 @@
    * @param {!Common.Event} commonEvent
    */
   _onEntryHighlighted(commonEvent) {
-    SDK.DOMModel.hideDOMNodeHighlight();
+    SDK.OverlayModel.hideDOMNodeHighlight();
     var entryIndex = /** @type {number} */ (commonEvent.data);
     var event = this._mainDataProvider.eventByIndex(entryIndex);
     if (!event)
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
index 48b5d1db..7f114a2 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
@@ -1852,7 +1852,7 @@
     output.push(':');
     var items = value.replace(Common.Color.Regex, '\0$1\0').split('\0');
     for (var i = 0; i < items.length; ++i)
-      output.push(this.patchColor(items[i], colorUsage));
+      output.push(this.patchColorText(items[i], colorUsage));
     if (style.getPropertyPriority(name))
       output.push(' !important');
     output.push(';');
@@ -1863,16 +1863,11 @@
    * @param {!UI.ThemeSupport.ColorUsage} colorUsage
    * @return {string}
    */
-  patchColor(text, colorUsage) {
+  patchColorText(text, colorUsage) {
     var color = Common.Color.parse(text);
     if (!color)
       return text;
-
-    var hsla = color.hsla();
-    this._patchHSLA(hsla, colorUsage);
-    var rgba = [];
-    Common.Color.hsl2rgb(hsla, rgba);
-    var outColor = new Common.Color(rgba, color.format());
+    var outColor = this.patchColor(color, colorUsage);
     var outText = outColor.asString(null);
     if (!outText)
       outText = outColor.asString(outColor.hasAlpha() ? Common.Color.Format.RGBA : Common.Color.Format.RGB);
@@ -1880,6 +1875,19 @@
   }
 
   /**
+   * @param {!Common.Color} color
+   * @param {!UI.ThemeSupport.ColorUsage} colorUsage
+   * @return {!Common.Color}
+   */
+  patchColor(color, colorUsage) {
+    var hsla = color.hsla();
+    this._patchHSLA(hsla, colorUsage);
+    var rgba = [];
+    Common.Color.hsl2rgb(hsla, rgba);
+    return new Common.Color(rgba, color.format());
+  }
+
+  /**
    * @param {!Array<number>} hsla
    * @param {!UI.ThemeSupport.ColorUsage} colorUsage
    */
diff --git a/third_party/WebKit/Source/devtools/scripts/build/generate_protocol_externs.py b/third_party/WebKit/Source/devtools/scripts/build/generate_protocol_externs.py
index e81d9796..a231f09e 100755
--- a/third_party/WebKit/Source/devtools/scripts/build/generate_protocol_externs.py
+++ b/third_party/WebKit/Source/devtools/scripts/build/generate_protocol_externs.py
@@ -53,6 +53,7 @@
     "DOMDebugger",
     "Emulation",
     "HeapProfiler",
+    "Overlay",
     "Page",
     "Profiler",
     "LayerTree",
diff --git a/third_party/WebKit/Source/modules/accessibility/AXInlineTextBox.cpp b/third_party/WebKit/Source/modules/accessibility/AXInlineTextBox.cpp
index 8b8e12d..8658ffc 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXInlineTextBox.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXInlineTextBox.cpp
@@ -101,7 +101,7 @@
   unsigned len = inline_text_box_->Len();
   Vector<float> widths;
   inline_text_box_->CharacterWidths(widths);
-  DCHECK(widths.size() == len);
+  DCHECK_EQ(widths.size(), len);
   offsets.Resize(len);
 
   float width_so_far = 0;
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
index ce2fc51..20d7b43 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
@@ -1781,9 +1781,9 @@
     return AXRange();
 
   int anchor_offset = anchor_object->IndexForVisiblePosition(visible_start);
-  DCHECK(anchor_offset >= 0);
+  DCHECK_GE(anchor_offset, 0);
   int focus_offset = focus_object->IndexForVisiblePosition(visible_end);
-  DCHECK(focus_offset >= 0);
+  DCHECK_GE(focus_offset, 0);
   return AXRange(anchor_object, anchor_offset, start_affinity, focus_object,
                  focus_offset, end_affinity);
 }
@@ -1818,9 +1818,9 @@
   }
 
   int start = IndexForVisiblePosition(selection.VisibleStart());
-  DCHECK(start >= 0);
+  DCHECK_GE(start, 0);
   int end = IndexForVisiblePosition(selection.VisibleEnd());
-  DCHECK(end >= 0);
+  DCHECK_GE(end, 0);
 
   return AXRange(start, end);
 }
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
index ac90d6f2..a256d1c 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
@@ -2208,7 +2208,7 @@
     for (size_t i = 0; i < length; ++i)
       children_.insert(index + i, children[i]);
   } else {
-    DCHECK(child->ParentObject() == this);
+    DCHECK_EQ(child->ParentObject(), this);
     children_.insert(index, child);
   }
 }
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp b/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp
index c3d401c..9d73c06 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp
@@ -473,7 +473,7 @@
   if (!objects_.Take(ax_id))
     return;
 
-  DCHECK(objects_.size() >= ids_in_use_.size());
+  DCHECK_GE(objects_.size(), ids_in_use_.size());
 }
 
 void AXObjectCacheImpl::Remove(LayoutObject* layout_object) {
diff --git a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
index bbeb7d5..4a5d14a0 100644
--- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
@@ -9,8 +9,8 @@
 #include "bindings/core/v8/ScriptState.h"
 #include "core/css/cssom/CSSURLImageValue.h"
 #include "core/css/parser/CSSParser.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/ExecutionContext.h"
-#include "core/dom/NotShared.h"
 #include "core/frame/ImageBitmap.h"
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/HTMLImageElement.h"
diff --git a/third_party/WebKit/Source/modules/encoding/TextEncoder.h b/third_party/WebKit/Source/modules/encoding/TextEncoder.h
index 538fffb..093a0e0 100644
--- a/third_party/WebKit/Source/modules/encoding/TextEncoder.h
+++ b/third_party/WebKit/Source/modules/encoding/TextEncoder.h
@@ -33,8 +33,8 @@
 
 #include <memory>
 #include "bindings/core/v8/ScriptWrappable.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/text/TextCodec.h"
 #include "platform/wtf/text/TextEncoding.h"
diff --git a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.h b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.h
index 6647c0c..85d17374 100644
--- a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.h
+++ b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.h
@@ -33,7 +33,7 @@
 
 #include <memory>
 #include "bindings/core/v8/ActiveScriptWrappable.h"
-#include "core/dom/NotShared.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/SuspendableObject.h"
 #include "modules/EventTargetModules.h"
 #include "modules/mediasource/TrackDefaultList.h"
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCDataChannel.h b/third_party/WebKit/Source/modules/peerconnection/RTCDataChannel.h
index 3692b1e..7084e54 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCDataChannel.h
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCDataChannel.h
@@ -28,7 +28,7 @@
 #include <memory>
 #include "base/gtest_prod_util.h"
 #include "bindings/core/v8/ActiveScriptWrappable.h"
-#include "core/dom/NotShared.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/SuspendableObject.h"
 #include "modules/EventTargetModules.h"
 #include "platform/Timer.h"
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationConnection.h b/third_party/WebKit/Source/modules/presentation/PresentationConnection.h
index 13346e5..96cc031 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationConnection.h
+++ b/third_party/WebKit/Source/modules/presentation/PresentationConnection.h
@@ -6,8 +6,8 @@
 #define PresentationConnection_h
 
 #include <memory>
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/ContextLifecycleObserver.h"
-#include "core/dom/NotShared.h"
 #include "core/events/EventTarget.h"
 #include "core/fileapi/Blob.h"
 #include "core/fileapi/FileError.h"
diff --git a/third_party/WebKit/Source/modules/webaudio/AnalyserNode.h b/third_party/WebKit/Source/modules/webaudio/AnalyserNode.h
index e124487..6dafb45 100644
--- a/third_party/WebKit/Source/modules/webaudio/AnalyserNode.h
+++ b/third_party/WebKit/Source/modules/webaudio/AnalyserNode.h
@@ -26,8 +26,8 @@
 #ifndef AnalyserNode_h
 #define AnalyserNode_h
 
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "modules/webaudio/AudioBasicInspectorNode.h"
 #include "modules/webaudio/RealtimeAnalyser.h"
 
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioBuffer.h b/third_party/WebKit/Source/modules/webaudio/AudioBuffer.h
index f42219520..0216c8aca 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioBuffer.h
+++ b/third_party/WebKit/Source/modules/webaudio/AudioBuffer.h
@@ -30,8 +30,8 @@
 #define AudioBuffer_h
 
 #include "bindings/core/v8/ScriptWrappable.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "modules/ModulesExport.h"
 #include "platform/wtf/PassRefPtr.h"
 #include "platform/wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParam.h b/third_party/WebKit/Source/modules/webaudio/AudioParam.h
index beaef99d..9dee605 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioParam.h
+++ b/third_party/WebKit/Source/modules/webaudio/AudioParam.h
@@ -31,8 +31,8 @@
 
 #include <sys/types.h>
 #include "bindings/core/v8/ScriptWrappable.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "modules/webaudio/AudioParamTimeline.h"
 #include "modules/webaudio/AudioSummingJunction.h"
 #include "modules/webaudio/BaseAudioContext.h"
diff --git a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h
index eaa1be1..67b43b0 100644
--- a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h
+++ b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h
@@ -29,8 +29,8 @@
 #include "bindings/core/v8/ActiveScriptWrappable.h"
 #include "bindings/core/v8/ScriptPromise.h"
 #include "bindings/core/v8/ScriptPromiseResolver.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "core/dom/SuspendableObject.h"
 #include "core/events/EventListener.h"
 #include "modules/EventTargetModules.h"
diff --git a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.h b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.h
index b83c5c7..c56cc51 100644
--- a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.h
+++ b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.h
@@ -26,8 +26,8 @@
 #ifndef BiquadFilterNode_h
 #define BiquadFilterNode_h
 
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "modules/webaudio/AudioNode.h"
 #include "modules/webaudio/BiquadProcessor.h"
 
diff --git a/third_party/WebKit/Source/modules/webaudio/IIRFilterNode.h b/third_party/WebKit/Source/modules/webaudio/IIRFilterNode.h
index 826bd67a..019c3f5d 100644
--- a/third_party/WebKit/Source/modules/webaudio/IIRFilterNode.h
+++ b/third_party/WebKit/Source/modules/webaudio/IIRFilterNode.h
@@ -5,8 +5,8 @@
 #ifndef IIRFilterNode_h
 #define IIRFilterNode_h
 
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "modules/webaudio/AudioNode.h"
 #include "modules/webaudio/IIRProcessor.h"
 
diff --git a/third_party/WebKit/Source/modules/webaudio/PeriodicWave.h b/third_party/WebKit/Source/modules/webaudio/PeriodicWave.h
index 44404f5..126eab1 100644
--- a/third_party/WebKit/Source/modules/webaudio/PeriodicWave.h
+++ b/third_party/WebKit/Source/modules/webaudio/PeriodicWave.h
@@ -31,8 +31,8 @@
 
 #include <memory>
 #include "bindings/core/v8/ScriptWrappable.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "platform/audio/AudioArray.h"
 #include "platform/wtf/Forward.h"
 #include "platform/wtf/Vector.h"
diff --git a/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.h b/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.h
index 3773781..eb2b044 100644
--- a/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.h
+++ b/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.h
@@ -26,8 +26,8 @@
 #ifndef WaveShaperNode_h
 #define WaveShaperNode_h
 
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "modules/webaudio/AudioNode.h"
 #include "modules/webaudio/WaveShaperProcessor.h"
 
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
index c0ae1b65..8806042 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
@@ -73,7 +73,7 @@
   if (!byte_length) {
     byte_length = view->byteLength() - byte_offset;
   }
-  uint8_t* data = static_cast<uint8_t*>(view->BaseAddress());
+  uint8_t* data = static_cast<uint8_t*>(view->BaseAddressMaybeShared());
   data += byte_offset;
   *out_base_address = data;
   *out_byte_length = byte_length;
@@ -250,7 +250,7 @@
 
 void WebGL2RenderingContextBase::bufferData(
     GLenum target,
-    NotShared<DOMArrayBufferView> src_data,
+    MaybeShared<DOMArrayBufferView> src_data,
     GLenum usage,
     GLuint src_offset,
     GLuint length) {
@@ -279,16 +279,17 @@
   WebGLRenderingContextBase::bufferData(target, data, usage);
 }
 
-void WebGL2RenderingContextBase::bufferData(GLenum target,
-                                            NotShared<DOMArrayBufferView> data,
-                                            GLenum usage) {
+void WebGL2RenderingContextBase::bufferData(
+    GLenum target,
+    MaybeShared<DOMArrayBufferView> data,
+    GLenum usage) {
   WebGLRenderingContextBase::bufferData(target, data, usage);
 }
 
 void WebGL2RenderingContextBase::bufferSubData(
     GLenum target,
     GLintptr dst_byte_offset,
-    NotShared<DOMArrayBufferView> src_data,
+    MaybeShared<DOMArrayBufferView> src_data,
     GLuint src_offset,
     GLuint length) {
   if (isContextLost())
@@ -370,7 +371,7 @@
 void WebGL2RenderingContextBase::getBufferSubData(
     GLenum target,
     long long src_byte_offset,
-    NotShared<DOMArrayBufferView> dst_data,
+    MaybeShared<DOMArrayBufferView> dst_data,
     GLuint dst_offset,
     GLuint length) {
   WebGLBuffer* source_buffer = nullptr;
@@ -759,7 +760,7 @@
     GLsizei height,
     GLenum format,
     GLenum type,
-    NotShared<DOMArrayBufferView> pixels) {
+    MaybeShared<DOMArrayBufferView> pixels) {
   if (isContextLost())
     return;
   if (bound_pixel_pack_buffer_.Get()) {
@@ -778,7 +779,7 @@
     GLsizei height,
     GLenum format,
     GLenum type,
-    NotShared<DOMArrayBufferView> pixels,
+    MaybeShared<DOMArrayBufferView> pixels,
     GLuint offset) {
   if (isContextLost())
     return;
@@ -1139,7 +1140,7 @@
     GLint border,
     GLenum format,
     GLenum type,
-    NotShared<DOMArrayBufferView> data) {
+    MaybeShared<DOMArrayBufferView> data) {
   if (isContextLost())
     return;
   if (bound_pixel_unpack_buffer_) {
@@ -1151,16 +1152,17 @@
                                         height, border, format, type, data);
 }
 
-void WebGL2RenderingContextBase::texImage2D(GLenum target,
-                                            GLint level,
-                                            GLint internalformat,
-                                            GLsizei width,
-                                            GLsizei height,
-                                            GLint border,
-                                            GLenum format,
-                                            GLenum type,
-                                            NotShared<DOMArrayBufferView> data,
-                                            GLuint src_offset) {
+void WebGL2RenderingContextBase::texImage2D(
+    GLenum target,
+    GLint level,
+    GLint internalformat,
+    GLsizei width,
+    GLsizei height,
+    GLint border,
+    GLenum format,
+    GLenum type,
+    MaybeShared<DOMArrayBufferView> data,
+    GLuint src_offset) {
   if (isContextLost())
     return;
   if (bound_pixel_unpack_buffer_) {
@@ -1400,7 +1402,7 @@
     GLsizei height,
     GLenum format,
     GLenum type,
-    NotShared<DOMArrayBufferView> pixels) {
+    MaybeShared<DOMArrayBufferView> pixels) {
   if (isContextLost())
     return;
   if (bound_pixel_unpack_buffer_) {
@@ -1421,7 +1423,7 @@
     GLsizei height,
     GLenum format,
     GLenum type,
-    NotShared<DOMArrayBufferView> pixels,
+    MaybeShared<DOMArrayBufferView> pixels,
     GLuint src_offset) {
   if (isContextLost())
     return;
@@ -1697,7 +1699,7 @@
     GLint border,
     GLenum format,
     GLenum type,
-    NotShared<DOMArrayBufferView> pixels) {
+    MaybeShared<DOMArrayBufferView> pixels) {
   TexImageHelperDOMArrayBufferView(kTexImage3D, target, level, internalformat,
                                    width, height, depth, border, format, type,
                                    0, 0, 0, pixels.View(), kNullAllowed, 0);
@@ -1713,7 +1715,7 @@
     GLint border,
     GLenum format,
     GLenum type,
-    NotShared<DOMArrayBufferView> pixels,
+    MaybeShared<DOMArrayBufferView> pixels,
     GLuint src_offset) {
   if (isContextLost())
     return;
@@ -1895,7 +1897,7 @@
     GLsizei depth,
     GLenum format,
     GLenum type,
-    NotShared<DOMArrayBufferView> pixels,
+    MaybeShared<DOMArrayBufferView> pixels,
     GLuint src_offset) {
   if (isContextLost())
     return;
@@ -2110,7 +2112,7 @@
     GLsizei width,
     GLsizei height,
     GLint border,
-    NotShared<DOMArrayBufferView> data) {
+    MaybeShared<DOMArrayBufferView> data) {
   if (isContextLost())
     return;
   if (bound_pixel_unpack_buffer_) {
@@ -2129,7 +2131,7 @@
     GLsizei width,
     GLsizei height,
     GLint border,
-    NotShared<DOMArrayBufferView> data,
+    MaybeShared<DOMArrayBufferView> data,
     GLuint src_offset,
     GLuint src_length_override) {
   if (isContextLost())
@@ -2157,7 +2159,8 @@
   }
   ContextGL()->CompressedTexImage2D(
       target, level, internalformat, width, height, border, src_length_override,
-      static_cast<uint8_t*>(data.View()->BaseAddress()) + src_offset);
+      static_cast<uint8_t*>(data.View()->BaseAddressMaybeShared()) +
+          src_offset);
 }
 
 void WebGL2RenderingContextBase::compressedTexImage2D(GLenum target,
@@ -2188,7 +2191,7 @@
     GLsizei width,
     GLsizei height,
     GLenum format,
-    NotShared<DOMArrayBufferView> data) {
+    MaybeShared<DOMArrayBufferView> data) {
   if (isContextLost())
     return;
   if (bound_pixel_unpack_buffer_) {
@@ -2208,7 +2211,7 @@
     GLsizei width,
     GLsizei height,
     GLenum format,
-    NotShared<DOMArrayBufferView> data,
+    MaybeShared<DOMArrayBufferView> data,
     GLuint src_offset,
     GLuint src_length_override) {
   if (isContextLost())
@@ -2237,7 +2240,8 @@
   ContextGL()->CompressedTexSubImage2D(
       target, level, xoffset, yoffset, width, height, format,
       src_length_override,
-      static_cast<uint8_t*>(data.View()->BaseAddress()) + src_offset);
+      static_cast<uint8_t*>(data.View()->BaseAddressMaybeShared()) +
+          src_offset);
 }
 
 void WebGL2RenderingContextBase::compressedTexSubImage2D(GLenum target,
@@ -2269,7 +2273,7 @@
     GLsizei height,
     GLsizei depth,
     GLint border,
-    NotShared<DOMArrayBufferView> data,
+    MaybeShared<DOMArrayBufferView> data,
     GLuint src_offset,
     GLuint src_length_override) {
   if (isContextLost())
@@ -2298,7 +2302,8 @@
   ContextGL()->CompressedTexImage3D(
       target, level, internalformat, width, height, depth, border,
       src_length_override,
-      static_cast<uint8_t*>(data.View()->BaseAddress()) + src_offset);
+      static_cast<uint8_t*>(data.View()->BaseAddressMaybeShared()) +
+          src_offset);
 }
 
 void WebGL2RenderingContextBase::compressedTexImage3D(GLenum target,
@@ -2332,7 +2337,7 @@
     GLsizei height,
     GLsizei depth,
     GLenum format,
-    NotShared<DOMArrayBufferView> data,
+    MaybeShared<DOMArrayBufferView> data,
     GLuint src_offset,
     GLuint src_length_override) {
   if (isContextLost())
@@ -2361,7 +2366,8 @@
   ContextGL()->CompressedTexSubImage3D(
       target, level, xoffset, yoffset, zoffset, width, height, depth, format,
       src_length_override,
-      static_cast<uint8_t*>(data.View()->BaseAddress()) + src_offset);
+      static_cast<uint8_t*>(data.View()->BaseAddressMaybeShared()) +
+          src_offset);
 }
 
 void WebGL2RenderingContextBase::compressedTexSubImage3D(GLenum target,
@@ -2844,7 +2850,7 @@
 void WebGL2RenderingContextBase::uniformMatrix2fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> v,
+    MaybeShared<DOMFloat32Array> v,
     GLuint src_offset,
     GLuint src_length) {
   if (isContextLost() ||
@@ -2854,7 +2860,7 @@
   ContextGL()->UniformMatrix2fv(
       location->Location(),
       (src_length ? src_length : (v.View()->length() - src_offset)) >> 2,
-      transpose, v.View()->Data() + src_offset);
+      transpose, v.View()->DataMaybeShared() + src_offset);
 }
 
 void WebGL2RenderingContextBase::uniformMatrix2fv(
@@ -2876,7 +2882,7 @@
 void WebGL2RenderingContextBase::uniformMatrix3fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> v,
+    MaybeShared<DOMFloat32Array> v,
     GLuint src_offset,
     GLuint src_length) {
   if (isContextLost() ||
@@ -2886,7 +2892,7 @@
   ContextGL()->UniformMatrix3fv(
       location->Location(),
       (src_length ? src_length : (v.View()->length() - src_offset)) / 9,
-      transpose, v.View()->Data() + src_offset);
+      transpose, v.View()->DataMaybeShared() + src_offset);
 }
 
 void WebGL2RenderingContextBase::uniformMatrix3fv(
@@ -2908,7 +2914,7 @@
 void WebGL2RenderingContextBase::uniformMatrix4fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> v,
+    MaybeShared<DOMFloat32Array> v,
     GLuint src_offset,
     GLuint src_length) {
   if (isContextLost() ||
@@ -2918,7 +2924,7 @@
   ContextGL()->UniformMatrix4fv(
       location->Location(),
       (src_length ? src_length : (v.View()->length() - src_offset)) >> 4,
-      transpose, v.View()->Data() + src_offset);
+      transpose, v.View()->DataMaybeShared() + src_offset);
 }
 
 void WebGL2RenderingContextBase::uniformMatrix4fv(
@@ -2940,7 +2946,7 @@
 void WebGL2RenderingContextBase::uniformMatrix2x3fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> value,
+    MaybeShared<DOMFloat32Array> value,
     GLuint src_offset,
     GLuint src_length) {
   if (isContextLost() || !ValidateUniformMatrixParameters(
@@ -2950,7 +2956,7 @@
   ContextGL()->UniformMatrix2x3fv(
       location->Location(),
       (src_length ? src_length : (value.View()->length() - src_offset)) / 6,
-      transpose, value.View()->Data() + src_offset);
+      transpose, value.View()->DataMaybeShared() + src_offset);
 }
 
 void WebGL2RenderingContextBase::uniformMatrix2x3fv(
@@ -2973,7 +2979,7 @@
 void WebGL2RenderingContextBase::uniformMatrix3x2fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> value,
+    MaybeShared<DOMFloat32Array> value,
     GLuint src_offset,
     GLuint src_length) {
   if (isContextLost() || !ValidateUniformMatrixParameters(
@@ -2983,7 +2989,7 @@
   ContextGL()->UniformMatrix3x2fv(
       location->Location(),
       (src_length ? src_length : (value.View()->length() - src_offset)) / 6,
-      transpose, value.View()->Data() + src_offset);
+      transpose, value.View()->DataMaybeShared() + src_offset);
 }
 
 void WebGL2RenderingContextBase::uniformMatrix3x2fv(
@@ -3006,7 +3012,7 @@
 void WebGL2RenderingContextBase::uniformMatrix2x4fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> value,
+    MaybeShared<DOMFloat32Array> value,
     GLuint src_offset,
     GLuint src_length) {
   if (isContextLost() || !ValidateUniformMatrixParameters(
@@ -3016,7 +3022,7 @@
   ContextGL()->UniformMatrix2x4fv(
       location->Location(),
       (src_length ? src_length : (value.View()->length() - src_offset)) >> 3,
-      transpose, value.View()->Data() + src_offset);
+      transpose, value.View()->DataMaybeShared() + src_offset);
 }
 
 void WebGL2RenderingContextBase::uniformMatrix2x4fv(
@@ -3039,7 +3045,7 @@
 void WebGL2RenderingContextBase::uniformMatrix4x2fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> value,
+    MaybeShared<DOMFloat32Array> value,
     GLuint src_offset,
     GLuint src_length) {
   if (isContextLost() || !ValidateUniformMatrixParameters(
@@ -3049,7 +3055,7 @@
   ContextGL()->UniformMatrix4x2fv(
       location->Location(),
       (src_length ? src_length : (value.View()->length() - src_offset)) >> 3,
-      transpose, value.View()->Data() + src_offset);
+      transpose, value.View()->DataMaybeShared() + src_offset);
 }
 
 void WebGL2RenderingContextBase::uniformMatrix4x2fv(
@@ -3072,7 +3078,7 @@
 void WebGL2RenderingContextBase::uniformMatrix3x4fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> value,
+    MaybeShared<DOMFloat32Array> value,
     GLuint src_offset,
     GLuint src_length) {
   if (isContextLost() || !ValidateUniformMatrixParameters(
@@ -3082,7 +3088,7 @@
   ContextGL()->UniformMatrix3x4fv(
       location->Location(),
       (src_length ? src_length : (value.View()->length() - src_offset)) / 12,
-      transpose, value.View()->Data() + src_offset);
+      transpose, value.View()->DataMaybeShared() + src_offset);
 }
 
 void WebGL2RenderingContextBase::uniformMatrix3x4fv(
@@ -3105,7 +3111,7 @@
 void WebGL2RenderingContextBase::uniformMatrix4x3fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> value,
+    MaybeShared<DOMFloat32Array> value,
     GLuint src_offset,
     GLuint src_length) {
   if (isContextLost() || !ValidateUniformMatrixParameters(
@@ -3115,7 +3121,7 @@
   ContextGL()->UniformMatrix4x3fv(
       location->Location(),
       (src_length ? src_length : (value.View()->length() - src_offset)) / 12,
-      transpose, value.View()->Data() + src_offset);
+      transpose, value.View()->DataMaybeShared() + src_offset);
 }
 
 void WebGL2RenderingContextBase::uniformMatrix4x3fv(
@@ -3234,7 +3240,7 @@
 void WebGL2RenderingContextBase::uniformMatrix2fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> v) {
+    MaybeShared<DOMFloat32Array> v) {
   WebGLRenderingContextBase::uniformMatrix2fv(location, transpose, v);
 }
 
@@ -3248,7 +3254,7 @@
 void WebGL2RenderingContextBase::uniformMatrix3fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> v) {
+    MaybeShared<DOMFloat32Array> v) {
   WebGLRenderingContextBase::uniformMatrix3fv(location, transpose, v);
 }
 
@@ -3262,7 +3268,7 @@
 void WebGL2RenderingContextBase::uniformMatrix4fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> v) {
+    MaybeShared<DOMFloat32Array> v) {
   WebGLRenderingContextBase::uniformMatrix4fv(location, transpose, v);
 }
 
@@ -3286,14 +3292,14 @@
 
 void WebGL2RenderingContextBase::vertexAttribI4iv(
     GLuint index,
-    NotShared<const DOMInt32Array> v) {
+    MaybeShared<const DOMInt32Array> v) {
   if (isContextLost())
     return;
   if (!v.View() || v.View()->length() < 4) {
     SynthesizeGLError(GL_INVALID_VALUE, "vertexAttribI4iv", "invalid array");
     return;
   }
-  ContextGL()->VertexAttribI4iv(index, v.View()->Data());
+  ContextGL()->VertexAttribI4iv(index, v.View()->DataMaybeShared());
   SetVertexAttribType(index, kInt32ArrayType);
 }
 
@@ -3322,14 +3328,14 @@
 
 void WebGL2RenderingContextBase::vertexAttribI4uiv(
     GLuint index,
-    NotShared<const DOMUint32Array> v) {
+    MaybeShared<const DOMUint32Array> v) {
   if (isContextLost())
     return;
   if (!v.View() || v.View()->length() < 4) {
     SynthesizeGLError(GL_INVALID_VALUE, "vertexAttribI4uiv", "invalid array");
     return;
   }
-  ContextGL()->VertexAttribI4uiv(index, v.View()->Data());
+  ContextGL()->VertexAttribI4uiv(index, v.View()->DataMaybeShared());
   SetVertexAttribType(index, kUint32ArrayType);
 }
 
@@ -3555,7 +3561,7 @@
 
 void WebGL2RenderingContextBase::clearBufferiv(GLenum buffer,
                                                GLint drawbuffer,
-                                               NotShared<DOMInt32Array> value,
+                                               MaybeShared<DOMInt32Array> value,
                                                GLuint src_offset) {
   if (isContextLost() ||
       !ValidateClearBuffer("clearBufferiv", buffer, value.View()->length(),
@@ -3563,7 +3569,7 @@
     return;
 
   ContextGL()->ClearBufferiv(buffer, drawbuffer,
-                             value.View()->Data() + src_offset);
+                             value.View()->DataMaybeShared() + src_offset);
 }
 
 void WebGL2RenderingContextBase::clearBufferiv(GLenum buffer,
@@ -3577,17 +3583,18 @@
   ContextGL()->ClearBufferiv(buffer, drawbuffer, value.Data() + src_offset);
 }
 
-void WebGL2RenderingContextBase::clearBufferuiv(GLenum buffer,
-                                                GLint drawbuffer,
-                                                NotShared<DOMUint32Array> value,
-                                                GLuint src_offset) {
+void WebGL2RenderingContextBase::clearBufferuiv(
+    GLenum buffer,
+    GLint drawbuffer,
+    MaybeShared<DOMUint32Array> value,
+    GLuint src_offset) {
   if (isContextLost() ||
       !ValidateClearBuffer("clearBufferuiv", buffer, value.View()->length(),
                            src_offset))
     return;
 
   ContextGL()->ClearBufferuiv(buffer, drawbuffer,
-                              value.View()->Data() + src_offset);
+                              value.View()->DataMaybeShared() + src_offset);
 }
 
 void WebGL2RenderingContextBase::clearBufferuiv(GLenum buffer,
@@ -3601,17 +3608,18 @@
   ContextGL()->ClearBufferuiv(buffer, drawbuffer, value.Data() + src_offset);
 }
 
-void WebGL2RenderingContextBase::clearBufferfv(GLenum buffer,
-                                               GLint drawbuffer,
-                                               NotShared<DOMFloat32Array> value,
-                                               GLuint src_offset) {
+void WebGL2RenderingContextBase::clearBufferfv(
+    GLenum buffer,
+    GLint drawbuffer,
+    MaybeShared<DOMFloat32Array> value,
+    GLuint src_offset) {
   if (isContextLost() ||
       !ValidateClearBuffer("clearBufferfv", buffer, value.View()->length(),
                            src_offset))
     return;
 
   ContextGL()->ClearBufferfv(buffer, drawbuffer,
-                             value.View()->Data() + src_offset);
+                             value.View()->DataMaybeShared() + src_offset);
 }
 
 void WebGL2RenderingContextBase::clearBufferfv(GLenum buffer,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h
index f7a951c..ea72408 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h
@@ -32,13 +32,13 @@
 
   /* Buffer objects */
   void bufferData(GLenum,
-                  NotShared<DOMArrayBufferView>,
+                  MaybeShared<DOMArrayBufferView>,
                   GLenum,
                   GLuint,
                   GLuint);
   void bufferSubData(GLenum,
                      GLintptr,
-                     NotShared<DOMArrayBufferView>,
+                     MaybeShared<DOMArrayBufferView>,
                      GLuint,
                      GLuint);
   // Have to re-declare/re-define the following buffer{Sub}Data functions from
@@ -47,7 +47,7 @@
   void bufferData(GLenum target, long long size, GLenum usage);
   void bufferData(GLenum target, DOMArrayBuffer* data, GLenum usage);
   void bufferData(GLenum target,
-                  NotShared<DOMArrayBufferView> data,
+                  MaybeShared<DOMArrayBufferView> data,
                   GLenum usage);
   void bufferSubData(GLenum target, long long offset, DOMArrayBuffer* data);
   void bufferSubData(GLenum target,
@@ -57,7 +57,7 @@
   void copyBufferSubData(GLenum, GLenum, long long, long long, long long);
   void getBufferSubData(GLenum,
                         long long,
-                        NotShared<DOMArrayBufferView>,
+                        MaybeShared<DOMArrayBufferView>,
                         GLuint,
                         GLuint);
 
@@ -166,7 +166,7 @@
                   GLint,
                   GLenum,
                   GLenum,
-                  NotShared<DOMArrayBufferView>,
+                  MaybeShared<DOMArrayBufferView>,
                   GLuint);
 
   void texSubImage2D(GLenum,
@@ -238,7 +238,7 @@
                      GLsizei,
                      GLenum,
                      GLenum,
-                     NotShared<DOMArrayBufferView>,
+                     MaybeShared<DOMArrayBufferView>,
                      GLuint);
 
   // Have to re-declare/re-define the following tex{Sub}Image2D functions from
@@ -324,7 +324,7 @@
                   GLint,
                   GLenum,
                   GLenum,
-                  NotShared<DOMArrayBufferView>);
+                  MaybeShared<DOMArrayBufferView>);
   void texImage3D(GLenum,
                   GLint,
                   GLint,
@@ -334,7 +334,7 @@
                   GLint,
                   GLenum,
                   GLenum,
-                  NotShared<DOMArrayBufferView>,
+                  MaybeShared<DOMArrayBufferView>,
                   GLuint);
   void texImage3D(GLenum,
                   GLint,
@@ -413,7 +413,7 @@
                      GLsizei,
                      GLenum,
                      GLenum,
-                     NotShared<DOMArrayBufferView>,
+                     MaybeShared<DOMArrayBufferView>,
                      GLuint);
   void texSubImage3D(GLenum,
                      GLint,
@@ -497,7 +497,7 @@
                   GLint,
                   GLenum,
                   GLenum,
-                  NotShared<DOMArrayBufferView>);
+                  MaybeShared<DOMArrayBufferView>);
   void texSubImage2D(GLenum,
                      GLint,
                      GLint,
@@ -506,7 +506,7 @@
                      GLsizei,
                      GLenum,
                      GLenum,
-                     NotShared<DOMArrayBufferView>);
+                     MaybeShared<DOMArrayBufferView>);
 
   void copyTexSubImage3D(GLenum,
                          GLint,
@@ -524,7 +524,7 @@
                             GLsizei width,
                             GLsizei height,
                             GLint border,
-                            NotShared<DOMArrayBufferView> data,
+                            MaybeShared<DOMArrayBufferView> data,
                             GLuint src_offset,
                             GLuint src_length_override);
   void compressedTexSubImage2D(GLenum target,
@@ -534,7 +534,7 @@
                                GLsizei width,
                                GLsizei height,
                                GLenum format,
-                               NotShared<DOMArrayBufferView> data,
+                               MaybeShared<DOMArrayBufferView> data,
                                GLuint src_offset,
                                GLuint src_length_override);
   void compressedTexImage3D(GLenum,
@@ -544,7 +544,7 @@
                             GLsizei,
                             GLsizei,
                             GLint,
-                            NotShared<DOMArrayBufferView>,
+                            MaybeShared<DOMArrayBufferView>,
                             GLuint,
                             GLuint);
   void compressedTexSubImage3D(GLenum,
@@ -556,7 +556,7 @@
                                GLsizei,
                                GLsizei,
                                GLenum,
-                               NotShared<DOMArrayBufferView>,
+                               MaybeShared<DOMArrayBufferView>,
                                GLuint,
                                GLuint);
   void compressedTexImage2D(GLenum target,
@@ -606,7 +606,7 @@
                             GLsizei width,
                             GLsizei height,
                             GLint border,
-                            NotShared<DOMArrayBufferView> data);
+                            MaybeShared<DOMArrayBufferView> data);
   void compressedTexSubImage2D(GLenum target,
                                GLint level,
                                GLint xoffset,
@@ -614,7 +614,7 @@
                                GLsizei width,
                                GLsizei height,
                                GLenum format,
-                               NotShared<DOMArrayBufferView> data);
+                               MaybeShared<DOMArrayBufferView> data);
 
   /* Programs and shaders */
   GLint getFragDataLocation(WebGLProgram*, const String&);
@@ -710,7 +710,7 @@
                    GLuint);
   void uniformMatrix2fv(const WebGLUniformLocation*,
                         GLboolean,
-                        NotShared<DOMFloat32Array>,
+                        MaybeShared<DOMFloat32Array>,
                         GLuint,
                         GLuint);
   void uniformMatrix2fv(const WebGLUniformLocation*,
@@ -720,7 +720,7 @@
                         GLuint);
   void uniformMatrix3fv(const WebGLUniformLocation*,
                         GLboolean,
-                        NotShared<DOMFloat32Array>,
+                        MaybeShared<DOMFloat32Array>,
                         GLuint,
                         GLuint);
   void uniformMatrix3fv(const WebGLUniformLocation*,
@@ -730,7 +730,7 @@
                         GLuint);
   void uniformMatrix4fv(const WebGLUniformLocation*,
                         GLboolean,
-                        NotShared<DOMFloat32Array>,
+                        MaybeShared<DOMFloat32Array>,
                         GLuint,
                         GLuint);
   void uniformMatrix4fv(const WebGLUniformLocation*,
@@ -740,7 +740,7 @@
                         GLuint);
   void uniformMatrix2x3fv(const WebGLUniformLocation*,
                           GLboolean,
-                          NotShared<DOMFloat32Array>,
+                          MaybeShared<DOMFloat32Array>,
                           GLuint,
                           GLuint);
   void uniformMatrix2x3fv(const WebGLUniformLocation*,
@@ -750,7 +750,7 @@
                           GLuint);
   void uniformMatrix3x2fv(const WebGLUniformLocation*,
                           GLboolean,
-                          NotShared<DOMFloat32Array>,
+                          MaybeShared<DOMFloat32Array>,
                           GLuint,
                           GLuint);
   void uniformMatrix3x2fv(const WebGLUniformLocation*,
@@ -760,7 +760,7 @@
                           GLuint);
   void uniformMatrix2x4fv(const WebGLUniformLocation*,
                           GLboolean,
-                          NotShared<DOMFloat32Array>,
+                          MaybeShared<DOMFloat32Array>,
                           GLuint,
                           GLuint);
   void uniformMatrix2x4fv(const WebGLUniformLocation*,
@@ -770,7 +770,7 @@
                           GLuint);
   void uniformMatrix4x2fv(const WebGLUniformLocation*,
                           GLboolean,
-                          NotShared<DOMFloat32Array>,
+                          MaybeShared<DOMFloat32Array>,
                           GLuint,
                           GLuint);
   void uniformMatrix4x2fv(const WebGLUniformLocation*,
@@ -780,7 +780,7 @@
                           GLuint);
   void uniformMatrix3x4fv(const WebGLUniformLocation*,
                           GLboolean,
-                          NotShared<DOMFloat32Array>,
+                          MaybeShared<DOMFloat32Array>,
                           GLuint,
                           GLuint);
   void uniformMatrix3x4fv(const WebGLUniformLocation*,
@@ -790,7 +790,7 @@
                           GLuint);
   void uniformMatrix4x3fv(const WebGLUniformLocation*,
                           GLboolean,
-                          NotShared<DOMFloat32Array>,
+                          MaybeShared<DOMFloat32Array>,
                           GLuint,
                           GLuint);
   void uniformMatrix4x3fv(const WebGLUniformLocation*,
@@ -819,28 +819,28 @@
   void uniform4iv(const WebGLUniformLocation*, Vector<GLint>&);
   void uniformMatrix2fv(const WebGLUniformLocation*,
                         GLboolean transpose,
-                        NotShared<DOMFloat32Array> value);
+                        MaybeShared<DOMFloat32Array> value);
   void uniformMatrix2fv(const WebGLUniformLocation*,
                         GLboolean transpose,
                         Vector<GLfloat>& value);
   void uniformMatrix3fv(const WebGLUniformLocation*,
                         GLboolean transpose,
-                        NotShared<DOMFloat32Array> value);
+                        MaybeShared<DOMFloat32Array> value);
   void uniformMatrix3fv(const WebGLUniformLocation*,
                         GLboolean transpose,
                         Vector<GLfloat>& value);
   void uniformMatrix4fv(const WebGLUniformLocation*,
                         GLboolean transpose,
-                        NotShared<DOMFloat32Array> value);
+                        MaybeShared<DOMFloat32Array> value);
   void uniformMatrix4fv(const WebGLUniformLocation*,
                         GLboolean transpose,
                         Vector<GLfloat>& value);
 
   void vertexAttribI4i(GLuint, GLint, GLint, GLint, GLint);
-  void vertexAttribI4iv(GLuint, NotShared<const DOMInt32Array>);
+  void vertexAttribI4iv(GLuint, MaybeShared<const DOMInt32Array>);
   void vertexAttribI4iv(GLuint, const Vector<GLint>&);
   void vertexAttribI4ui(GLuint, GLuint, GLuint, GLuint, GLuint);
-  void vertexAttribI4uiv(GLuint, NotShared<const DOMUint32Array>);
+  void vertexAttribI4uiv(GLuint, MaybeShared<const DOMUint32Array>);
   void vertexAttribI4uiv(GLuint, const Vector<GLuint>&);
   void vertexAttribIPointer(GLuint index,
                             GLint size,
@@ -861,11 +861,11 @@
 
   /* Multiple Render Targets */
   void drawBuffers(const Vector<GLenum>&);
-  void clearBufferiv(GLenum, GLint, NotShared<DOMInt32Array>, GLuint);
+  void clearBufferiv(GLenum, GLint, MaybeShared<DOMInt32Array>, GLuint);
   void clearBufferiv(GLenum, GLint, const Vector<GLint>&, GLuint);
-  void clearBufferuiv(GLenum, GLint, NotShared<DOMUint32Array>, GLuint);
+  void clearBufferuiv(GLenum, GLint, MaybeShared<DOMUint32Array>, GLuint);
   void clearBufferuiv(GLenum, GLint, const Vector<GLuint>&, GLuint);
-  void clearBufferfv(GLenum, GLint, NotShared<DOMFloat32Array>, GLuint);
+  void clearBufferfv(GLenum, GLint, MaybeShared<DOMFloat32Array>, GLuint);
   void clearBufferfv(GLenum, GLint, const Vector<GLfloat>&, GLuint);
   void clearBufferfi(GLenum, GLint, GLfloat, GLint);
 
@@ -940,7 +940,7 @@
                   GLsizei height,
                   GLenum format,
                   GLenum type,
-                  NotShared<DOMArrayBufferView> pixels,
+                  MaybeShared<DOMArrayBufferView> pixels,
                   GLuint offset);
   void readPixels(GLint x,
                   GLint y,
@@ -969,7 +969,7 @@
                   GLsizei height,
                   GLenum format,
                   GLenum type,
-                  NotShared<DOMArrayBufferView> pixels) override;
+                  MaybeShared<DOMArrayBufferView> pixels) override;
   void RestoreCurrentFramebuffer() override;
 
   DECLARE_VIRTUAL_TRACE();
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.idl b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.idl
index 8e793999..5a822d2 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.idl
@@ -277,10 +277,10 @@
     const GLenum MAX_CLIENT_WAIT_TIMEOUT_WEBGL                 = 0x9247;
 
     /* Buffer objects */
-    void bufferData(GLenum target, ArrayBufferView srcData, GLenum usage, GLuint srcOffset, optional GLuint length = 0);
-    void bufferSubData(GLenum target, GLintptr dstByteOffset, ArrayBufferView srcData, GLuint srcOffset, optional GLuint length = 0);
+    void bufferData(GLenum target, [AllowShared] ArrayBufferView srcData, GLenum usage, GLuint srcOffset, optional GLuint length = 0);
+    void bufferSubData(GLenum target, GLintptr dstByteOffset, [AllowShared] ArrayBufferView srcData, GLuint srcOffset, optional GLuint length = 0);
     void copyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
-    void getBufferSubData(GLenum target, GLintptr srcByteOffset, ArrayBufferView dstData, optional GLuint dstOffset = 0, optional GLuint length = 0);
+    void getBufferSubData(GLenum target, GLintptr srcByteOffset, [AllowShared] ArrayBufferView dstData, optional GLuint dstOffset = 0, optional GLuint length = 0);
 
     /* Framebuffer objects */
     void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
@@ -300,14 +300,14 @@
     [CallWith=ExecutionContext, RaisesException] void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, HTMLCanvasElement canvas);
     [CallWith=ExecutionContext,RaisesException] void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, HTMLVideoElement video);
     [RaisesException] void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ImageBitmap bitmap);
-    void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ArrayBufferView srcData, GLuint srcOffset);
+    void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, GLuint srcOffset);
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLintptr offset);
     void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, ImageData data);
     [CallWith=ExecutionContext, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, HTMLImageElement image);
     [CallWith=ExecutionContext, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, HTMLCanvasElement canvas);
     [CallWith=ExecutionContext, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, HTMLVideoElement video);
     [RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, ImageBitmap bitmap);
-    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView srcData, GLuint srcOffset);
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, GLuint srcOffset);
     void texStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
     void texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
     void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLintptr offset);
@@ -316,28 +316,28 @@
     [CallWith=ExecutionContext, RaisesException] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, HTMLCanvasElement canvas);
     [CallWith=ExecutionContext, RaisesException] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, HTMLVideoElement video);
     [RaisesException] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, ImageBitmap bitmap);
-    void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
-    void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, ArrayBufferView pixels, GLuint srcOffset);
+    void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels);
+    void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView pixels, GLuint srcOffset);
     void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLintptr offset);
     void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, ImageData data);
     [CallWith=ExecutionContext, RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, HTMLImageElement image);
     [CallWith=ExecutionContext, RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, HTMLCanvasElement canvas);
     [CallWith=ExecutionContext, RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, HTMLVideoElement video);
     [RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, ImageBitmap bitmap);
-    void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, ArrayBufferView pixels, optional GLuint srcOffset = 0);
+    void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, [AllowShared] ArrayBufferView pixels, optional GLuint srcOffset = 0);
 
     void copyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
 
     void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
                               GLsizei width, GLsizei height, GLint border,
-                              ArrayBufferView data, GLuint srcOffset,
+                              [AllowShared] ArrayBufferView data, GLuint srcOffset,
                               optional GLuint srcLengthOverride = 0);
     void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
                                  GLsizei width, GLsizei height, GLenum format,
-                                 ArrayBufferView data, GLuint srcOffset,
+                                 [AllowShared] ArrayBufferView data, GLuint srcOffset,
                                  optional GLuint srcLengthOverride = 0);
-    void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, ArrayBufferView data, optional GLuint srcOffset = 0, optional GLuint srcLengthOverride = 0);
-    void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, ArrayBufferView data, optional GLuint srcOffset = 0, optional GLuint srcLengthOverride = 0);
+    void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, [AllowShared] ArrayBufferView data, optional GLuint srcOffset = 0, optional GLuint srcLengthOverride = 0);
+    void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, [AllowShared] ArrayBufferView data, optional GLuint srcOffset = 0, optional GLuint srcLengthOverride = 0);
 
     void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
                               GLsizei width, GLsizei height, GLint border,
@@ -412,48 +412,48 @@
                      optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
     void uniform4uiv(WebGLUniformLocation? location, sequence<GLuint> v,
                      optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
-    void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array,
+    void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, [AllowShared] Float32Array array,
                           GLuint srcOffset, optional GLuint srcLength = 0);
     void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> array,
                           GLuint srcOffset, optional GLuint srcLength = 0);
-    void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array,
+    void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, [AllowShared] Float32Array array,
                           GLuint srcOffset, optional GLuint srcLength = 0);
     void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> array,
                           GLuint srcOffset, optional GLuint srcLength = 0);
-    void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array,
+    void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, [AllowShared] Float32Array array,
                           GLuint srcOffset, optional GLuint srcLength = 0);
     void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> array,
                           GLuint srcOffset, optional GLuint srcLength = 0);
-    void uniformMatrix2x3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value,
+    void uniformMatrix2x3fv(WebGLUniformLocation? location, GLboolean transpose, [AllowShared] Float32Array value,
                             optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
     void uniformMatrix2x3fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> value,
                             optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
-    void uniformMatrix3x2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value,
+    void uniformMatrix3x2fv(WebGLUniformLocation? location, GLboolean transpose, [AllowShared] Float32Array value,
                             optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
     void uniformMatrix3x2fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> value,
                             optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
-    void uniformMatrix2x4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value,
+    void uniformMatrix2x4fv(WebGLUniformLocation? location, GLboolean transpose, [AllowShared] Float32Array value,
                             optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
     void uniformMatrix2x4fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> value,
                             optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
-    void uniformMatrix4x2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value,
+    void uniformMatrix4x2fv(WebGLUniformLocation? location, GLboolean transpose, [AllowShared] Float32Array value,
                             optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
     void uniformMatrix4x2fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> value,
                             optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
-    void uniformMatrix3x4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value,
+    void uniformMatrix3x4fv(WebGLUniformLocation? location, GLboolean transpose, [AllowShared] Float32Array value,
                             optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
     void uniformMatrix3x4fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> value,
                             optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
-    void uniformMatrix4x3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value,
+    void uniformMatrix4x3fv(WebGLUniformLocation? location, GLboolean transpose, [AllowShared] Float32Array value,
                             optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
     void uniformMatrix4x3fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> value,
                             optional GLuint srcOffset = 0, optional GLuint srcLength = 0);
 
     void vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
-    void vertexAttribI4iv(GLuint index, Int32Array v);
+    void vertexAttribI4iv(GLuint index, [AllowShared] Int32Array v);
     void vertexAttribI4iv(GLuint index, sequence<GLint> v);
     void vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
-    void vertexAttribI4uiv(GLuint index, Uint32Array v);
+    void vertexAttribI4uiv(GLuint index, [AllowShared] Uint32Array v);
     void vertexAttribI4uiv(GLuint index, sequence<GLuint> v);
     void vertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
 
@@ -465,11 +465,11 @@
 
     /* Multiple Render Targets */
     void drawBuffers(sequence<GLenum> buffers);
-    void clearBufferiv(GLenum buffer, GLint drawbuffer, Int32Array value, optional GLuint srcOffset = 0);
+    void clearBufferiv(GLenum buffer, GLint drawbuffer, [AllowShared] Int32Array value, optional GLuint srcOffset = 0);
     void clearBufferiv(GLenum buffer, GLint drawbuffer, sequence<GLint> value, optional GLuint srcOffset = 0);
-    void clearBufferuiv(GLenum buffer, GLint drawbuffer, Uint32Array value, optional GLuint srcOffset = 0);
+    void clearBufferuiv(GLenum buffer, GLint drawbuffer, [AllowShared] Uint32Array value, optional GLuint srcOffset = 0);
     void clearBufferuiv(GLenum buffer, GLint drawbuffer, sequence<GLuint> value, optional GLuint srcOffset = 0);
-    void clearBufferfv(GLenum buffer, GLint drawbuffer, Float32Array value, optional GLuint srcOffset = 0);
+    void clearBufferfv(GLenum buffer, GLint drawbuffer, [AllowShared] Float32Array value, optional GLuint srcOffset = 0);
     void clearBufferfv(GLenum buffer, GLint drawbuffer, sequence<GLfloat> value, optional GLuint srcOffset = 0);
     void clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
 
@@ -530,7 +530,7 @@
     void bindVertexArray(WebGLVertexArrayObject? vertexArray);
 
     /* Reading */
-    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView dstData, GLintptr offset);
+    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView dstData, GLintptr offset);
     void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLintptr offset);
 };
 WebGL2RenderingContextBase implements WebGLRenderingContextBase;
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLGetBufferSubDataAsync.h b/third_party/WebKit/Source/modules/webgl/WebGLGetBufferSubDataAsync.h
index d0f8ec9..21cbf010 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLGetBufferSubDataAsync.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGLGetBufferSubDataAsync.h
@@ -6,7 +6,7 @@
 #define WebGLGetBufferSubDataAsync_h
 
 #include "bindings/core/v8/ScriptPromise.h"
-#include "core/dom/NotShared.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "modules/webgl/WebGLExtension.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index f4be992..3561d18 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -32,6 +32,7 @@
 #include "bindings/core/v8/V8BindingMacros.h"
 #include "bindings/modules/v8/HTMLCanvasElementOrOffscreenCanvas.h"
 #include "bindings/modules/v8/WebGLAny.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMArrayBuffer.h"
 #include "core/dom/DOMTypedArray.h"
 #include "core/dom/ExecutionContext.h"
@@ -1904,13 +1905,13 @@
 }
 
 void WebGLRenderingContextBase::bufferData(GLenum target,
-                                           NotShared<DOMArrayBufferView> data,
+                                           MaybeShared<DOMArrayBufferView> data,
                                            GLenum usage) {
   if (isContextLost())
     return;
   DCHECK(data);
-  BufferDataImpl(target, data.View()->byteLength(), data.View()->BaseAddress(),
-                 usage);
+  BufferDataImpl(target, data.View()->byteLength(),
+                 data.View()->BaseAddressMaybeShared(), usage);
 }
 
 void WebGLRenderingContextBase::BufferSubDataImpl(GLenum target,
@@ -2084,7 +2085,7 @@
     GLsizei width,
     GLsizei height,
     GLint border,
-    NotShared<DOMArrayBufferView> data) {
+    MaybeShared<DOMArrayBufferView> data) {
   if (isContextLost())
     return;
   if (!ValidateTexture2DBinding("compressedTexImage2D", target))
@@ -2093,7 +2094,7 @@
     return;
   ContextGL()->CompressedTexImage2D(target, level, internalformat, width,
                                     height, border, data.View()->byteLength(),
-                                    data.View()->BaseAddress());
+                                    data.View()->BaseAddressMaybeShared());
 }
 
 void WebGLRenderingContextBase::compressedTexSubImage2D(
@@ -2104,7 +2105,7 @@
     GLsizei width,
     GLsizei height,
     GLenum format,
-    NotShared<DOMArrayBufferView> data) {
+    MaybeShared<DOMArrayBufferView> data) {
   if (isContextLost())
     return;
   if (!ValidateTexture2DBinding("compressedTexSubImage2D", target))
@@ -2113,7 +2114,7 @@
     return;
   ContextGL()->CompressedTexSubImage2D(
       target, level, xoffset, yoffset, width, height, format,
-      data.View()->byteLength(), data.View()->BaseAddress());
+      data.View()->byteLength(), data.View()->BaseAddressMaybeShared());
 }
 
 bool WebGLRenderingContextBase::ValidateSettableTexFormat(
@@ -4116,7 +4117,7 @@
     GLsizei height,
     GLenum format,
     GLenum type,
-    NotShared<DOMArrayBufferView> pixels) {
+    MaybeShared<DOMArrayBufferView> pixels) {
   ReadPixelsHelper(x, y, width, height, format, type, pixels.View(), 0);
 }
 
@@ -4166,7 +4167,7 @@
     return;
   }
   ClearIfComposited();
-  uint8_t* data = static_cast<uint8_t*>(pixels->BaseAddress()) +
+  uint8_t* data = static_cast<uint8_t*>(pixels->BaseAddressMaybeShared()) +
                   offset_in_bytes.ValueOrDie();
   {
     ScopedDrawingBufferBinder binder(GetDrawingBuffer(), framebuffer);
@@ -4682,7 +4683,7 @@
                            format, type, pixels, null_disposition, src_offset))
     return;
   uint8_t* data =
-      reinterpret_cast<uint8_t*>(pixels ? pixels->BaseAddress() : 0);
+      reinterpret_cast<uint8_t*>(pixels ? pixels->BaseAddressMaybeShared() : 0);
   if (src_offset) {
     DCHECK(pixels);
     // No need to check overflow because validateTexFuncData() already did.
@@ -4733,7 +4734,7 @@
     GLint border,
     GLenum format,
     GLenum type,
-    NotShared<DOMArrayBufferView> pixels) {
+    MaybeShared<DOMArrayBufferView> pixels) {
   TexImageHelperDOMArrayBufferView(kTexImage2D, target, level, internalformat,
                                    width, height, 1, border, format, type, 0, 0,
                                    0, pixels.View(), kNullAllowed, 0);
@@ -5600,7 +5601,7 @@
     GLsizei height,
     GLenum format,
     GLenum type,
-    NotShared<DOMArrayBufferView> pixels) {
+    MaybeShared<DOMArrayBufferView> pixels) {
   TexImageHelperDOMArrayBufferView(kTexSubImage2D, target, level, 0, width,
                                    height, 1, 0, format, type, xoffset, yoffset,
                                    0, pixels.View(), kNullNotAllowed, 0);
@@ -5966,13 +5967,13 @@
 void WebGLRenderingContextBase::uniformMatrix2fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> v) {
+    MaybeShared<DOMFloat32Array> v) {
   if (isContextLost() ||
       !ValidateUniformMatrixParameters("uniformMatrix2fv", location, transpose,
                                        v.View(), 4, 0, v.View()->length()))
     return;
   ContextGL()->UniformMatrix2fv(location->Location(), v.View()->length() >> 2,
-                                transpose, v.View()->Data());
+                                transpose, v.View()->DataMaybeShared());
 }
 
 void WebGLRenderingContextBase::uniformMatrix2fv(
@@ -5990,13 +5991,13 @@
 void WebGLRenderingContextBase::uniformMatrix3fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> v) {
+    MaybeShared<DOMFloat32Array> v) {
   if (isContextLost() ||
       !ValidateUniformMatrixParameters("uniformMatrix3fv", location, transpose,
                                        v.View(), 9, 0, v.View()->length()))
     return;
   ContextGL()->UniformMatrix3fv(location->Location(), v.View()->length() / 9,
-                                transpose, v.View()->Data());
+                                transpose, v.View()->DataMaybeShared());
 }
 
 void WebGLRenderingContextBase::uniformMatrix3fv(
@@ -6014,13 +6015,13 @@
 void WebGLRenderingContextBase::uniformMatrix4fv(
     const WebGLUniformLocation* location,
     GLboolean transpose,
-    NotShared<DOMFloat32Array> v) {
+    MaybeShared<DOMFloat32Array> v) {
   if (isContextLost() ||
       !ValidateUniformMatrixParameters("uniformMatrix4fv", location, transpose,
                                        v.View(), 16, 0, v.View()->length()))
     return;
   ContextGL()->UniformMatrix4fv(location->Location(), v.View()->length() >> 4,
-                                transpose, v.View()->Data());
+                                transpose, v.View()->DataMaybeShared());
 }
 
 void WebGLRenderingContextBase::uniformMatrix4fv(
@@ -6078,14 +6079,14 @@
 
 void WebGLRenderingContextBase::vertexAttrib1fv(
     GLuint index,
-    NotShared<const DOMFloat32Array> v) {
+    MaybeShared<const DOMFloat32Array> v) {
   if (isContextLost())
     return;
   if (!v.View() || v.View()->length() < 1) {
     SynthesizeGLError(GL_INVALID_VALUE, "vertexAttrib1fv", "invalid array");
     return;
   }
-  ContextGL()->VertexAttrib1fv(index, v.View()->Data());
+  ContextGL()->VertexAttrib1fv(index, v.View()->DataMaybeShared());
   SetVertexAttribType(index, kFloat32ArrayType);
 }
 
@@ -6112,14 +6113,14 @@
 
 void WebGLRenderingContextBase::vertexAttrib2fv(
     GLuint index,
-    NotShared<const DOMFloat32Array> v) {
+    MaybeShared<const DOMFloat32Array> v) {
   if (isContextLost())
     return;
   if (!v.View() || v.View()->length() < 2) {
     SynthesizeGLError(GL_INVALID_VALUE, "vertexAttrib2fv", "invalid array");
     return;
   }
-  ContextGL()->VertexAttrib2fv(index, v.View()->Data());
+  ContextGL()->VertexAttrib2fv(index, v.View()->DataMaybeShared());
   SetVertexAttribType(index, kFloat32ArrayType);
 }
 
@@ -6147,14 +6148,14 @@
 
 void WebGLRenderingContextBase::vertexAttrib3fv(
     GLuint index,
-    NotShared<const DOMFloat32Array> v) {
+    MaybeShared<const DOMFloat32Array> v) {
   if (isContextLost())
     return;
   if (!v.View() || v.View()->length() < 3) {
     SynthesizeGLError(GL_INVALID_VALUE, "vertexAttrib3fv", "invalid array");
     return;
   }
-  ContextGL()->VertexAttrib3fv(index, v.View()->Data());
+  ContextGL()->VertexAttrib3fv(index, v.View()->DataMaybeShared());
   SetVertexAttribType(index, kFloat32ArrayType);
 }
 
@@ -6183,14 +6184,14 @@
 
 void WebGLRenderingContextBase::vertexAttrib4fv(
     GLuint index,
-    NotShared<const DOMFloat32Array> v) {
+    MaybeShared<const DOMFloat32Array> v) {
   if (isContextLost())
     return;
   if (!v.View() || v.View()->length() < 4) {
     SynthesizeGLError(GL_INVALID_VALUE, "vertexAttrib4fv", "invalid array");
     return;
   }
-  ContextGL()->VertexAttrib4fv(index, v.View()->Data());
+  ContextGL()->VertexAttrib4fv(index, v.View()->DataMaybeShared());
   SetVertexAttribType(index, kFloat32ArrayType);
 }
 
@@ -7245,7 +7246,7 @@
     return false;
   }
   return ValidateUniformMatrixParameters(
-      function_name, location, transpose, v->Data(), v->length(),
+      function_name, location, transpose, v->DataMaybeShared(), v->length(),
       required_min_size, src_offset, src_length);
 }
 
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
index 3a7af8e..c498e06 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -34,8 +34,8 @@
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "bindings/core/v8/ScriptWrappableVisitor.h"
 #include "core/CoreExport.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "core/dom/TypedFlexibleArrayBufferView.h"
 #include "core/html/canvas/CanvasContextCreationAttributes.h"
 #include "core/html/canvas/CanvasRenderingContext.h"
@@ -168,7 +168,7 @@
   void bufferData(GLenum target, long long size, GLenum usage);
   void bufferData(GLenum target, DOMArrayBuffer* data, GLenum usage);
   void bufferData(GLenum target,
-                  NotShared<DOMArrayBufferView> data,
+                  MaybeShared<DOMArrayBufferView> data,
                   GLenum usage);
   void bufferSubData(GLenum target, long long offset, DOMArrayBuffer* data);
   void bufferSubData(GLenum target,
@@ -192,7 +192,7 @@
                             GLsizei width,
                             GLsizei height,
                             GLint border,
-                            NotShared<DOMArrayBufferView> data);
+                            MaybeShared<DOMArrayBufferView> data);
   void compressedTexSubImage2D(GLenum target,
                                GLint level,
                                GLint xoffset,
@@ -200,7 +200,7 @@
                                GLsizei width,
                                GLsizei height,
                                GLenum format,
-                               NotShared<DOMArrayBufferView> data);
+                               MaybeShared<DOMArrayBufferView> data);
 
   void copyTexImage2D(GLenum target,
                       GLint level,
@@ -325,7 +325,7 @@
                           GLsizei height,
                           GLenum format,
                           GLenum type,
-                          NotShared<DOMArrayBufferView> pixels);
+                          MaybeShared<DOMArrayBufferView> pixels);
   void renderbufferStorage(GLenum target,
                            GLenum internalformat,
                            GLsizei width,
@@ -348,7 +348,7 @@
                   GLint border,
                   GLenum format,
                   GLenum type,
-                  NotShared<DOMArrayBufferView>);
+                  MaybeShared<DOMArrayBufferView>);
   void texImage2D(GLenum target,
                   GLint level,
                   GLint internalformat,
@@ -398,7 +398,7 @@
                      GLsizei height,
                      GLenum format,
                      GLenum type,
-                     NotShared<DOMArrayBufferView>);
+                     MaybeShared<DOMArrayBufferView>);
   void texSubImage2D(GLenum target,
                      GLint level,
                      GLint xoffset,
@@ -476,19 +476,19 @@
   void uniform4iv(const WebGLUniformLocation*, Vector<GLint>&);
   void uniformMatrix2fv(const WebGLUniformLocation*,
                         GLboolean transpose,
-                        NotShared<DOMFloat32Array> value);
+                        MaybeShared<DOMFloat32Array> value);
   void uniformMatrix2fv(const WebGLUniformLocation*,
                         GLboolean transpose,
                         Vector<GLfloat>& value);
   void uniformMatrix3fv(const WebGLUniformLocation*,
                         GLboolean transpose,
-                        NotShared<DOMFloat32Array> value);
+                        MaybeShared<DOMFloat32Array> value);
   void uniformMatrix3fv(const WebGLUniformLocation*,
                         GLboolean transpose,
                         Vector<GLfloat>& value);
   void uniformMatrix4fv(const WebGLUniformLocation*,
                         GLboolean transpose,
-                        NotShared<DOMFloat32Array> value);
+                        MaybeShared<DOMFloat32Array> value);
   void uniformMatrix4fv(const WebGLUniformLocation*,
                         GLboolean transpose,
                         Vector<GLfloat>& value);
@@ -497,16 +497,16 @@
   void validateProgram(WebGLProgram*);
 
   void vertexAttrib1f(GLuint index, GLfloat x);
-  void vertexAttrib1fv(GLuint index, NotShared<const DOMFloat32Array> values);
+  void vertexAttrib1fv(GLuint index, MaybeShared<const DOMFloat32Array> values);
   void vertexAttrib1fv(GLuint index, const Vector<GLfloat>& values);
   void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
-  void vertexAttrib2fv(GLuint index, NotShared<const DOMFloat32Array> values);
+  void vertexAttrib2fv(GLuint index, MaybeShared<const DOMFloat32Array> values);
   void vertexAttrib2fv(GLuint index, const Vector<GLfloat>& values);
   void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
-  void vertexAttrib3fv(GLuint index, NotShared<const DOMFloat32Array> values);
+  void vertexAttrib3fv(GLuint index, MaybeShared<const DOMFloat32Array> values);
   void vertexAttrib3fv(GLuint index, const Vector<GLfloat>& values);
   void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-  void vertexAttrib4fv(GLuint index, NotShared<const DOMFloat32Array> values);
+  void vertexAttrib4fv(GLuint index, MaybeShared<const DOMFloat32Array> values);
   void vertexAttrib4fv(GLuint index, const Vector<GLfloat>& values);
   void vertexAttribPointer(GLuint index,
                            GLint size,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.idl b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.idl
index 7047ff4..71a3a55 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.idl
@@ -486,7 +486,7 @@
     // FIXME: should be union type
     // https://www.khronos.org/bugzilla/show_bug.cgi?id=1172
     void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
-    void bufferData(GLenum target, ArrayBufferView data, GLenum usage);
+    void bufferData(GLenum target, [AllowShared] ArrayBufferView data, GLenum usage);
     void bufferData(GLenum target, ArrayBuffer? data, GLenum usage);
     void bufferSubData(GLenum target, GLintptr offset, [FlexibleArrayBufferView] ArrayBufferView data);
     void bufferSubData(GLenum target, GLintptr offset, ArrayBuffer data);
@@ -500,9 +500,9 @@
     void compileShader(WebGLShader shader);
 
     void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
-                              GLsizei width, GLsizei height, GLint border, ArrayBufferView data);
+                              GLsizei width, GLsizei height, GLint border, [AllowShared] ArrayBufferView data);
     void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-                                 GLsizei width, GLsizei height, GLenum format, ArrayBufferView data);
+                                 GLsizei width, GLsizei height, GLenum format, [AllowShared] ArrayBufferView data);
 
     void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
     void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
@@ -595,7 +595,7 @@
     void pixelStorei(GLenum pname, GLint param);
     void polygonOffset(GLfloat factor, GLfloat units);
 
-    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView? pixels);
+    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels);
 
     void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
     void sampleCoverage(GLclampf value, GLboolean invert);
@@ -617,7 +617,7 @@
     void texImage2D(
         GLenum target, GLint level, GLint internalformat,
         GLsizei width, GLsizei height, GLint border,
-        GLenum format, GLenum type, ArrayBufferView? pixels);
+        GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels);
     void texImage2D(
         GLenum target, GLint level, GLint internalformat,
         GLenum format, GLenum type, ImageData pixels);
@@ -637,7 +637,7 @@
     void texSubImage2D(
         GLenum target, GLint level, GLint xoffset, GLint yoffset,
         GLsizei width, GLsizei height,
-        GLenum format, GLenum type, ArrayBufferView? pixels);
+        GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels);
     void texSubImage2D(
         GLenum target, GLint level, GLint xoffset, GLint yoffset,
         GLenum format, GLenum type, ImageData pixels);
@@ -679,27 +679,27 @@
     void uniform4iv(WebGLUniformLocation? location, [FlexibleArrayBufferView] Int32Array v);
     void uniform4iv(WebGLUniformLocation? location, sequence<GLint> v);
 
-    void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
+    void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, [AllowShared] Float32Array array);
     void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> array);
-    void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
+    void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, [AllowShared] Float32Array array);
     void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> array);
-    void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
+    void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, [AllowShared] Float32Array array);
     void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> array);
 
     void useProgram(WebGLProgram? program);
     void validateProgram(WebGLProgram program);
 
     void vertexAttrib1f(GLuint indx, GLfloat x);
-    void vertexAttrib1fv(GLuint indx, Float32Array values);
+    void vertexAttrib1fv(GLuint indx, [AllowShared] Float32Array values);
     void vertexAttrib1fv(GLuint indx, sequence<GLfloat> values);
     void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
-    void vertexAttrib2fv(GLuint indx, Float32Array values);
+    void vertexAttrib2fv(GLuint indx, [AllowShared] Float32Array values);
     void vertexAttrib2fv(GLuint indx, sequence<GLfloat> values);
     void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
-    void vertexAttrib3fv(GLuint indx, Float32Array values);
+    void vertexAttrib3fv(GLuint indx, [AllowShared] Float32Array values);
     void vertexAttrib3fv(GLuint indx, sequence<GLfloat> values);
     void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-    void vertexAttrib4fv(GLuint indx, Float32Array values);
+    void vertexAttrib4fv(GLuint indx, [AllowShared] Float32Array values);
     void vertexAttrib4fv(GLuint indx, sequence<GLfloat> values);
     void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized,
                                                     GLsizei stride, GLintptr offset);
diff --git a/third_party/WebKit/Source/modules/webmidi/MIDIOutput.h b/third_party/WebKit/Source/modules/webmidi/MIDIOutput.h
index 74d4fca..4ce3d9f 100644
--- a/third_party/WebKit/Source/modules/webmidi/MIDIOutput.h
+++ b/third_party/WebKit/Source/modules/webmidi/MIDIOutput.h
@@ -31,8 +31,8 @@
 #ifndef MIDIOutput_h
 #define MIDIOutput_h
 
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/dom/NotShared.h"
 #include "modules/webmidi/MIDIPort.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/modules/websockets/DOMWebSocket.h b/third_party/WebKit/Source/modules/websockets/DOMWebSocket.h
index 42c9a94b..b12425d 100644
--- a/third_party/WebKit/Source/modules/websockets/DOMWebSocket.h
+++ b/third_party/WebKit/Source/modules/websockets/DOMWebSocket.h
@@ -36,7 +36,7 @@
 #include <memory>
 #include "bindings/core/v8/ActiveScriptWrappable.h"
 #include "bindings/core/v8/ScriptWrappable.h"
-#include "core/dom/NotShared.h"
+#include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/SuspendableObject.h"
 #include "core/events/EventListener.h"
 #include "core/events/EventTarget.h"
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index e5c45f2f..55013198 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -261,7 +261,6 @@
     "FrameViewBase.h",
     "Histogram.cpp",
     "Histogram.h",
-    "HostWindow.h",
     "InstanceCounters.cpp",
     "InstanceCounters.h",
     "KeyboardCodes.h",
@@ -297,6 +296,7 @@
     "PartitionAllocMemoryDumpProvider.cpp",
     "PartitionAllocMemoryDumpProvider.h",
     "PasteMode.h",
+    "PlatformChromeClient.h",
     "PlatformExport.h",
     "PlatformResourceLoader.cpp",
     "PlatformResourceLoader.h",
diff --git a/third_party/WebKit/Source/platform/DragImageTest.cpp b/third_party/WebKit/Source/platform/DragImageTest.cpp
index 6b5be27..fc8dabc7 100644
--- a/third_party/WebKit/Source/platform/DragImageTest.cpp
+++ b/third_party/WebKit/Source/platform/DragImageTest.cpp
@@ -156,23 +156,17 @@
 TEST(DragImageTest, InterpolationNone) {
   SkBitmap expected_bitmap;
   expected_bitmap.allocN32Pixels(4, 4);
-  {
-    SkAutoLockPixels lock(expected_bitmap);
-    expected_bitmap.eraseArea(SkIRect::MakeXYWH(0, 0, 2, 2), 0xFFFFFFFF);
-    expected_bitmap.eraseArea(SkIRect::MakeXYWH(0, 2, 2, 2), 0xFF000000);
-    expected_bitmap.eraseArea(SkIRect::MakeXYWH(2, 0, 2, 2), 0xFF000000);
-    expected_bitmap.eraseArea(SkIRect::MakeXYWH(2, 2, 2, 2), 0xFFFFFFFF);
-  }
+  expected_bitmap.eraseArea(SkIRect::MakeXYWH(0, 0, 2, 2), 0xFFFFFFFF);
+  expected_bitmap.eraseArea(SkIRect::MakeXYWH(0, 2, 2, 2), 0xFF000000);
+  expected_bitmap.eraseArea(SkIRect::MakeXYWH(2, 0, 2, 2), 0xFF000000);
+  expected_bitmap.eraseArea(SkIRect::MakeXYWH(2, 2, 2, 2), 0xFFFFFFFF);
 
   SkBitmap test_bitmap;
   test_bitmap.allocN32Pixels(2, 2);
-  {
-    SkAutoLockPixels lock(test_bitmap);
-    test_bitmap.eraseArea(SkIRect::MakeXYWH(0, 0, 1, 1), 0xFFFFFFFF);
-    test_bitmap.eraseArea(SkIRect::MakeXYWH(0, 1, 1, 1), 0xFF000000);
-    test_bitmap.eraseArea(SkIRect::MakeXYWH(1, 0, 1, 1), 0xFF000000);
-    test_bitmap.eraseArea(SkIRect::MakeXYWH(1, 1, 1, 1), 0xFFFFFFFF);
-  }
+  test_bitmap.eraseArea(SkIRect::MakeXYWH(0, 0, 1, 1), 0xFFFFFFFF);
+  test_bitmap.eraseArea(SkIRect::MakeXYWH(0, 1, 1, 1), 0xFF000000);
+  test_bitmap.eraseArea(SkIRect::MakeXYWH(1, 0, 1, 1), 0xFF000000);
+  test_bitmap.eraseArea(SkIRect::MakeXYWH(1, 1, 1, 1), 0xFFFFFFFF);
 
   RefPtr<TestImage> test_image =
       TestImage::Create(SkImage::MakeFromBitmap(test_bitmap));
@@ -181,13 +175,9 @@
   ASSERT_TRUE(drag_image);
   drag_image->Scale(2, 2);
   const SkBitmap& drag_bitmap = drag_image->Bitmap();
-  {
-    SkAutoLockPixels lock1(drag_bitmap);
-    SkAutoLockPixels lock2(expected_bitmap);
-    for (int x = 0; x < drag_bitmap.width(); ++x)
-      for (int y = 0; y < drag_bitmap.height(); ++y)
-        EXPECT_EQ(expected_bitmap.getColor(x, y), drag_bitmap.getColor(x, y));
-  }
+  for (int x = 0; x < drag_bitmap.width(); ++x)
+    for (int y = 0; y < drag_bitmap.height(); ++y)
+      EXPECT_EQ(expected_bitmap.getColor(x, y), drag_bitmap.getColor(x, y));
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/HostWindow.h b/third_party/WebKit/Source/platform/PlatformChromeClient.h
similarity index 86%
rename from third_party/WebKit/Source/platform/HostWindow.h
rename to third_party/WebKit/Source/platform/PlatformChromeClient.h
index 3ccc0cc..3f939b80 100644
--- a/third_party/WebKit/Source/platform/HostWindow.h
+++ b/third_party/WebKit/Source/platform/PlatformChromeClient.h
@@ -23,8 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef HostWindow_h
-#define HostWindow_h
+#ifndef PlatformChromeClient_h
+#define PlatformChromeClient_h
 
 #include "platform/PlatformExport.h"
 #include "platform/heap/Handle.h"
@@ -36,13 +36,13 @@
 class FrameViewBase;
 class LocalFrame;
 
-class PLATFORM_EXPORT HostWindow
-    : public GarbageCollectedFinalized<HostWindow> {
-  WTF_MAKE_NONCOPYABLE(HostWindow);
+class PLATFORM_EXPORT PlatformChromeClient
+    : public GarbageCollectedFinalized<PlatformChromeClient> {
+  WTF_MAKE_NONCOPYABLE(PlatformChromeClient);
 
  public:
-  HostWindow() {}
-  virtual ~HostWindow() {}
+  PlatformChromeClient() {}
+  virtual ~PlatformChromeClient() {}
   DEFINE_INLINE_VIRTUAL_TRACE() {}
 
   // Requests the host invalidate the contents.
@@ -61,4 +61,4 @@
 
 }  // namespace blink
 
-#endif  // HostWindow_h
+#endif  // PlatformChromeClient_h
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
index 74a77c0..f10da27 100644
--- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
@@ -172,8 +172,6 @@
 
   canvas_->drawPicture(record);
   EXPECT_EQ(0, decode_request_count_);
-
-  SkAutoLockPixels auto_lock(bitmap_);
   EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), bitmap_.getColor(0, 0));
 }
 
@@ -203,8 +201,6 @@
                  PaintImage::CompletionState::DONE),
       0, 0);
   canvas_->drawPicture(recorder.finishRecordingAsPicture());
-
-  SkAutoLockPixels auto_lock(bitmap_);
   EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), bitmap_.getColor(0, 0));
 }
 
@@ -237,8 +233,6 @@
                       record));
   thread.reset();
   EXPECT_EQ(0, decode_request_count_);
-
-  SkAutoLockPixels auto_lock(bitmap_);
   EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), bitmap_.getColor(0, 0));
 }
 
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp
index 00833ae3..55a61e2 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp
@@ -48,7 +48,6 @@
 
 #define EXPECT_OPAQUE_PIXELS_IN_RECT(bitmap, opaqueRect)         \
   {                                                              \
-    SkAutoLockPixels locker(bitmap);                             \
     for (int y = opaqueRect.Y(); y < opaqueRect.MaxY(); ++y)     \
       for (int x = opaqueRect.X(); x < opaqueRect.MaxX(); ++x) { \
         int alpha = *bitmap.getAddr32(x, y) >> 24;               \
@@ -58,7 +57,6 @@
 
 #define EXPECT_OPAQUE_PIXELS_ONLY_IN_RECT(bitmap, opaqueRect) \
   {                                                           \
-    SkAutoLockPixels locker(bitmap);                          \
     for (int y = 0; y < bitmap.height(); ++y)                 \
       for (int x = 0; x < bitmap.width(); ++x) {              \
         int alpha = *bitmap.getAddr32(x, y) >> 24;            \
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
index de81bab..a971f8a 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
@@ -1244,8 +1244,6 @@
     canvas.drawPicture(std::move(new_record));
   }
 
-  old_bitmap.lockPixels();
-  new_bitmap.lockPixels();
   int mismatching_pixels = 0;
   static const int kMaxMismatchesToReport = 50;
   for (int bitmap_y = 0; bitmap_y < rect.Height(); ++bitmap_y) {
@@ -1277,8 +1275,6 @@
       }
     }
   }
-  old_bitmap.unlockPixels();
-  new_bitmap.unlockPixels();
 
   // Visualize under-invalidations by overlaying the new bitmap (containing red
   // pixels indicating under-invalidations, and transparent pixels otherwise)
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.cpp b/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.cpp
index 10858cc..bf97b5c 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.cpp
@@ -83,12 +83,4 @@
   Canvas()->flush();
 }
 
-bool ImageBufferSurface::WritePixels(const SkImageInfo& orig_info,
-                                     const void* pixels,
-                                     size_t row_bytes,
-                                     int x,
-                                     int y) {
-  return Canvas()->writePixels(orig_info, pixels, row_bytes, x, y);
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.h
index bc4af9dd..62f9231 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.h
+++ b/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.h
@@ -96,7 +96,7 @@
                            const void* pixels,
                            size_t row_bytes,
                            int x,
-                           int y);
+                           int y) = 0;
 
   // May return nullptr if the surface is GPU-backed and the GPU context was
   // lost.
diff --git a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
index 933023e..2382ab7 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
@@ -86,10 +86,7 @@
     if (!CompatibleInfo(info_, info) || row_bytes_ != dst->rowBytes())
       return false;
 
-    if (!dst->installPixels(info, pixels_, row_bytes_))
-      return false;
-    dst->lockPixels();
-    return true;
+    return dst->installPixels(info, pixels_, row_bytes_);
   }
 
  private:
@@ -165,7 +162,6 @@
   // provided. If not, make a copy.
   DCHECK_EQ(bitmap.width(), scaled_size.width());
   DCHECK_EQ(bitmap.height(), scaled_size.height());
-  SkAutoLockPixels bitmap_lock(bitmap);
   if (bitmap.getPixels() != pixels)
     CopyPixels(pixels, row_bytes, bitmap.getPixels(), bitmap.rowBytes(), info);
   return true;
diff --git a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.cpp b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.cpp
index ce38fa85..64a496b5 100644
--- a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.cpp
+++ b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.cpp
@@ -73,6 +73,14 @@
   return surface_;
 }
 
+bool UnacceleratedImageBufferSurface::WritePixels(const SkImageInfo& orig_info,
+                                                  const void* pixels,
+                                                  size_t row_bytes,
+                                                  int x,
+                                                  int y) {
+  return surface_->getCanvas()->writePixels(orig_info, pixels, row_bytes, x, y);
+}
+
 sk_sp<SkImage> UnacceleratedImageBufferSurface::NewImageSnapshot(
     AccelerationHint,
     SnapshotReason) {
diff --git a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h
index 2a6cf946..c94f4b2c 100644
--- a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h
+++ b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h
@@ -53,6 +53,11 @@
 
   PaintCanvas* Canvas() override;
   bool IsValid() const override;
+  bool WritePixels(const SkImageInfo& orig_info,
+                   const void* pixels,
+                   size_t row_bytes,
+                   int x,
+                   int y) override;
 
   sk_sp<SkImage> NewImageSnapshot(AccelerationHint, SnapshotReason) override;
 
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.cpp b/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.cpp
index fd5a436f..fa52e694 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.cpp
@@ -89,4 +89,12 @@
       ->fID;
 }
 
+bool AcceleratedImageBufferSurface::WritePixels(const SkImageInfo& orig_info,
+                                                const void* pixels,
+                                                size_t row_bytes,
+                                                int x,
+                                                int y) {
+  return surface_->getCanvas()->writePixels(orig_info, pixels, row_bytes, x, y);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.h
index 91ee454..ef31bc9 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.h
+++ b/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.h
@@ -56,6 +56,11 @@
   bool IsAccelerated() const override { return true; }
   sk_sp<SkImage> NewImageSnapshot(AccelerationHint, SnapshotReason) override;
   GLuint GetBackingTextureHandleForOverwrite() override;
+  bool WritePixels(const SkImageInfo& orig_info,
+                   const void* pixels,
+                   size_t row_bytes,
+                   int x,
+                   int y) override;
 
  private:
   unsigned context_id_;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.cpp b/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.cpp
index 2a17f3d..d88ea7c 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.cpp
@@ -83,8 +83,6 @@
 
   SkBitmap bitmap1 = RecordToBitmap(record1);
   SkBitmap bitmap2 = RecordToBitmap(record2);
-  bitmap1.lockPixels();
-  bitmap2.lockPixels();
   int mismatch_count = 0;
   const int kMaxMismatches = 10;
   for (int y = 0; y < rect.height() && mismatch_count < kMaxMismatches; ++y) {
@@ -98,8 +96,6 @@
       }
     }
   }
-  bitmap1.unlockPixels();
-  bitmap2.unlockPixels();
   return !mismatch_count;
 }
 
diff --git a/third_party/WebKit/Source/platform/heap/GCInfo.cpp b/third_party/WebKit/Source/platform/heap/GCInfo.cpp
index 2f4a425..6b5fda67 100644
--- a/third_party/WebKit/Source/platform/heap/GCInfo.cpp
+++ b/third_party/WebKit/Source/platform/heap/GCInfo.cpp
@@ -18,8 +18,8 @@
 
 void GCInfoTable::EnsureGCInfoIndex(const GCInfo* gc_info,
                                     size_t* gc_info_index_slot) {
-  ASSERT(gc_info);
-  ASSERT(gc_info_index_slot);
+  DCHECK(gc_info);
+  DCHECK(gc_info_index_slot);
   // Keep a global GCInfoTable lock while allocating a new slot.
   DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, mutex, new Mutex);
   MutexLocker locker(mutex);
@@ -48,11 +48,11 @@
 
   size_t new_size =
       gc_info_table_size_ ? 2 * gc_info_table_size_ : kInitialSize;
-  ASSERT(new_size < GCInfoTable::kMaxIndex);
+  DCHECK(new_size < GCInfoTable::kMaxIndex);
   g_gc_info_table =
       reinterpret_cast<GCInfo const**>(WTF::Partitions::FastRealloc(
           g_gc_info_table, new_size * sizeof(GCInfo), "GCInfo"));
-  ASSERT(g_gc_info_table);
+  DCHECK(g_gc_info_table);
   memset(reinterpret_cast<uint8_t*>(g_gc_info_table) +
              gc_info_table_size_ * sizeof(GCInfo),
          kGcInfoZapValue, (new_size - gc_info_table_size_) * sizeof(GCInfo));
@@ -70,8 +70,8 @@
 #if !defined(COMPONENT_BUILD)
   // On component builds we cannot compare the gcInfos as they are statically
   // defined in each of the components and hence will not match.
-  ASSERT(HeapObjectHeader::FromPayload(payload)->GcInfoIndex() ==
-         gc_info_index);
+  DCHECK_EQ(HeapObjectHeader::FromPayload(payload)->GcInfoIndex(),
+            gc_info_index);
 #endif
 }
 #endif
diff --git a/third_party/WebKit/Source/platform/heap/GCInfo.h b/third_party/WebKit/Source/platform/heap/GCInfo.h
index bdc2854..edeb5ee19 100644
--- a/third_party/WebKit/Source/platform/heap/GCInfo.h
+++ b/third_party/WebKit/Source/platform/heap/GCInfo.h
@@ -198,11 +198,11 @@
     };
 
     static size_t gc_info_index = 0;
-    ASSERT(g_gc_info_table);
+    DCHECK(g_gc_info_table);
     if (!AcquireLoad(&gc_info_index))
       GCInfoTable::EnsureGCInfoIndex(&kGcInfo, &gc_info_index);
-    ASSERT(gc_info_index >= 1);
-    ASSERT(gc_info_index < GCInfoTable::kMaxIndex);
+    DCHECK_GE(gc_info_index, 1u);
+    DCHECK(gc_info_index < GCInfoTable::kMaxIndex);
     return gc_info_index;
   }
 };
diff --git a/third_party/WebKit/Source/platform/heap/GCTaskRunner.h b/third_party/WebKit/Source/platform/heap/GCTaskRunner.h
index c4a9d54..18c662c 100644
--- a/third_party/WebKit/Source/platform/heap/GCTaskRunner.h
+++ b/third_party/WebKit/Source/platform/heap/GCTaskRunner.h
@@ -50,7 +50,7 @@
   ~GCTaskObserver() {
     // m_nesting can be 1 if this was unregistered in a task and
     // didProcessTask was not called.
-    ASSERT(!nesting_ || nesting_ == 1);
+    DCHECK(!nesting_ || nesting_ == 1);
   }
 
   virtual void WillProcessTask() { nesting_++; }
diff --git a/third_party/WebKit/Source/platform/heap/Heap.cpp b/third_party/WebKit/Source/platform/heap/Heap.cpp
index c36c0eb..0d2bf24a 100644
--- a/third_party/WebKit/Source/platform/heap/Heap.cpp
+++ b/third_party/WebKit/Source/platform/heap/Heap.cpp
@@ -171,7 +171,7 @@
 #endif
 
 Address ThreadHeap::CheckAndMarkPointer(Visitor* visitor, Address address) {
-  ASSERT(ThreadState::Current()->IsInGC());
+  DCHECK(ThreadState::Current()->IsInGC());
 
 #if !DCHECK_IS_ON()
   if (heap_does_not_contain_cache_->Lookup(address))
@@ -179,8 +179,10 @@
 #endif
 
   if (BasePage* page = LookupPageForAddress(address)) {
-    ASSERT(page->Contains(address));
-    ASSERT(!heap_does_not_contain_cache_->Lookup(address));
+#if DCHECK_IS_ON()
+    DCHECK(page->Contains(address));
+#endif
+    DCHECK(!heap_does_not_contain_cache_->Lookup(address));
     DCHECK(&visitor->Heap() == &page->Arena()->GetThreadState()->Heap());
     page->CheckAndMarkPointer(visitor, address);
     return address;
@@ -219,7 +221,7 @@
 #endif
 
 void ThreadHeap::PushTraceCallback(void* object, TraceCallback callback) {
-  ASSERT(ThreadState::Current()->IsInGC());
+  DCHECK(ThreadState::Current()->IsInGC());
 
   CallbackStack::Item* slot = marking_stack_->AllocateEntry();
   *slot = CallbackStack::Item(object, callback);
@@ -234,7 +236,7 @@
 }
 
 void ThreadHeap::PushPostMarkingCallback(void* object, TraceCallback callback) {
-  ASSERT(ThreadState::Current()->IsInGC());
+  DCHECK(ThreadState::Current()->IsInGC());
 
   CallbackStack::Item* slot = post_marking_callback_stack_->AllocateEntry();
   *slot = CallbackStack::Item(object, callback);
@@ -249,7 +251,7 @@
 }
 
 void ThreadHeap::PushWeakCallback(void* closure, WeakCallback callback) {
-  ASSERT(ThreadState::Current()->IsInGC());
+  DCHECK(ThreadState::Current()->IsInGC());
 
   CallbackStack::Item* slot = weak_callback_stack_->AllocateEntry();
   *slot = CallbackStack::Item(closure, callback);
@@ -266,7 +268,7 @@
 void ThreadHeap::RegisterWeakTable(void* table,
                                    EphemeronCallback iteration_callback,
                                    EphemeronCallback iteration_done_callback) {
-  ASSERT(ThreadState::Current()->IsInGC());
+  DCHECK(ThreadState::Current()->IsInGC());
 
   CallbackStack::Item* slot = ephemeron_stack_->AllocateEntry();
   *slot = CallbackStack::Item(table, iteration_callback);
@@ -278,7 +280,7 @@
 
 #if DCHECK_IS_ON()
 bool ThreadHeap::WeakTableRegistered(const void* table) {
-  ASSERT(ephemeron_stack_);
+  DCHECK(ephemeron_stack_);
   return ephemeron_stack_->HasCallbackForObject(table);
 }
 #endif
@@ -352,7 +354,7 @@
   // Post-marking callbacks should not trace any objects and
   // therefore the marking stack should be empty after the
   // post-marking callbacks.
-  ASSERT(marking_stack_->IsEmpty());
+  DCHECK(marking_stack_->IsEmpty());
 }
 
 void ThreadHeap::WeakProcessing(Visitor* visitor) {
@@ -370,7 +372,7 @@
 
   // It is not permitted to trace pointers of live objects in the weak
   // callback phase, so the marking stack should still be empty here.
-  ASSERT(marking_stack_->IsEmpty());
+  DCHECK(marking_stack_->IsEmpty());
 
   double time_for_weak_processing = WTF::CurrentTimeMS() - start_time;
   DEFINE_THREAD_SAFE_STATIC_LOCAL(
@@ -481,7 +483,7 @@
 }
 
 void ThreadHeap::VisitPersistentRoots(Visitor* visitor) {
-  ASSERT(ThreadState::Current()->IsInGC());
+  DCHECK(ThreadState::Current()->IsInGC());
   TRACE_EVENT0("blink_gc", "ThreadHeap::visitPersistentRoots");
   ProcessHeap::GetCrossThreadPersistentRegion().TracePersistentNodes(visitor);
 
@@ -489,13 +491,13 @@
 }
 
 void ThreadHeap::VisitStackRoots(Visitor* visitor) {
-  ASSERT(ThreadState::Current()->IsInGC());
+  DCHECK(ThreadState::Current()->IsInGC());
   TRACE_EVENT0("blink_gc", "ThreadHeap::visitStackRoots");
   thread_state_->VisitStack(visitor);
 }
 
 BasePage* ThreadHeap::LookupPageForAddress(Address address) {
-  ASSERT(ThreadState::Current()->IsInGC());
+  DCHECK(ThreadState::Current()->IsInGC());
   if (PageMemoryRegion* region = region_tree_->Lookup(address)) {
     return region->PageFromAddress(address);
   }
@@ -503,7 +505,7 @@
 }
 
 void ThreadHeap::ResetHeapCounters() {
-  ASSERT(ThreadState::Current()->IsInGC());
+  DCHECK(ThreadState::Current()->IsInGC());
 
   ThreadHeap::ReportMemoryUsageForTracing();
 
diff --git a/third_party/WebKit/Source/platform/heap/Heap.h b/third_party/WebKit/Source/platform/heap/Heap.h
index 0a9ec91..0a2f9fa 100644
--- a/third_party/WebKit/Source/platform/heap/Heap.h
+++ b/third_party/WebKit/Source/platform/heap/Heap.h
@@ -301,7 +301,7 @@
     // Page has been swept and it is still alive.
     if (page->HasBeenSwept())
       return false;
-    ASSERT(page->Arena()->GetThreadState()->IsSweepingInProgress());
+    DCHECK(page->Arena()->GetThreadState()->IsSweepingInProgress());
 
     // If marked and alive, the object hasn't yet been swept..and won't
     // be once its page is processed.
@@ -419,11 +419,11 @@
   BasePage* LookupPageForAddress(Address);
 
   static const GCInfo* GcInfo(size_t gc_info_index) {
-    ASSERT(gc_info_index >= 1);
-    ASSERT(gc_info_index < GCInfoTable::kMaxIndex);
-    ASSERT(g_gc_info_table);
+    DCHECK_GE(gc_info_index, 1u);
+    DCHECK(gc_info_index < GCInfoTable::kMaxIndex);
+    DCHECK(g_gc_info_table);
     const GCInfo* info = g_gc_info_table[gc_info_index];
-    ASSERT(info);
+    DCHECK(info);
     return info;
   }
 
@@ -572,7 +572,7 @@
     // eagerly finalized. Declaring and defining an 'operator new'
     // for this class is what's required -- consider using
     // DECLARE_EAGER_FINALIZATION_OPERATOR_NEW().
-    ASSERT(IS_EAGERLY_FINALIZED());
+    DCHECK(IS_EAGERLY_FINALIZED());
   }
 };
 #define EAGERLY_FINALIZE()                            \
@@ -592,8 +592,8 @@
                                                 int arena_index,
                                                 size_t gc_info_index,
                                                 const char* type_name) {
-  ASSERT(state->IsAllocationAllowed());
-  ASSERT(arena_index != BlinkGC::kLargeObjectArenaIndex);
+  DCHECK(state->IsAllocationAllowed());
+  DCHECK_NE(arena_index, BlinkGC::kLargeObjectArenaIndex);
   NormalPageArena* arena =
       static_cast<NormalPageArena*>(state->Arena(arena_index));
   Address address =
@@ -627,7 +627,7 @@
   ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
   HeapObjectHeader* previous_header = HeapObjectHeader::FromPayload(previous);
   BasePage* page = PageFromObject(previous_header);
-  ASSERT(page);
+  DCHECK(page);
 
   // Determine arena index of new allocation.
   int arena_index;
@@ -642,8 +642,8 @@
 
   size_t gc_info_index = GCInfoTrait<T>::Index();
   // TODO(haraken): We don't support reallocate() for finalizable objects.
-  ASSERT(!ThreadHeap::GcInfo(previous_header->GcInfoIndex())->HasFinalizer());
-  ASSERT(previous_header->GcInfoIndex() == gc_info_index);
+  DCHECK(!ThreadHeap::GcInfo(previous_header->GcInfoIndex())->HasFinalizer());
+  DCHECK_EQ(previous_header->GcInfoIndex(), gc_info_index);
   HeapAllocHooks::FreeHookIfEnabled(static_cast<Address>(previous));
   Address address;
   if (arena_index == BlinkGC::kLargeObjectArenaIndex) {
diff --git a/third_party/WebKit/Source/platform/heap/HeapAllocator.cpp b/third_party/WebKit/Source/platform/heap/HeapAllocator.cpp
index 01ffac8..3d8cc11 100644
--- a/third_party/WebKit/Source/platform/heap/HeapAllocator.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapAllocator.cpp
@@ -13,7 +13,7 @@
   ThreadState* state = ThreadState::Current();
   if (state->SweepForbidden())
     return;
-  ASSERT(!state->IsInGC());
+  DCHECK(!state->IsInGC());
 
   // Don't promptly free large objects because their page is never reused.
   // Don't free backings allocated on other threads.
@@ -46,8 +46,8 @@
   ThreadState* state = ThreadState::Current();
   if (state->SweepForbidden())
     return false;
-  ASSERT(!state->IsInGC());
-  ASSERT(state->IsAllocationAllowed());
+  DCHECK(!state->IsInGC());
+  DCHECK(state->IsAllocationAllowed());
   DCHECK_EQ(&state->Heap(), &ThreadState::FromObject(address)->Heap());
 
   // FIXME: Support expand for large objects.
@@ -82,13 +82,13 @@
   if (!address || quantized_shrunk_size == quantized_current_size)
     return true;
 
-  ASSERT(quantized_shrunk_size < quantized_current_size);
+  DCHECK_LT(quantized_shrunk_size, quantized_current_size);
 
   ThreadState* state = ThreadState::Current();
   if (state->SweepForbidden())
     return false;
-  ASSERT(!state->IsInGC());
-  ASSERT(state->IsAllocationAllowed());
+  DCHECK(!state->IsInGC());
+  DCHECK(state->IsAllocationAllowed());
   DCHECK_EQ(&state->Heap(), &ThreadState::FromObject(address)->Heap());
 
   // FIXME: Support shrink for large objects.
diff --git a/third_party/WebKit/Source/platform/heap/HeapAllocator.h b/third_party/WebKit/Source/platform/heap/HeapAllocator.h
index ee61d0b..7acd10e8 100644
--- a/third_party/WebKit/Source/platform/heap/HeapAllocator.h
+++ b/third_party/WebKit/Source/platform/heap/HeapAllocator.h
@@ -66,7 +66,7 @@
   static T* AllocateVectorBacking(size_t size) {
     ThreadState* state =
         ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
-    ASSERT(state->IsAllocationAllowed());
+    DCHECK(state->IsAllocationAllowed());
     size_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index();
     NormalPageArena* arena =
         static_cast<NormalPageArena*>(state->VectorBackingArena(gc_info_index));
@@ -77,7 +77,7 @@
   static T* AllocateExpandedVectorBacking(size_t size) {
     ThreadState* state =
         ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
-    ASSERT(state->IsAllocationAllowed());
+    DCHECK(state->IsAllocationAllowed());
     size_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index();
     NormalPageArena* arena = static_cast<NormalPageArena*>(
         state->ExpandedVectorBackingArena(gc_info_index));
@@ -323,7 +323,7 @@
       "HeapVectorBacking doesn't support objects that cannot be cleared as "
       "unused with memset or don't have a vtable");
 
-  ASSERT(!WTF::IsTriviallyDestructible<T>::value);
+  DCHECK(!WTF::IsTriviallyDestructible<T>::value);
   HeapObjectHeader* header = HeapObjectHeader::FromPayload(pointer);
   // Use the payload size as recorded by the heap to determine how many
   // elements to finalize.
@@ -351,7 +351,7 @@
 template <typename Table>
 void HeapHashTableBacking<Table>::Finalize(void* pointer) {
   using Value = typename Table::ValueType;
-  ASSERT(!WTF::IsTriviallyDestructible<Value>::value);
+  DCHECK(!WTF::IsTriviallyDestructible<Value>::value);
   HeapObjectHeader* header = HeapObjectHeader::FromPayload(pointer);
   // Use the payload size as recorded by the heap to determine how many
   // elements to finalize.
diff --git a/third_party/WebKit/Source/platform/heap/HeapLinkedStack.h b/third_party/WebKit/Source/platform/heap/HeapLinkedStack.h
index 090e4669..c207cf9 100644
--- a/third_party/WebKit/Source/platform/heap/HeapLinkedStack.h
+++ b/third_party/WebKit/Source/platform/heap/HeapLinkedStack.h
@@ -98,7 +98,8 @@
 
 template <typename T>
 inline void HeapLinkedStack<T>::Pop() {
-  ASSERT(head_ && size_);
+  DCHECK(head_);
+  DCHECK(size_);
   head_ = head_->next_;
   --size_;
 }
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.cpp b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
index 634336c..e61b69a 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
@@ -61,7 +61,7 @@
 #define ASAN_RETIRE_CONTAINER_ANNOTATION(object, objectSize)          \
   do {                                                                \
     BasePage* page = PageFromObject(object);                          \
-    ASSERT(page);                                                     \
+    DCHECK(page);                                                     \
     bool is_container =                                               \
         ThreadState::IsVectorArenaIndex(page->Arena()->ArenaIndex()); \
     if (!is_container && page->IsLargeObjectPage())                   \
@@ -77,7 +77,7 @@
 #define ASAN_MARK_LARGE_VECTOR_CONTAINER(arena, large_object)            \
   if (ThreadState::IsVectorArenaIndex(arena->ArenaIndex())) {            \
     BasePage* large_page = PageFromObject(large_object);                 \
-    ASSERT(large_page->IsLargeObjectPage());                             \
+    DCHECK(large_page->IsLargeObjectPage());                             \
     static_cast<LargeObjectPage*>(large_page)->SetIsVectorBackingPage(); \
   }
 #else
@@ -112,14 +112,14 @@
       index_(index) {}
 
 BaseArena::~BaseArena() {
-  ASSERT(!first_page_);
-  ASSERT(!first_unswept_page_);
+  DCHECK(!first_page_);
+  DCHECK(!first_unswept_page_);
 }
 
 void BaseArena::RemoveAllPages() {
   ClearFreeLists();
 
-  ASSERT(!first_unswept_page_);
+  DCHECK(!first_unswept_page_);
   while (first_page_) {
     BasePage* page = first_page_;
     page->Unlink(&first_page_);
@@ -171,7 +171,9 @@
 
 void BaseArena::MakeConsistentForGC() {
   ClearFreeLists();
-  ASSERT(IsConsistentForGC());
+#if DCHECK_IS_ON()
+  DCHECK(IsConsistentForGC());
+#endif
   for (BasePage* page = first_page_; page; page = page->Next()) {
     page->MarkAsUnswept();
     page->InvalidateObjectStartBitmap();
@@ -194,8 +196,10 @@
 
 void BaseArena::MakeConsistentForMutator() {
   ClearFreeLists();
-  ASSERT(IsConsistentForGC());
-  ASSERT(!first_page_);
+#if DCHECK_IS_ON()
+  DCHECK(IsConsistentForGC());
+#endif
+  DCHECK(!first_page_);
 
   // Drop marks from marked objects and rebuild free lists in preparation for
   // resuming the executions of mutators.
@@ -207,17 +211,19 @@
     page->InvalidateObjectStartBitmap();
   }
   if (previous_page) {
-    ASSERT(first_unswept_page_);
+    DCHECK(first_unswept_page_);
     previous_page->next_ = first_page_;
     first_page_ = first_unswept_page_;
     first_unswept_page_ = nullptr;
   }
-  ASSERT(!first_unswept_page_);
+  DCHECK(!first_unswept_page_);
 }
 
 size_t BaseArena::ObjectPayloadSizeForTesting() {
-  ASSERT(IsConsistentForGC());
-  ASSERT(!first_unswept_page_);
+#if DCHECK_IS_ON()
+  DCHECK(IsConsistentForGC());
+#endif
+  DCHECK(!first_unswept_page_);
 
   size_t object_payload_size = 0;
   for (BasePage* page = first_page_; page; page = page->Next())
@@ -226,8 +232,8 @@
 }
 
 void BaseArena::PrepareForSweep() {
-  ASSERT(GetThreadState()->IsInGC());
-  ASSERT(!first_unswept_page_);
+  DCHECK(GetThreadState()->IsInGC());
+  DCHECK(!first_unswept_page_);
 
   // Move all pages to a list of unswept pages.
   first_unswept_page_ = first_page_;
@@ -290,8 +296,8 @@
   static const int kDeadlineCheckInterval = 10;
 
   CHECK(GetThreadState()->IsSweepingInProgress());
-  ASSERT(GetThreadState()->SweepForbidden());
-  ASSERT(!GetThreadState()->IsMainThread() ||
+  DCHECK(GetThreadState()->SweepForbidden());
+  DCHECK(!GetThreadState()->IsMainThread() ||
          ScriptForbiddenScope::IsScriptForbidden());
 
   NormalPageArena* normal_arena = nullptr;
@@ -324,8 +330,8 @@
 
 void BaseArena::CompleteSweep() {
   CHECK(GetThreadState()->IsSweepingInProgress());
-  ASSERT(GetThreadState()->SweepForbidden());
-  ASSERT(!GetThreadState()->IsMainThread() ||
+  DCHECK(GetThreadState()->SweepForbidden());
+  DCHECK(!GetThreadState()->IsMainThread() ||
          ScriptForbiddenScope::IsScriptForbidden());
 
   while (first_unswept_page_) {
@@ -667,7 +673,7 @@
   if (GetThreadState()->SweepForbidden())
     return false;
 
-  ASSERT(!HasCurrentAllocationArea());
+  DCHECK(!HasCurrentAllocationArea());
   TRACE_EVENT0("blink_gc", "BaseArena::coalesce");
 
   // Rebuild free lists.
@@ -681,11 +687,11 @@
       HeapObjectHeader* header =
           reinterpret_cast<HeapObjectHeader*>(header_address);
       size_t size = header->size();
-      ASSERT(size > 0);
-      ASSERT(size < BlinkPagePayloadSize());
+      DCHECK_GT(size, 0u);
+      DCHECK_LT(size, BlinkPagePayloadSize());
 
       if (header->IsPromptlyFreed()) {
-        ASSERT(size >= sizeof(HeapObjectHeader));
+        DCHECK_GE(size, sizeof(HeapObjectHeader));
         // Zero the memory in the free list header to maintain the
         // invariant that memory on the free list is zero filled.
         // The rest of the memory is already on the free list and is
@@ -719,20 +725,21 @@
       AddToFreeList(start_of_gap, page->PayloadEnd() - start_of_gap);
   }
   GetThreadState()->DecreaseAllocatedObjectSize(freed_size);
-  ASSERT(promptly_freed_size_ == freed_size);
+  DCHECK_EQ(promptly_freed_size_, freed_size);
   promptly_freed_size_ = 0;
   return true;
 }
 
 void NormalPageArena::PromptlyFreeObject(HeapObjectHeader* header) {
-  ASSERT(!GetThreadState()->SweepForbidden());
+  DCHECK(!GetThreadState()->SweepForbidden());
   Address address = reinterpret_cast<Address>(header);
   Address payload = header->Payload();
   size_t size = header->size();
   size_t payload_size = header->PayloadSize();
-  ASSERT(size > 0);
-  ASSERT(PageFromObject(address) == FindPageFromAddress(address));
-
+  DCHECK_GT(size, 0u);
+#if DCHECK_IS_ON()
+  DCHECK_EQ(PageFromObject(address), FindPageFromAddress(address));
+#endif
   {
     ThreadState::SweepForbiddenScope forbidden_scope(GetThreadState());
     header->Finalize(payload, payload_size);
@@ -756,26 +763,28 @@
   if (header->PayloadSize() >= new_size)
     return true;
   size_t allocation_size = ThreadHeap::AllocationSizeFromSize(new_size);
-  ASSERT(allocation_size > header->size());
+  DCHECK_GT(allocation_size, header->size());
   size_t expand_size = allocation_size - header->size();
   if (IsObjectAllocatedAtAllocationPoint(header) &&
       expand_size <= remaining_allocation_size_) {
     current_allocation_point_ += expand_size;
-    ASSERT(remaining_allocation_size_ >= expand_size);
+    DCHECK_GE(remaining_allocation_size_, expand_size);
     SetRemainingAllocationSize(remaining_allocation_size_ - expand_size);
     // Unpoison the memory used for the object (payload).
     SET_MEMORY_ACCESSIBLE(header->PayloadEnd(), expand_size);
     header->SetSize(allocation_size);
-    ASSERT(FindPageFromAddress(header->PayloadEnd() - 1));
+#if DCHECK_IS_ON()
+    DCHECK(FindPageFromAddress(header->PayloadEnd() - 1));
+#endif
     return true;
   }
   return false;
 }
 
 bool NormalPageArena::ShrinkObject(HeapObjectHeader* header, size_t new_size) {
-  ASSERT(header->PayloadSize() > new_size);
+  DCHECK_GT(header->PayloadSize(), new_size);
   size_t allocation_size = ThreadHeap::AllocationSizeFromSize(new_size);
-  ASSERT(header->size() > allocation_size);
+  DCHECK_GT(header->size(), allocation_size);
   size_t shrink_size = header->size() - allocation_size;
   if (IsObjectAllocatedAtAllocationPoint(header)) {
     current_allocation_point_ -= shrink_size;
@@ -784,14 +793,16 @@
     header->SetSize(allocation_size);
     return true;
   }
-  ASSERT(shrink_size >= sizeof(HeapObjectHeader));
-  ASSERT(header->GcInfoIndex() > 0);
+  DCHECK_GE(shrink_size, sizeof(HeapObjectHeader));
+  DCHECK_GT(header->GcInfoIndex(), 0u);
   Address shrink_address = header->PayloadEnd() - shrink_size;
   HeapObjectHeader* freed_header = new (NotNull, shrink_address)
       HeapObjectHeader(shrink_size, header->GcInfoIndex());
   freed_header->MarkPromptlyFreed();
-  ASSERT(PageFromObject(reinterpret_cast<Address>(header)) ==
-         FindPageFromAddress(reinterpret_cast<Address>(header)));
+#if DCHECK_IS_ON()
+  DCHECK_EQ(PageFromObject(reinterpret_cast<Address>(header)),
+            FindPageFromAddress(reinterpret_cast<Address>(header)));
+#endif
   promptly_freed_size_ += shrink_size;
   header->SetSize(allocation_size);
   SET_MEMORY_INACCESSIBLE(shrink_address + sizeof(HeapObjectHeader),
@@ -801,7 +812,7 @@
 
 Address NormalPageArena::LazySweepPages(size_t allocation_size,
                                         size_t gc_info_index) {
-  ASSERT(!HasCurrentAllocationArea());
+  DCHECK(!HasCurrentAllocationArea());
   AutoReset<bool> is_lazy_sweeping(&is_lazy_sweeping_, true);
   Address result = nullptr;
   while (first_unswept_page_) {
@@ -850,16 +861,16 @@
         last_remaining_allocation_size_ - RemainingAllocationSize());
     last_remaining_allocation_size_ = RemainingAllocationSize();
   }
-  ASSERT(last_remaining_allocation_size_ == RemainingAllocationSize());
+  DCHECK_EQ(last_remaining_allocation_size_, RemainingAllocationSize());
 }
 
 void NormalPageArena::SetAllocationPoint(Address point, size_t size) {
 #if DCHECK_IS_ON()
   if (point) {
-    ASSERT(size);
+    DCHECK(size);
     BasePage* page = PageFromObject(point);
-    ASSERT(!page->IsLargeObjectPage());
-    ASSERT(size <= static_cast<NormalPage*>(page)->PayloadSize());
+    DCHECK(!page->IsLargeObjectPage());
+    DCHECK_LE(size, static_cast<NormalPage*>(page)->PayloadSize());
   }
 #endif
   if (HasCurrentAllocationArea()) {
@@ -872,8 +883,8 @@
 
 Address NormalPageArena::OutOfLineAllocate(size_t allocation_size,
                                            size_t gc_info_index) {
-  ASSERT(allocation_size > RemainingAllocationSize());
-  ASSERT(allocation_size >= kAllocationGranularity);
+  DCHECK_GT(allocation_size, RemainingAllocationSize());
+  DCHECK_GE(allocation_size, kAllocationGranularity);
 
   // 1. If this allocation is big enough, allocate a large object.
   if (allocation_size >= kLargeObjectSizeThreshold)
@@ -939,8 +950,8 @@
     if (entry) {
       entry->Unlink(&free_list_.free_lists_[index]);
       SetAllocationPoint(entry->GetAddress(), entry->size());
-      ASSERT(HasCurrentAllocationArea());
-      ASSERT(RemainingAllocationSize() >= allocation_size);
+      DCHECK(HasCurrentAllocationArea());
+      DCHECK_GE(RemainingAllocationSize(), allocation_size);
       free_list_.biggest_free_list_index_ = index;
       return AllocateObject(allocation_size, gc_info_index);
     }
@@ -956,7 +967,7 @@
                                                   size_t gc_info_index) {
   // Caller already added space for object header and rounded up to allocation
   // alignment
-  ASSERT(!(allocation_size & kAllocationMask));
+  DCHECK(!(allocation_size & kAllocationMask));
 
   // 1. Try to sweep large objects more than allocationSize bytes
   // before allocating a new large object.
@@ -993,13 +1004,13 @@
 #if DCHECK_IS_ON()
   // Verify that the allocated PageMemory is expectedly zeroed.
   for (size_t i = 0; i < large_object_size; ++i)
-    ASSERT(!large_object_address[i]);
+    DCHECK(!large_object_address[i]);
 #endif
-  ASSERT(gc_info_index > 0);
+  DCHECK_GT(gc_info_index, 0u);
   HeapObjectHeader* header = new (NotNull, header_address)
       HeapObjectHeader(kLargeObjectSizeInHeader, gc_info_index);
   Address result = header_address + sizeof(*header);
-  ASSERT(!(reinterpret_cast<uintptr_t>(result) & kAllocationMask));
+  DCHECK(!(reinterpret_cast<uintptr_t>(result) & kAllocationMask));
   LargeObjectPage* large_object = new (large_object_address)
       LargeObjectPage(page_memory, this, allocation_size);
 
@@ -1049,7 +1060,7 @@
       // more than allocationSize bytes.
       if (swept_size >= allocation_size) {
         result = DoAllocateLargeObjectPage(allocation_size, gc_info_index);
-        ASSERT(result);
+        DCHECK(result);
         break;
       }
     } else {
@@ -1067,17 +1078,17 @@
 FreeList::FreeList() : biggest_free_list_index_(0) {}
 
 void FreeList::AddToFreeList(Address address, size_t size) {
-  ASSERT(size < BlinkPagePayloadSize());
+  DCHECK_LT(size, BlinkPagePayloadSize());
   // The free list entries are only pointer aligned (but when we allocate
   // from them we are 8 byte aligned due to the header size).
-  ASSERT(!((reinterpret_cast<uintptr_t>(address) + sizeof(HeapObjectHeader)) &
+  DCHECK(!((reinterpret_cast<uintptr_t>(address) + sizeof(HeapObjectHeader)) &
            kAllocationMask));
-  ASSERT(!(size & kAllocationMask));
+  DCHECK(!(size & kAllocationMask));
   ASAN_UNPOISON_MEMORY_REGION(address, size);
   FreeListEntry* entry;
   if (size < sizeof(*entry)) {
     // Create a dummy header with only a size and freelist bit set.
-    ASSERT(size >= sizeof(HeapObjectHeader));
+    DCHECK_GE(size, sizeof(HeapObjectHeader));
     // Free list encode the size to mark the lost memory as freelist memory.
     new (NotNull, address)
         HeapObjectHeader(size, kGcInfoIndexForFreeListHeader);
@@ -1162,7 +1173,7 @@
 void NEVER_INLINE FreeList::CheckFreedMemoryIsZapped(Address address,
                                                      size_t size) {
   for (size_t i = 0; i < size; i++) {
-    ASSERT(address[i] == kReuseAllowedZapValue ||
+    DCHECK(address[i] == kReuseAllowedZapValue ||
            address[i] == kReuseForbiddenZapValue);
   }
 }
@@ -1206,7 +1217,7 @@
 }
 
 int FreeList::BucketIndexForSize(size_t size) {
-  ASSERT(size > 0);
+  DCHECK_GT(size, 0u);
   int index = -1;
   while (size) {
     size >>= 1;
@@ -1240,28 +1251,32 @@
 
 BasePage::BasePage(PageMemory* storage, BaseArena* arena)
     : storage_(storage), arena_(arena), next_(nullptr), swept_(true) {
-  ASSERT(IsPageHeaderAddress(reinterpret_cast<Address>(this)));
+#if DCHECK_IS_ON()
+  DCHECK(IsPageHeaderAddress(reinterpret_cast<Address>(this)));
+#endif
 }
 
 NormalPage::NormalPage(PageMemory* storage, BaseArena* arena)
     : BasePage(storage, arena), object_start_bit_map_computed_(false) {
-  ASSERT(IsPageHeaderAddress(reinterpret_cast<Address>(this)));
+#if DCHECK_IS_ON()
+  DCHECK(IsPageHeaderAddress(reinterpret_cast<Address>(this)));
+#endif
 }
 
 size_t NormalPage::ObjectPayloadSizeForTesting() {
   size_t object_payload_size = 0;
   Address header_address = Payload();
   MarkAsSwept();
-  ASSERT(header_address != PayloadEnd());
+  DCHECK_NE(header_address, PayloadEnd());
   do {
     HeapObjectHeader* header =
         reinterpret_cast<HeapObjectHeader*>(header_address);
     if (!header->IsFree()) {
       object_payload_size += header->PayloadSize();
     }
-    ASSERT(header->size() < BlinkPagePayloadSize());
+    DCHECK_LT(header->size(), BlinkPagePayloadSize());
     header_address += header->size();
-    ASSERT(header_address <= PayloadEnd());
+    DCHECK_LE(header_address, PayloadEnd());
   } while (header_address < PayloadEnd());
   return object_payload_size;
 }
@@ -1295,8 +1310,8 @@
     HeapObjectHeader* header =
         reinterpret_cast<HeapObjectHeader*>(header_address);
     size_t size = header->size();
-    ASSERT(size > 0);
-    ASSERT(size < BlinkPagePayloadSize());
+    DCHECK_GT(size, 0u);
+    DCHECK_LT(size, BlinkPagePayloadSize());
 
     if (header->IsPromptlyFreed())
       page_arena->DecreasePromptlyFreedSize(size);
@@ -1370,7 +1385,8 @@
     HeapObjectHeader* header =
         reinterpret_cast<HeapObjectHeader*>(header_address);
     size_t size = header->size();
-    DCHECK(size > 0 && size < BlinkPagePayloadSize());
+    DCHECK_GT(size, 0u);
+    DCHECK_LT(size, BlinkPagePayloadSize());
 
     if (header->IsPromptlyFreed())
       page_arena->DecreasePromptlyFreedSize(size);
@@ -1470,7 +1486,7 @@
     HeapObjectHeader* header =
         reinterpret_cast<HeapObjectHeader*>(header_address);
     size_t size = header->size();
-    ASSERT(size < BlinkPagePayloadSize());
+    DCHECK_LT(size, BlinkPagePayloadSize());
     if (header->IsPromptlyFreed())
       ArenaForNormalPage()->DecreasePromptlyFreedSize(size);
     if (header->IsFree()) {
@@ -1491,7 +1507,7 @@
       header->Unmark();
     header_address += size;
     start_of_gap = header_address;
-    ASSERT(header_address <= PayloadEnd());
+    DCHECK_LE(header_address, PayloadEnd());
   }
   if (start_of_gap != PayloadEnd())
     normal_arena->AddToFreeList(start_of_gap, PayloadEnd() - start_of_gap);
@@ -1502,7 +1518,7 @@
   for (Address header_address = Payload(); header_address < PayloadEnd();) {
     HeapObjectHeader* header =
         reinterpret_cast<HeapObjectHeader*>(header_address);
-    ASSERT(header->size() < BlinkPagePayloadSize());
+    DCHECK_LT(header->size(), BlinkPagePayloadSize());
     // Check if a free list entry first since we cannot call
     // isMarked on a free list entry.
     if (header->IsFree()) {
@@ -1523,13 +1539,13 @@
     HeapObjectHeader* header =
         reinterpret_cast<HeapObjectHeader*>(header_address);
     size_t object_offset = header_address - start;
-    ASSERT(!(object_offset & kAllocationMask));
+    DCHECK(!(object_offset & kAllocationMask));
     size_t object_start_number = object_offset / kAllocationGranularity;
     size_t map_index = object_start_number / 8;
-    ASSERT(map_index < kObjectStartBitMapSize);
+    DCHECK_LT(map_index, kObjectStartBitMapSize);
     object_start_bit_map_[map_index] |= (1 << (object_start_number & 7));
     header_address += header->size();
-    ASSERT(header_address <= PayloadEnd());
+    DCHECK_LE(header_address, PayloadEnd());
   }
   object_start_bit_map_computed_ = true;
 }
@@ -1559,11 +1575,11 @@
   size_t object_offset = address - Payload();
   size_t object_start_number = object_offset / kAllocationGranularity;
   size_t map_index = object_start_number / 8;
-  ASSERT(map_index < kObjectStartBitMapSize);
+  DCHECK_LT(map_index, kObjectStartBitMapSize);
   size_t bit = object_start_number & 7;
   uint8_t byte = object_start_bit_map_[map_index] & ((1 << (bit + 1)) - 1);
   while (!byte) {
-    ASSERT(map_index > 0);
+    DCHECK_GT(map_index, 0u);
     byte = object_start_bit_map_[--map_index];
   }
   int leading_zeroes = NumberOfLeadingZeroes(byte);
@@ -1604,7 +1620,9 @@
     // has not yet been initialized. In this case, we should mark the A
     // object without tracing any member of the A object.
     visitor->MarkHeaderNoTracing(header);
-    ASSERT(IsUninitializedMemory(header->Payload(), header->PayloadSize()));
+#if DCHECK_IS_ON()
+    DCHECK(IsUninitializedMemory(header->Payload(), header->PayloadSize()));
+#endif
   } else {
     visitor->MarkHeader(header, gc_info->trace_);
   }
@@ -1680,7 +1698,7 @@
 bool NormalPage::Contains(Address addr) {
   Address blink_page_start = RoundToBlinkPageStart(GetAddress());
   // Page is at aligned address plus guard page size.
-  ASSERT(blink_page_start == GetAddress() - kBlinkGuardPageSize);
+  DCHECK_EQ(blink_page_start, GetAddress() - kBlinkGuardPageSize);
   return blink_page_start <= addr && addr < blink_page_start + kBlinkPageSize;
 }
 #endif
@@ -1804,10 +1822,10 @@
 }
 
 bool HeapDoesNotContainCache::Lookup(Address address) {
-  ASSERT(ThreadState::Current()->IsInGC());
+  DCHECK(ThreadState::Current()->IsInGC());
 
   size_t index = GetHash(address);
-  ASSERT(!(index & 1));
+  DCHECK(!(index & 1));
   Address cache_page = RoundToBlinkPageStart(address);
   if (entries_[index] == cache_page)
     return entries_[index];
@@ -1817,11 +1835,11 @@
 }
 
 void HeapDoesNotContainCache::AddEntry(Address address) {
-  ASSERT(ThreadState::Current()->IsInGC());
+  DCHECK(ThreadState::Current()->IsInGC());
 
   has_entries_ = true;
   size_t index = GetHash(address);
-  ASSERT(!(index & 1));
+  DCHECK(!(index & 1));
   Address cache_page = RoundToBlinkPageStart(address);
   entries_[index + 1] = entries_[index];
   entries_[index] = cache_page;
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.h b/third_party/WebKit/Source/platform/heap/HeapPage.h
index 5ee17b83..43019c6 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.h
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.h
@@ -187,9 +187,9 @@
     magic_ = GetMagic();
 #endif
 
-    ASSERT(gc_info_index < GCInfoTable::kMaxIndex);
-    ASSERT(size < kNonLargeObjectPageSizeMax);
-    ASSERT(!(size & kAllocationMask));
+    DCHECK(gc_info_index < GCInfoTable::kMaxIndex);
+    DCHECK_LT(size, kNonLargeObjectPageSizeMax);
+    DCHECK(!(size & kAllocationMask));
     encoded_ = static_cast<uint32_t>(
         (gc_info_index << kHeaderGCInfoIndexShift) | size |
         (gc_info_index == kGcInfoIndexForFreeListHeader ? kHeaderFreedBitMask
@@ -216,7 +216,7 @@
   }
 
   NO_SANITIZE_ADDRESS void SetSize(size_t size) {
-    ASSERT(size < kNonLargeObjectPageSizeMax);
+    DCHECK_LT(size, kNonLargeObjectPageSizeMax);
     CheckHeader();
     encoded_ = static_cast<uint32_t>(size) | (encoded_ & ~kHeaderSizeMask);
   }
@@ -275,7 +275,7 @@
   explicit FreeListEntry(size_t size)
       : HeapObjectHeader(size, kGcInfoIndexForFreeListHeader), next_(nullptr) {
 #if DCHECK_IS_ON() && CPU(64BIT)
-    ASSERT(size >= sizeof(HeapObjectHeader));
+    DCHECK_GE(size, sizeof(HeapObjectHeader));
     ZapMagic();
 #endif
   }
@@ -299,7 +299,7 @@
 
   NO_SANITIZE_ADDRESS
   void Append(FreeListEntry* next) {
-    ASSERT(!next_);
+    DCHECK(!next_);
     next_ = next;
   }
 
@@ -434,12 +434,12 @@
   bool HasBeenSwept() const { return swept_; }
 
   void MarkAsSwept() {
-    ASSERT(!swept_);
+    DCHECK(!swept_);
     swept_ = true;
   }
 
   void MarkAsUnswept() {
-    ASSERT(swept_);
+    DCHECK(swept_);
     swept_ = false;
   }
 
@@ -753,8 +753,10 @@
  public:
   NormalPageArena(ThreadState*, int);
   void AddToFreeList(Address address, size_t size) {
-    ASSERT(FindPageFromAddress(address));
-    ASSERT(FindPageFromAddress(address + size - 1));
+#if DCHECK_IS_ON()
+    DCHECK(FindPageFromAddress(address));
+    DCHECK(FindPageFromAddress(address + size - 1));
+#endif
     free_list_.AddToFreeList(address, size);
   }
   void ClearFreeLists() override;
@@ -837,7 +839,9 @@
   Address address = reinterpret_cast<Address>(const_cast<void*>(object));
   BasePage* page = reinterpret_cast<BasePage*>(BlinkPageAddress(address) +
                                                kBlinkGuardPageSize);
-  ASSERT(page->Contains(address));
+#if DCHECK_IS_ON()
+  DCHECK(page->Contains(address));
+#endif
   return page;
 }
 
@@ -845,8 +849,8 @@
   size_t result = encoded_ & kHeaderSizeMask;
   // Large objects should not refer to header->size(). The actual size of a
   // large object is stored in |LargeObjectPage::m_payloadSize|.
-  ASSERT(result != kLargeObjectSizeInHeader);
-  ASSERT(!PageFromObject(this)->IsLargeObjectPage());
+  DCHECK(result != kLargeObjectSizeInHeader);
+  DCHECK(!PageFromObject(this)->IsLargeObjectPage());
   return result;
 }
 
@@ -869,10 +873,10 @@
   CheckHeader();
   size_t size = encoded_ & kHeaderSizeMask;
   if (UNLIKELY(size == kLargeObjectSizeInHeader)) {
-    ASSERT(PageFromObject(this)->IsLargeObjectPage());
+    DCHECK(PageFromObject(this)->IsLargeObjectPage());
     return static_cast<LargeObjectPage*>(PageFromObject(this))->PayloadSize();
   }
-  ASSERT(!PageFromObject(this)->IsLargeObjectPage());
+  DCHECK(!PageFromObject(this)->IsLargeObjectPage());
   return size - sizeof(HeapObjectHeader);
 }
 
@@ -950,13 +954,13 @@
 
 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::MarkWrapperHeader() {
   CheckHeader();
-  ASSERT(!IsWrapperHeaderMarked());
+  DCHECK(!IsWrapperHeaderMarked());
   encoded_ |= kHeaderWrapperMarkBitMask;
 }
 
 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::UnmarkWrapperHeader() {
   CheckHeader();
-  ASSERT(IsWrapperHeaderMarked());
+  DCHECK(IsWrapperHeaderMarked());
   encoded_ &= ~kHeaderWrapperMarkBitMask;
 }
 
@@ -967,13 +971,13 @@
 
 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::Mark() {
   CheckHeader();
-  ASSERT(!IsMarked());
+  DCHECK(!IsMarked());
   encoded_ = encoded_ | kHeaderMarkBitMask;
 }
 
 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::Unmark() {
   CheckHeader();
-  ASSERT(IsMarked());
+  DCHECK(IsMarked());
   encoded_ &= ~kHeaderMarkBitMask;
 }
 
@@ -983,14 +987,16 @@
     Address header_address = current_allocation_point_;
     current_allocation_point_ += allocation_size;
     remaining_allocation_size_ -= allocation_size;
-    ASSERT(gc_info_index > 0);
+    DCHECK_GT(gc_info_index, 0u);
     new (NotNull, header_address)
         HeapObjectHeader(allocation_size, gc_info_index);
     Address result = header_address + sizeof(HeapObjectHeader);
-    ASSERT(!(reinterpret_cast<uintptr_t>(result) & kAllocationMask));
+    DCHECK(!(reinterpret_cast<uintptr_t>(result) & kAllocationMask));
 
     SET_MEMORY_ACCESSIBLE(result, allocation_size - sizeof(HeapObjectHeader));
-    ASSERT(FindPageFromAddress(header_address + allocation_size - 1));
+#if DCHECK_IS_ON()
+    DCHECK(FindPageFromAddress(header_address + allocation_size - 1));
+#endif
     return result;
   }
   return OutOfLineAllocate(allocation_size, gc_info_index);
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
index 429115d..6dd9eef4 100644
--- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -182,7 +182,7 @@
   // Regular constructor.
   PairWithWeakHandling(IntWrapper* one, IntWrapper* two)
       : StrongWeakPair(one, two) {
-    ASSERT(one);  // We use null first field to indicate empty slots in the hash
+    DCHECK(one);  // We use null first field to indicate empty slots in the hash
                   // table.
   }
 
@@ -332,7 +332,7 @@
  public:
   explicit TestGCScope(BlinkGC::StackState state)
       : state_(ThreadState::Current()), safe_point_scope_(state) {
-    ASSERT(state_->CheckThread());
+    DCHECK(state_->CheckThread());
     state_->PreGC();
   }
 
@@ -518,7 +518,7 @@
     // Verify that the threads cleared their CTPs when
     // terminating, preventing access to a finalized heap.
     for (auto& global_int_wrapper : cross_persistents_) {
-      ASSERT(global_int_wrapper.get());
+      DCHECK(global_int_wrapper.get());
       EXPECT_FALSE(global_int_wrapper.get()->Get());
     }
   }
@@ -937,15 +937,17 @@
 
   void Ref() {
     if (UNLIKELY(!ref_count_)) {
-      ASSERT(ThreadState::Current()->FindPageFromAddress(
+#if DCHECK_IS_ON()
+      DCHECK(ThreadState::Current()->FindPageFromAddress(
           reinterpret_cast<Address>(this)));
+#endif
       keep_alive_ = this;
     }
     ++ref_count_;
   }
 
   void Deref() {
-    ASSERT(ref_count_ > 0);
+    DCHECK_GT(ref_count_, 0);
     if (!--ref_count_)
       keep_alive_.Clear();
   }
@@ -975,15 +977,17 @@
 
   void Ref() {
     if (UNLIKELY(!ref_count_)) {
-      ASSERT(ThreadState::Current()->FindPageFromAddress(
+#if DCHECK_IS_ON()
+      DCHECK(ThreadState::Current()->FindPageFromAddress(
           reinterpret_cast<Address>(this)));
+#endif
       keep_alive_ = this;
     }
     ++ref_count_;
   }
 
   void Deref() {
-    ASSERT(ref_count_ > 0);
+    DCHECK_GT(ref_count_, 0);
     if (!--ref_count_)
       keep_alive_.Clear();
   }
@@ -1215,7 +1219,7 @@
       result.stored_value->value =
           WTF::MakeUnique<FinalizationObserverWithHashMap>(target);
     } else {
-      ASSERT(result.stored_value->value);
+      DCHECK(result.stored_value->value);
     }
     return map;
   }
@@ -2091,11 +2095,15 @@
   {
     Bar::live_ = 0;
     Persistent<Bar> bar = Bar::Create();
-    ASSERT(ThreadState::Current()->FindPageFromAddress(bar));
+#if DCHECK_IS_ON()
+    DCHECK(ThreadState::Current()->FindPageFromAddress(bar));
+#endif
     EXPECT_EQ(1u, Bar::live_);
     {
       Foo* foo = Foo::Create(bar);
-      ASSERT(ThreadState::Current()->FindPageFromAddress(foo));
+#if DCHECK_IS_ON()
+      DCHECK(ThreadState::Current()->FindPageFromAddress(foo));
+#endif
       EXPECT_EQ(2u, Bar::live_);
       EXPECT_TRUE(reinterpret_cast<Address>(foo) !=
                   reinterpret_cast<Address>(bar.Get()));
@@ -2115,14 +2123,20 @@
   Bar::live_ = 0;
   {
     Bar* bar = Bar::Create();
-    ASSERT(ThreadState::Current()->FindPageFromAddress(bar));
+#if DCHECK_IS_ON()
+    DCHECK(ThreadState::Current()->FindPageFromAddress(bar));
+#endif
     Foo* foo = Foo::Create(bar);
-    ASSERT(ThreadState::Current()->FindPageFromAddress(foo));
+#if DCHECK_IS_ON()
+    DCHECK(ThreadState::Current()->FindPageFromAddress(foo));
+#endif
     EXPECT_EQ(2u, Bar::live_);
     for (unsigned i = 0; i < kDepth; i++) {
       Foo* foo2 = Foo::Create(foo);
       foo = foo2;
-      ASSERT(ThreadState::Current()->FindPageFromAddress(foo));
+#if DCHECK_IS_ON()
+      DCHECK(ThreadState::Current()->FindPageFromAddress(foo));
+#endif
     }
     EXPECT_EQ(kDepth + 2, Bar::live_);
     ConservativelyCollectGarbage();
@@ -2265,9 +2279,11 @@
     int slack =
         8;  // LargeHeapObject points to an IntWrapper that is also allocated.
     Persistent<LargeHeapObject> object = LargeHeapObject::Create();
-    ASSERT(ThreadState::Current()->FindPageFromAddress(object));
-    ASSERT(ThreadState::Current()->FindPageFromAddress(
+#if DCHECK_IS_ON()
+    DCHECK(ThreadState::Current()->FindPageFromAddress(object));
+    DCHECK(ThreadState::Current()->FindPageFromAddress(
         reinterpret_cast<char*>(object.Get()) + sizeof(LargeHeapObject) - 1));
+#endif
     ClearOutOldGarbage();
     size_t after_allocation = heap.HeapStats().AllocatedSpace();
     {
@@ -5657,7 +5673,7 @@
 }
 
 static bool CheckGCForbidden() {
-  ASSERT(ThreadState::Current()->IsGCForbidden());
+  DCHECK(ThreadState::Current()->IsGCForbidden());
   return true;
 }
 
@@ -6211,7 +6227,7 @@
     previous = nullptr;
     return result;
   }
-  ASSERT(&dummy != previous);
+  DCHECK_NE(&dummy, previous);
   return &dummy < previous ? kGrowsTowardsLower : kGrowsTowardsHigher;
 }
 
@@ -6232,7 +6248,7 @@
   TestMixinAllocationA() {
     // Completely wrong in general, but test only
     // runs this constructor while constructing another mixin.
-    ASSERT(ThreadState::Current()->IsGCForbidden());
+    DCHECK(ThreadState::Current()->IsGCForbidden());
   }
 
   DEFINE_INLINE_VIRTUAL_TRACE() {}
@@ -6248,7 +6264,7 @@
   {
     // Completely wrong in general, but test only
     // runs this constructor while constructing another mixin.
-    ASSERT(ThreadState::Current()->IsGCForbidden());
+    DCHECK(ThreadState::Current()->IsGCForbidden());
   }
 
   DEFINE_INLINE_TRACE() {
@@ -6264,7 +6280,7 @@
   USING_GARBAGE_COLLECTED_MIXIN(TestMixinAllocationC);
 
  public:
-  TestMixinAllocationC() { ASSERT(!ThreadState::Current()->IsGCForbidden()); }
+  TestMixinAllocationC() { DCHECK(!ThreadState::Current()->IsGCForbidden()); }
 
   DEFINE_INLINE_TRACE() { TestMixinAllocationB::Trace(visitor); }
 };
@@ -6283,7 +6299,7 @@
     // and it is a base of GC mixin, GCs will remain locked out
     // regardless, as we cannot safely trace the leftmost GC
     // mixin base.
-    ASSERT(ThreadState::Current()->IsGCForbidden());
+    DCHECK(ThreadState::Current()->IsGCForbidden());
     for (size_t i = 0; i < number_of_large_objects_to_allocate; i++) {
       LargeHeapObject* large_object = LargeHeapObject::Create();
       EXPECT_TRUE(large_object);
@@ -6313,7 +6329,7 @@
   TestMixinAllocatingObject(ClassWithMember* member)
       : ObjectWithLargeAmountsOfAllocationInConstructor(600, member),
         trace_counter_(TraceCounter::Create()) {
-    ASSERT(!ThreadState::Current()->IsGCForbidden());
+    DCHECK(!ThreadState::Current()->IsGCForbidden());
     ConservativelyCollectGarbage();
     EXPECT_GT(member->TraceCount(), 0);
     EXPECT_GT(TraceCount(), 0);
diff --git a/third_party/WebKit/Source/platform/heap/PageMemory.cpp b/third_party/WebKit/Source/platform/heap/PageMemory.cpp
index 169be5a5..96c5e2a 100644
--- a/third_party/WebKit/Source/platform/heap/PageMemory.cpp
+++ b/third_party/WebKit/Source/platform/heap/PageMemory.cpp
@@ -83,14 +83,14 @@
       current = current->right_;
       continue;
     }
-    ASSERT(current->region_->Contains(address));
+    DCHECK(current->region_->Contains(address));
     return current->region_;
   }
   return nullptr;
 }
 
 void RegionTree::Add(PageMemoryRegion* region) {
-  ASSERT(region);
+  DCHECK(region);
   RegionTreeNode* new_tree = new RegionTreeNode(region);
   new_tree->AddTo(&root_);
 }
@@ -98,7 +98,7 @@
 void RegionTreeNode::AddTo(RegionTreeNode** context) {
   Address base = region_->Base();
   for (RegionTreeNode* current = *context; current; current = *context) {
-    ASSERT(!current->region_->Contains(base));
+    DCHECK(!current->region_->Contains(base));
     context =
         (base < current->region_->Base()) ? &current->left_ : &current->right_;
   }
@@ -106,8 +106,8 @@
 }
 
 void RegionTree::Remove(PageMemoryRegion* region) {
-  ASSERT(region);
-  ASSERT(root_);
+  DCHECK(region);
+  DCHECK(root_);
   Address base = region->Base();
   RegionTreeNode** context = &root_;
   RegionTreeNode* current = root_;
@@ -136,7 +136,7 @@
 
 PageMemory::PageMemory(PageMemoryRegion* reserved, const MemoryRegion& writable)
     : reserved_(reserved), writable_(writable) {
-  ASSERT(reserved->Contains(writable));
+  DCHECK(reserved->Contains(writable));
 
   // Register the writable area of the memory as part of the LSan root set.
   // Only the writable area is mapped and can contain C++ objects.  Those
@@ -158,7 +158,7 @@
 }
 
 PageMemory* PageMemory::Allocate(size_t payload_size, RegionTree* region_tree) {
-  ASSERT(payload_size > 0);
+  DCHECK_GT(payload_size, 0u);
 
   // Virtual memory allocation routines operate in OS page sizes.
   // Round up the requested size to nearest os page size.
diff --git a/third_party/WebKit/Source/platform/heap/PageMemory.h b/third_party/WebKit/Source/platform/heap/PageMemory.h
index 334cf67..c985915 100644
--- a/third_party/WebKit/Source/platform/heap/PageMemory.h
+++ b/third_party/WebKit/Source/platform/heap/PageMemory.h
@@ -21,7 +21,7 @@
 
  public:
   MemoryRegion(Address base, size_t size) : base_(base), size_(size) {
-    ASSERT(size > 0);
+    DCHECK_GT(size, 0u);
   }
 
   bool Contains(Address addr) const {
@@ -57,7 +57,7 @@
   void PageDeleted(Address);
 
   void MarkPageUsed(Address page) {
-    ASSERT(!in_use_[Index(page)]);
+    DCHECK(!in_use_[Index(page)]);
     in_use_[Index(page)] = true;
   }
 
@@ -74,7 +74,7 @@
   }
 
   BasePage* PageFromAddress(Address address) {
-    ASSERT(Contains(address));
+    DCHECK(Contains(address));
     if (!in_use_[Index(address)])
       return nullptr;
     if (is_large_page_)
@@ -86,11 +86,11 @@
   PageMemoryRegion(Address base, size_t, unsigned num_pages, RegionTree*);
 
   unsigned Index(Address address) const {
-    ASSERT(Contains(address));
+    DCHECK(Contains(address));
     if (is_large_page_)
       return 0;
     size_t offset = BlinkPageAddress(address) - Base();
-    ASSERT(offset % kBlinkPageSize == 0);
+    DCHECK_EQ(offset % kBlinkPageSize, 0u);
     return offset / kBlinkPageSize;
   }
 
diff --git a/third_party/WebKit/Source/platform/heap/PagePool.cpp b/third_party/WebKit/Source/platform/heap/PagePool.cpp
index 2277333..4af09bc 100644
--- a/third_party/WebKit/Source/platform/heap/PagePool.cpp
+++ b/third_party/WebKit/Source/platform/heap/PagePool.cpp
@@ -21,7 +21,7 @@
     while (PoolEntry* entry = pool_[index]) {
       pool_[index] = entry->next;
       PageMemory* memory = entry->data;
-      ASSERT(memory);
+      DCHECK(memory);
       delete memory;
       delete entry;
     }
@@ -41,7 +41,7 @@
   while (PoolEntry* entry = pool_[index]) {
     pool_[index] = entry->next;
     PageMemory* memory = entry->data;
-    ASSERT(memory);
+    DCHECK(memory);
     delete entry;
     if (memory->Commit())
       return memory;
diff --git a/third_party/WebKit/Source/platform/heap/Persistent.h b/third_party/WebKit/Source/platform/heap/Persistent.h
index 536111b..443de36e 100644
--- a/third_party/WebKit/Source/platform/heap/Persistent.h
+++ b/third_party/WebKit/Source/platform/heap/Persistent.h
@@ -166,7 +166,7 @@
   // needing to be cleared out before the thread is terminated.
   PersistentBase* RegisterAsStaticReference() {
     if (persistent_node_) {
-      ASSERT(ThreadState::Current());
+      DCHECK(ThreadState::Current());
       ThreadState::Current()->RegisterStaticPersistentNode(persistent_node_,
                                                            nullptr);
       LEAK_SANITIZER_IGNORE_OBJECT(this);
@@ -214,7 +214,7 @@
 
   NO_SANITIZE_ADDRESS
   void Initialize() {
-    ASSERT(!persistent_node_);
+    DCHECK(!persistent_node_);
     if (!raw_ || IsHashTableDeletedValue())
       return;
 
@@ -228,7 +228,7 @@
     }
     ThreadState* state =
         ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
-    ASSERT(state->CheckThread());
+    DCHECK(state->CheckThread());
     persistent_node_ = state->GetPersistentRegion()->AllocatePersistentNode(
         this, trace_callback);
 #if DCHECK_IS_ON()
@@ -248,9 +248,11 @@
       return;
     ThreadState* state =
         ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
-    ASSERT(state->CheckThread());
+    DCHECK(state->CheckThread());
     // Persistent handle must be created and destructed in the same thread.
-    ASSERT(state_ == state);
+#if DCHECK_IS_ON()
+    DCHECK_EQ(state_, state);
+#endif
     state->FreePersistentNode(persistent_node_);
     persistent_node_ = nullptr;
   }
@@ -567,7 +569,7 @@
   // See PersistentBase::registerAsStaticReference() comment.
   PersistentHeapCollectionBase* RegisterAsStaticReference() {
     if (persistent_node_) {
-      ASSERT(ThreadState::Current());
+      DCHECK(ThreadState::Current());
       ThreadState::Current()->RegisterStaticPersistentNode(
           persistent_node_,
           &PersistentHeapCollectionBase<Collection>::ClearPersistentNode);
@@ -596,7 +598,7 @@
   void Initialize() {
     // FIXME: Derive affinity based on the collection.
     ThreadState* state = ThreadState::Current();
-    ASSERT(state->CheckThread());
+    DCHECK(state->CheckThread());
     persistent_node_ = state->GetPersistentRegion()->AllocatePersistentNode(
         this,
         TraceMethodDelegate<PersistentHeapCollectionBase<Collection>,
@@ -611,9 +613,11 @@
     if (!persistent_node_)
       return;
     ThreadState* state = ThreadState::Current();
-    ASSERT(state->CheckThread());
+    DCHECK(state->CheckThread());
     // Persistent handle must be created and destructed in the same thread.
-    ASSERT(state_ == state);
+#if DCHECK_IS_ON()
+    DCHECK_EQ(state_, state);
+#endif
     state->FreePersistentNode(persistent_node_);
     persistent_node_ = nullptr;
   }
diff --git a/third_party/WebKit/Source/platform/heap/PersistentNode.cpp b/third_party/WebKit/Source/platform/heap/PersistentNode.cpp
index 9e57c2a7..ff13ad3 100644
--- a/third_party/WebKit/Source/platform/heap/PersistentNode.cpp
+++ b/third_party/WebKit/Source/platform/heap/PersistentNode.cpp
@@ -42,13 +42,13 @@
 
 void PersistentRegion::EnsurePersistentNodeSlots(void* self,
                                                  TraceCallback trace) {
-  ASSERT(!free_list_head_);
+  DCHECK(!free_list_head_);
   PersistentNodeSlots* slots = new PersistentNodeSlots;
   for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) {
     PersistentNode* node = &slots->slot_[i];
     node->SetFreeListNext(free_list_head_);
     free_list_head_ = node;
-    ASSERT(node->IsUnused());
+    DCHECK(node->IsUnused());
   }
   slots->next_ = slots_;
   slots_ = slots;
@@ -57,18 +57,18 @@
 void PersistentRegion::ReleasePersistentNode(
     PersistentNode* persistent_node,
     ThreadState::PersistentClearCallback callback) {
-  ASSERT(!persistent_node->IsUnused());
+  DCHECK(!persistent_node->IsUnused());
   // 'self' is in use, containing the persistent wrapper object.
   void* self = persistent_node->Self();
   if (callback) {
     (*callback)(self);
-    ASSERT(persistent_node->IsUnused());
+    DCHECK(persistent_node->IsUnused());
     return;
   }
   Persistent<DummyGCBase>* persistent =
       reinterpret_cast<Persistent<DummyGCBase>*>(self);
   persistent->Clear();
-  ASSERT(persistent_node->IsUnused());
+  DCHECK(persistent_node->IsUnused());
 }
 
 // This function traces all PersistentNodes. If we encounter
@@ -111,8 +111,8 @@
       delete dead_slots;
     } else {
       if (free_list_last) {
-        ASSERT(free_list_next);
-        ASSERT(!free_list_last->FreeListNext());
+        DCHECK(free_list_next);
+        DCHECK(!free_list_last->FreeListNext());
         free_list_last->SetFreeListNext(free_list_head_);
         free_list_head_ = free_list_next;
       }
@@ -159,15 +159,15 @@
       CrossThreadPersistent<DummyGCBase>* persistent =
           reinterpret_cast<CrossThreadPersistent<DummyGCBase>*>(
               slots->slot_[i].Self());
-      ASSERT(persistent);
+      DCHECK(persistent);
       void* raw_object = persistent->AtomicGet();
       if (!raw_object)
         continue;
       BasePage* page = PageFromObject(raw_object);
-      ASSERT(page);
+      DCHECK(page);
       if (page->Arena()->GetThreadState() == thread_state) {
         persistent->Clear();
-        ASSERT(slots->slot_[i].IsUnused());
+        DCHECK(slots->slot_[i].IsUnused());
       }
     }
     slots = slots->next_;
diff --git a/third_party/WebKit/Source/platform/heap/PersistentNode.h b/third_party/WebKit/Source/platform/heap/PersistentNode.h
index 84ef3ce7..9ed41b0 100644
--- a/third_party/WebKit/Source/platform/heap/PersistentNode.h
+++ b/third_party/WebKit/Source/platform/heap/PersistentNode.h
@@ -21,7 +21,7 @@
   DISALLOW_NEW();
 
  public:
-  PersistentNode() : self_(nullptr), trace_(nullptr) { ASSERT(IsUnused()); }
+  PersistentNode() : self_(nullptr), trace_(nullptr) { DCHECK(IsUnused()); }
 
 #if DCHECK_IS_ON()
   ~PersistentNode() {
@@ -29,7 +29,7 @@
     // without clearing persistent handles that the thread created.
     // We don't enable the assert for the main thread because the
     // main thread finishes without clearing all persistent handles.
-    ASSERT(IsMainThread() || IsUnused());
+    DCHECK(IsMainThread() || IsUnused());
   }
 #endif
 
@@ -45,28 +45,28 @@
   // type of the most specific child and calls trace directly. See
   // TraceMethodDelegate in Visitor.h for how this is done.
   void TracePersistentNode(Visitor* visitor) {
-    ASSERT(!IsUnused());
-    ASSERT(trace_);
+    DCHECK(!IsUnused());
+    DCHECK(trace_);
     trace_(visitor, self_);
   }
 
   void Initialize(void* self, TraceCallback trace) {
-    ASSERT(IsUnused());
+    DCHECK(IsUnused());
     self_ = self;
     trace_ = trace;
   }
 
   void SetFreeListNext(PersistentNode* node) {
-    ASSERT(!node || node->IsUnused());
+    DCHECK(!node || node->IsUnused());
     self_ = node;
     trace_ = nullptr;
-    ASSERT(IsUnused());
+    DCHECK(IsUnused());
   }
 
   PersistentNode* FreeListNext() {
-    ASSERT(IsUnused());
+    DCHECK(IsUnused());
     PersistentNode* node = reinterpret_cast<PersistentNode*>(self_);
-    ASSERT(!node || node->IsUnused());
+    DCHECK(!node || node->IsUnused());
     return node;
   }
 
@@ -121,11 +121,11 @@
 #endif
     if (UNLIKELY(!free_list_head_))
       EnsurePersistentNodeSlots(self, trace);
-    ASSERT(free_list_head_);
+    DCHECK(free_list_head_);
     PersistentNode* node = free_list_head_;
     free_list_head_ = free_list_head_->FreeListNext();
     node->Initialize(self, trace);
-    ASSERT(!node->IsUnused());
+    DCHECK(!node->IsUnused());
     return node;
   }
 
diff --git a/third_party/WebKit/Source/platform/heap/SelfKeepAlive.h b/third_party/WebKit/Source/platform/heap/SelfKeepAlive.h
index 4bd6f70b..d2bee35 100644
--- a/third_party/WebKit/Source/platform/heap/SelfKeepAlive.h
+++ b/third_party/WebKit/Source/platform/heap/SelfKeepAlive.h
@@ -61,7 +61,7 @@
 
  private:
   void Assign(Self* self) {
-    ASSERT(!keep_alive_ || keep_alive_.Get() == self);
+    DCHECK(!keep_alive_ || keep_alive_.Get() == self);
     keep_alive_ = self;
   }
 
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
index 438c7d2..2f1eebb0 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -128,8 +128,8 @@
       allocated_object_size_(0),
       marked_object_size_(0),
       reported_memory_to_v8_(0) {
-  ASSERT(CheckThread());
-  ASSERT(!**thread_specific_);
+  DCHECK(CheckThread());
+  DCHECK(!**thread_specific_);
   **thread_specific_ = this;
 
   heap_ = WTF::WrapUnique(new ThreadHeap(this));
@@ -146,7 +146,7 @@
 }
 
 ThreadState::~ThreadState() {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   if (IsMainThread())
     DCHECK_EQ(Heap().HeapStats().AllocatedSpace(), 0u);
   CHECK(GcState() == ThreadState::kNoGCScheduled);
@@ -173,7 +173,7 @@
 }
 
 void ThreadState::RemoveAllPages() {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i)
     arenas_[i]->RemoveAllPages();
 }
@@ -183,7 +183,7 @@
     RemoveAllPages();
     return;
   }
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
 
   // Finish sweeping.
   CompleteSweep();
@@ -197,7 +197,7 @@
   // changes and is above zero.
   int old_count = -1;
   int current_count = GetPersistentRegion()->NumberOfPersistents();
-  ASSERT(current_count >= 0);
+  DCHECK_GE(current_count, 0);
   while (current_count != old_count) {
     CollectGarbage(BlinkGC::kNoHeapPointersOnStack, BlinkGC::kGCWithSweep,
                    BlinkGC::kThreadTerminationGC);
@@ -209,9 +209,9 @@
   }
   // We should not have any persistents left when getting to this point,
   // if we have it is probably a bug so adding a debug ASSERT to catch this.
-  ASSERT(!current_count);
+  DCHECK(!current_count);
   // All of pre-finalizers should be consumed.
-  ASSERT(ordered_pre_finalizers_.IsEmpty());
+  DCHECK(ordered_pre_finalizers_.IsEmpty());
   CHECK_EQ(GcState(), kNoGCScheduled);
 
   RemoveAllPages();
@@ -422,7 +422,7 @@
 }
 
 void ThreadState::ScheduleV8FollowupGCIfNeeded(BlinkGC::V8GCType gc_type) {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   ThreadHeap::ReportMemoryUsageForTracing();
 
 #if PRINT_HEAP_STATS
@@ -436,8 +436,8 @@
   // This completeSweep() will do nothing in common cases since we've
   // called completeSweep() before V8 starts minor/major GCs.
   CompleteSweep();
-  ASSERT(!IsSweepingInProgress());
-  ASSERT(!SweepForbidden());
+  DCHECK(!IsSweepingInProgress());
+  DCHECK(!SweepForbidden());
 
   if ((gc_type == BlinkGC::kV8MajorGC && ShouldForceMemoryPressureGC()) ||
       ShouldScheduleV8FollowupGC()) {
@@ -470,7 +470,7 @@
 
 void ThreadState::SchedulePageNavigationGCIfNeeded(
     float estimated_removal_ratio) {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   ThreadHeap::ReportMemoryUsageForTracing();
 
 #if PRINT_HEAP_STATS
@@ -487,8 +487,8 @@
   // TODO(haraken): It might not make sense to force completeSweep() for all
   // page navigations.
   CompleteSweep();
-  ASSERT(!IsSweepingInProgress());
-  ASSERT(!SweepForbidden());
+  DCHECK(!IsSweepingInProgress());
+  DCHECK(!SweepForbidden());
 
   if (ShouldForceMemoryPressureGC()) {
 #if PRINT_HEAP_STATS
@@ -507,13 +507,13 @@
 }
 
 void ThreadState::SchedulePageNavigationGC() {
-  ASSERT(CheckThread());
-  ASSERT(!IsSweepingInProgress());
+  DCHECK(CheckThread());
+  DCHECK(!IsSweepingInProgress());
   SetGCState(kPageNavigationGCScheduled);
 }
 
 void ThreadState::ScheduleGCIfNeeded() {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   ThreadHeap::ReportMemoryUsageForTracing();
 
 #if PRINT_HEAP_STATS
@@ -527,7 +527,7 @@
 
   if (IsSweepingInProgress())
     return;
-  ASSERT(!SweepForbidden());
+  DCHECK(!SweepForbidden());
 
   ReportMemoryToV8();
 
@@ -564,16 +564,16 @@
 }
 
 ThreadState* ThreadState::FromObject(const void* object) {
-  ASSERT(object);
+  DCHECK(object);
   BasePage* page = PageFromObject(object);
-  ASSERT(page);
-  ASSERT(page->Arena());
+  DCHECK(page);
+  DCHECK(page->Arena());
   return page->Arena()->GetThreadState();
 }
 
 void ThreadState::PerformIdleGC(double deadline_seconds) {
-  ASSERT(CheckThread());
-  ASSERT(Platform::Current()->CurrentThread()->Scheduler());
+  DCHECK(CheckThread());
+  DCHECK(Platform::Current()->CurrentThread()->Scheduler());
 
   if (GcState() != kIdleGCScheduled)
     return;
@@ -605,7 +605,7 @@
 }
 
 void ThreadState::PerformIdleLazySweep(double deadline_seconds) {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
 
   // If we are not in a sweeping phase, there is nothing to do here.
   if (!IsSweepingInProgress())
@@ -674,7 +674,7 @@
 }
 
 void ThreadState::SchedulePreciseGC() {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   if (IsSweepingInProgress()) {
     SetGCState(kSweepingAndPreciseGCScheduled);
     return;
@@ -717,7 +717,7 @@
 void ThreadState::SetGCState(GCState gc_state) {
   switch (gc_state) {
     case kNoGCScheduled:
-      ASSERT(CheckThread());
+      DCHECK(CheckThread());
       VERIFY_STATE_TRANSITION(gc_state_ == kSweeping ||
                               gc_state_ == kSweepingAndIdleGCScheduled);
       break;
@@ -725,7 +725,7 @@
     case kPreciseGCScheduled:
     case kFullGCScheduled:
     case kPageNavigationGCScheduled:
-      ASSERT(CheckThread());
+      DCHECK(CheckThread());
       VERIFY_STATE_TRANSITION(
           gc_state_ == kNoGCScheduled || gc_state_ == kIdleGCScheduled ||
           gc_state_ == kPreciseGCScheduled || gc_state_ == kFullGCScheduled ||
@@ -735,7 +735,7 @@
       CompleteSweep();
       break;
     case kGCRunning:
-      ASSERT(!IsInGC());
+      DCHECK(!IsInGC());
       VERIFY_STATE_TRANSITION(gc_state_ != kGCRunning);
       break;
     case kSweeping:
@@ -745,7 +745,7 @@
       break;
     case kSweepingAndIdleGCScheduled:
     case kSweepingAndPreciseGCScheduled:
-      ASSERT(CheckThread());
+      DCHECK(CheckThread());
       VERIFY_STATE_TRANSITION(gc_state_ == kSweeping ||
                               gc_state_ == kSweepingAndIdleGCScheduled ||
                               gc_state_ == kSweepingAndPreciseGCScheduled);
@@ -759,7 +759,7 @@
 #undef VERIFY_STATE_TRANSITION
 
 void ThreadState::RunScheduledGC(BlinkGC::StackState stack_state) {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   if (stack_state != BlinkGC::kNoHeapPointersOnStack)
     return;
 
@@ -799,7 +799,7 @@
 }
 
 void ThreadState::MakeConsistentForGC() {
-  ASSERT(IsInGC());
+  DCHECK(IsInGC());
   TRACE_EVENT0("blink_gc", "ThreadState::makeConsistentForGC");
   for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i)
     arenas_[i]->MakeConsistentForGC();
@@ -834,7 +834,7 @@
 }
 
 void ThreadState::MakeConsistentForMutator() {
-  ASSERT(IsInGC());
+  DCHECK(IsInGC());
   for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i)
     arenas_[i]->MakeConsistentForMutator();
 }
@@ -843,7 +843,7 @@
   if (isolate_ && perform_cleanup_)
     perform_cleanup_(isolate_);
 
-  ASSERT(!IsInGC());
+  DCHECK(!IsInGC());
   SetGCState(kGCRunning);
   MakeConsistentForGC();
   FlushHeapDoesNotContainCacheIfNeeded();
@@ -943,11 +943,11 @@
 #if defined(ADDRESS_SANITIZER)
   PoisonEagerArena();
 #endif
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   // Some objects need to be finalized promptly and cannot be handled
   // by lazy sweeping. Keep those in a designated heap and sweep it
   // eagerly.
-  ASSERT(IsSweepingInProgress());
+  DCHECK(IsSweepingInProgress());
 
   // Mirroring the completeSweep() condition; see its comment.
   if (SweepForbidden())
@@ -962,7 +962,7 @@
 }
 
 void ThreadState::CompleteSweep() {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   // If we are not in a sweeping phase, there is nothing to do here.
   if (!IsSweepingInProgress())
     return;
@@ -997,7 +997,7 @@
 }
 
 void ThreadState::PostSweep() {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   ThreadHeap::ReportMemoryUsageForTracing();
 
   if (IsMainThread()) {
@@ -1098,7 +1098,7 @@
 }
 
 void ThreadState::SafePoint(BlinkGC::StackState stack_state) {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   ThreadHeap::ReportMemoryUsageForTracing();
 
   RunScheduledGC(stack_state);
@@ -1143,12 +1143,12 @@
 
 void ThreadState::EnterSafePoint(BlinkGC::StackState stack_state,
                                  void* scope_marker) {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
 #ifdef ADDRESS_SANITIZER
   if (stack_state == BlinkGC::kHeapPointersOnStack)
     scope_marker = AdjustScopeMarkerForAdressSanitizer(scope_marker);
 #endif
-  ASSERT(stack_state == BlinkGC::kNoHeapPointersOnStack || scope_marker);
+  DCHECK(stack_state == BlinkGC::kNoHeapPointersOnStack || scope_marker);
   RunScheduledGC(stack_state);
   stack_state_ = stack_state;
   safe_point_scope_marker_ = scope_marker;
@@ -1156,7 +1156,7 @@
 }
 
 void ThreadState::LeaveSafePoint() {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   stack_state_ = BlinkGC::kHeapPointersOnStack;
   ClearSafePointScopeMarker();
 }
@@ -1206,12 +1206,12 @@
 #if defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER)
   // ASan/LSan use more space on the stack and we therefore
   // increase the allowed stack copying for those builds.
-  ASSERT(slot_count < 2048);
+  DCHECK_LT(slot_count, 2048u);
 #else
-  ASSERT(slot_count < 1024);
+  DCHECK_LT(slot_count, 1024u);
 #endif
 
-  ASSERT(!safe_point_stack_copy_.size());
+  DCHECK(!safe_point_stack_copy_.size());
   safe_point_stack_copy_.Resize(slot_count);
   for (size_t i = 0; i < slot_count; ++i) {
     safe_point_stack_copy_[i] = from[i];
@@ -1226,7 +1226,7 @@
     return;
 #endif
 
-  ASSERT(!static_persistents_.Contains(node));
+  DCHECK(!static_persistents_.Contains(node));
   static_persistents_.insert(node, callback);
 }
 
@@ -1248,7 +1248,7 @@
   //
   // There's no fundamental reason why this couldn't be supported,
   // but no known use for it.
-  ASSERT(!static_persistents_.Contains(persistent_node));
+  DCHECK(!static_persistents_.Contains(persistent_node));
 }
 
 #if defined(LEAK_SANITIZER)
@@ -1257,14 +1257,14 @@
 }
 
 void ThreadState::leaveStaticReferenceRegistrationDisabledScope() {
-  ASSERT(m_disabledStaticPersistentsRegistration);
+  DCHECK(m_disabledStaticPersistentsRegistration);
   m_disabledStaticPersistentsRegistration--;
 }
 #endif
 
 void ThreadState::InvokePreFinalizers() {
-  ASSERT(CheckThread());
-  ASSERT(!SweepForbidden());
+  DCHECK(CheckThread());
+  DCHECK(!SweepForbidden());
   TRACE_EVENT0("blink_gc", "ThreadState::invokePreFinalizers");
 
   SweepForbiddenScope sweep_forbidden(this);
@@ -1320,12 +1320,12 @@
       arena_index_with_min_arena_age = arena_index;
     }
   }
-  ASSERT(IsVectorArenaIndex(arena_index_with_min_arena_age));
+  DCHECK(IsVectorArenaIndex(arena_index_with_min_arena_age));
   return arena_index_with_min_arena_age;
 }
 
 BaseArena* ThreadState::ExpandedVectorBackingArena(size_t gc_info_index) {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   size_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask;
   --likely_to_be_promptly_freed_[entry_index];
   int arena_index = vector_backing_arena_index_;
@@ -1343,14 +1343,14 @@
 }
 
 void ThreadState::PromptlyFreed(size_t gc_info_index) {
-  ASSERT(CheckThread());
+  DCHECK(CheckThread());
   size_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask;
   // See the comment in vectorBackingArena() for why this is +3.
   likely_to_be_promptly_freed_[entry_index] += 3;
 }
 
 void ThreadState::TakeSnapshot(SnapshotType type) {
-  ASSERT(IsInGC());
+  DCHECK(IsInGC());
 
   // 0 is used as index for freelist entries. Objects are indexed 1 to
   // gcInfoIndex.
@@ -1392,7 +1392,7 @@
   SNAPSHOT_HEAP(LargeObject);
   FOR_EACH_TYPED_ARENA(SNAPSHOT_HEAP);
 
-  ASSERT(number_of_heaps_reported == BlinkGC::kNumberOfArenas);
+  DCHECK_EQ(number_of_heaps_reported, BlinkGC::kNumberOfArenas);
 
 #undef SNAPSHOT_HEAP
 
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.h b/third_party/WebKit/Source/platform/heap/ThreadState.h
index acf753d..ce8368a 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.h
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.h
@@ -146,11 +146,11 @@
 
    public:
     explicit SweepForbiddenScope(ThreadState* state) : state_(state) {
-      ASSERT(!state_->sweep_forbidden_);
+      DCHECK(!state_->sweep_forbidden_);
       state_->sweep_forbidden_ = true;
     }
     ~SweepForbiddenScope() {
-      ASSERT(state_->sweep_forbidden_);
+      DCHECK(state_->sweep_forbidden_);
       state_->sweep_forbidden_ = false;
     }
 
@@ -358,8 +358,8 @@
   // The thread heap is split into multiple heap parts based on object types
   // and object sizes.
   BaseArena* Arena(int arena_index) const {
-    ASSERT(0 <= arena_index);
-    ASSERT(arena_index < BlinkGC::kNumberOfArenas);
+    DCHECK_LE(0, arena_index);
+    DCHECK_LT(arena_index, BlinkGC::kNumberOfArenas);
     return arenas_[arena_index];
   }
 
@@ -432,7 +432,7 @@
   // constructed.
   void EnterGCForbiddenScopeIfNeeded(
       GarbageCollectedMixinConstructorMarker* gc_mixin_marker) {
-    ASSERT(CheckThread());
+    DCHECK(CheckThread());
     if (!gc_mixin_marker_) {
       EnterMixinConstructionScope();
       gc_mixin_marker_ = gc_mixin_marker;
@@ -440,7 +440,7 @@
   }
   void LeaveGCForbiddenScopeIfNeeded(
       GarbageCollectedMixinConstructorMarker* gc_mixin_marker) {
-    ASSERT(CheckThread());
+    DCHECK(CheckThread());
     if (gc_mixin_marker_ == gc_mixin_marker) {
       LeaveMixinConstructionScope();
       gc_mixin_marker_ = nullptr;
@@ -474,7 +474,7 @@
   //       freed since the last GC.
   //
   BaseArena* VectorBackingArena(size_t gc_info_index) {
-    ASSERT(CheckThread());
+    DCHECK(CheckThread());
     size_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask;
     --likely_to_be_promptly_freed_[entry_index];
     int arena_index = vector_backing_arena_index_;
@@ -487,7 +487,7 @@
           ArenaIndexOfVectorArenaLeastRecentlyExpanded(
               BlinkGC::kVector1ArenaIndex, BlinkGC::kVector4ArenaIndex);
     }
-    ASSERT(IsVectorArenaIndex(arena_index));
+    DCHECK(IsVectorArenaIndex(arena_index));
     return arenas_[arena_index];
   }
   BaseArena* ExpandedVectorBackingArena(size_t gc_info_index);
@@ -720,7 +720,7 @@
  public:
   static ThreadState* GetState() {
     // This specialization must only be used from the main thread.
-    ASSERT(ThreadState::Current()->IsMainThread());
+    DCHECK(ThreadState::Current()->IsMainThread());
     return ThreadState::MainThreadState();
   }
 };
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp
index 41c4c12..a265944 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp
@@ -48,9 +48,6 @@
     return *this;
 
   bitmap_ = other.bitmap_;
-  // Keep the pixels locked since we will be writing directly into the
-  // bitmap throughout this object's lifetime.
-  bitmap_.lockPixels();
   // Be sure to assign this before calling setStatus(), since setStatus() may
   // call notifyBitmapIfPixelsChanged().
   pixels_changed_ = other.pixels_changed_;
diff --git a/third_party/WebKit/Source/platform/mac/GraphicsContextCanvas.h b/third_party/WebKit/Source/platform/mac/GraphicsContextCanvas.h
index cff3885..cd76c8b8 100644
--- a/third_party/WebKit/Source/platform/mac/GraphicsContextCanvas.h
+++ b/third_party/WebKit/Source/platform/mac/GraphicsContextCanvas.h
@@ -44,11 +44,6 @@
   SkIPoint bitmap_offset_;
   SkScalar bitmap_scale_factor_;
 
-  // True if we are drawing to |m_canvas|'s backing store directly.
-  // Otherwise, the bits in |bitmap_| are our allocation and need to
-  // be copied over to |m_canvas|.
-  bool use_device_bits_;
-
   // True if |bitmap_| is a dummy 1x1 bitmap allocated for the sake of creating
   // a non-null CGContext (it is invalid to use a null CGContext), and will not
   // be copied to |m_canvas|. This will happen if |m_canvas|'s clip region is
diff --git a/third_party/WebKit/Source/platform/mac/GraphicsContextCanvas.mm b/third_party/WebKit/Source/platform/mac/GraphicsContextCanvas.mm
index 190a6fc..8601bcb 100644
--- a/third_party/WebKit/Source/platform/mac/GraphicsContextCanvas.mm
+++ b/third_party/WebKit/Source/platform/mac/GraphicsContextCanvas.mm
@@ -18,7 +18,6 @@
     : canvas_(canvas),
       cg_context_(0),
       bitmap_scale_factor_(bitmap_scale_factor),
-      use_device_bits_(false),
       bitmap_is_dummy_(false) {
   canvas_->save();
   canvas_->clipRect(SkRect::MakeFromIRect(user_clip_rect));
@@ -39,7 +38,7 @@
 void GraphicsContextCanvas::ReleaseIfNeeded() {
   if (!cg_context_)
     return;
-  if (!use_device_bits_ && !bitmap_is_dummy_) {
+  if (!bitmap_is_dummy_) {
     // Find the bits that were drawn to.
     SkIRect bounds = ComputeDirtyRect();
     SkBitmap subset;
@@ -57,7 +56,6 @@
   }
   CGContextRelease(cg_context_);
   cg_context_ = 0;
-  use_device_bits_ = false;
   bitmap_is_dummy_ = false;
 }
 
@@ -76,42 +74,22 @@
   // remember the top/left, in case we need to compose this later
   bitmap_offset_.set(clip_bounds.x(), clip_bounds.y());
 
-  SkPixmap device_pixels;
-  ToPixmap(canvas_, &device_pixels);
-
-  // Only draw directly if we have pixels, and we're only rect-clipped.
-  // If not, we allocate an offscreen and draw into that, relying on the
+  // Allocate an offscreen and draw into that, relying on the
   // compositing step to apply skia's clip.
-  use_device_bits_ =
-      device_pixels.addr() && canvas_->isClipRect() && !bitmap_is_dummy_;
   WTF::RetainPtr<CGColorSpace> color_space(CGColorSpaceCreateDeviceRGB());
 
-  int display_height;
-  if (use_device_bits_) {
-    SkPixmap subset;
-    bool result = device_pixels.extractSubset(&subset, clip_bounds);
-    DCHECK(result);
-    if (!result)
-      return 0;
-    display_height = subset.height();
-    cg_context_ = CGBitmapContextCreate(
-        subset.writable_addr(), subset.width(), subset.height(), 8,
-        subset.rowBytes(), color_space.Get(),
-        kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
-  } else {
-    bool result = offscreen_.tryAllocN32Pixels(
-        SkScalarCeilToInt(bitmap_scale_factor_ * clip_bounds.width()),
-        SkScalarCeilToInt(bitmap_scale_factor_ * clip_bounds.height()));
-    DCHECK(result);
-    if (!result)
-      return 0;
-    offscreen_.eraseColor(0);
-    display_height = offscreen_.height();
-    cg_context_ = CGBitmapContextCreate(
-        offscreen_.getPixels(), offscreen_.width(), offscreen_.height(), 8,
-        offscreen_.rowBytes(), color_space.Get(),
-        kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
-  }
+  bool result = offscreen_.tryAllocN32Pixels(
+      SkScalarCeilToInt(bitmap_scale_factor_ * clip_bounds.width()),
+      SkScalarCeilToInt(bitmap_scale_factor_ * clip_bounds.height()));
+  DCHECK(result);
+  if (!result)
+    return 0;
+  offscreen_.eraseColor(0);
+  int display_height = offscreen_.height();
+  cg_context_ = CGBitmapContextCreate(
+      offscreen_.getPixels(), offscreen_.width(), offscreen_.height(), 8,
+      offscreen_.rowBytes(), color_space.Get(),
+      kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
   DCHECK(cg_context_);
 
   SkMatrix matrix = canvas_->getTotalMatrix();
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
index 73409a0..55132629 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
@@ -31,7 +31,7 @@
 
 #include "platform/scroll/ScrollableArea.h"
 
-#include "platform/HostWindow.h"
+#include "platform/PlatformChromeClient.h"
 #include "platform/graphics/GraphicsLayer.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "platform/scroll/MainThreadScrollingReason.h"
@@ -43,7 +43,7 @@
 
 namespace blink {
 
-int ScrollableArea::PixelsPerLineStep(HostWindow* host) {
+int ScrollableArea::PixelsPerLineStep(PlatformChromeClient* host) {
   if (!host)
     return kPixelsPerLineStep;
   return host->WindowToViewportScalar(kPixelsPerLineStep);
@@ -615,7 +615,7 @@
 }
 
 int ScrollableArea::LineStep(ScrollbarOrientation) const {
-  return PixelsPerLineStep(GetHostWindow());
+  return PixelsPerLineStep(GetChromeClient());
 }
 
 int ScrollableArea::PageStep(ScrollbarOrientation orientation) const {
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
index b2e951e..03ba7c4 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
@@ -45,10 +45,10 @@
 class CompositorAnimationHost;
 class CompositorAnimationTimeline;
 class GraphicsLayer;
-class HostWindow;
 class LayoutBox;
 class LayoutObject;
 class PaintLayer;
+class PlatformChromeClient;
 class ProgrammaticScrollAnimator;
 struct ScrollAlignment;
 class ScrollAnchor;
@@ -65,7 +65,7 @@
   WTF_MAKE_NONCOPYABLE(ScrollableArea);
 
  public:
-  static int PixelsPerLineStep(HostWindow*);
+  static int PixelsPerLineStep(PlatformChromeClient*);
   static float MinFractionToStepWhenPaging();
   static int MaxOverlapBetweenPages();
 
@@ -75,10 +75,7 @@
     return std::isfinite(value) ? value : 0.0;
   }
 
-  // The window that hosts the ScrollableArea. The ScrollableArea will
-  // communicate scrolls and repaints to the host window in the window's
-  // coordinate space.
-  virtual HostWindow* GetHostWindow() const { return 0; }
+  virtual PlatformChromeClient* GetChromeClient() const { return 0; }
 
   virtual ScrollResult UserScroll(ScrollGranularity, const ScrollOffset&);
 
diff --git a/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp b/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
index c5a1386..ec956d70 100644
--- a/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
+++ b/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
@@ -26,7 +26,7 @@
 #include "platform/scroll/Scrollbar.h"
 
 #include <algorithm>
-#include "platform/HostWindow.h"
+#include "platform/PlatformChromeClient.h"
 #include "platform/geometry/FloatRect.h"
 #include "platform/graphics/paint/CullRect.h"
 #include "platform/scroll/ScrollAnimatorBase.h"
@@ -40,13 +40,13 @@
 Scrollbar::Scrollbar(ScrollableArea* scrollable_area,
                      ScrollbarOrientation orientation,
                      ScrollbarControlSize control_size,
-                     HostWindow* host_window,
+                     PlatformChromeClient* chrome_client,
                      ScrollbarTheme* theme)
     : scrollable_area_(scrollable_area),
       orientation_(orientation),
       control_size_(control_size),
       theme_(theme ? *theme : ScrollbarTheme::GetTheme()),
-      host_window_(host_window),
+      chrome_client_(chrome_client),
       visible_size_(0),
       total_size_(0),
       current_pos_(0),
@@ -72,8 +72,8 @@
   // sizing).
   int thickness = theme_.ScrollbarThickness(control_size);
   theme_scrollbar_thickness_ = thickness;
-  if (host_window_)
-    thickness = host_window_->WindowToViewportScalar(thickness);
+  if (chrome_client_)
+    thickness = chrome_client_->WindowToViewportScalar(thickness);
   FrameViewBase::SetFrameRect(IntRect(0, 0, thickness, thickness));
 
   current_pos_ = ScrollableAreaCurrentPos();
@@ -85,7 +85,7 @@
 
 DEFINE_TRACE(Scrollbar) {
   visitor->Trace(scrollable_area_);
-  visitor->Trace(host_window_);
+  visitor->Trace(chrome_client_);
   FrameViewBase::Trace(visitor);
 }
 
@@ -549,9 +549,9 @@
 
 int Scrollbar::ScrollbarThickness() const {
   int thickness = Orientation() == kHorizontalScrollbar ? Height() : Width();
-  if (!thickness || !host_window_)
+  if (!thickness || !chrome_client_)
     return thickness;
-  return host_window_->WindowToViewportScalar(theme_scrollbar_thickness_);
+  return chrome_client_->WindowToViewportScalar(theme_scrollbar_thickness_);
 }
 
 bool Scrollbar::IsOverlayScrollbar() const {
diff --git a/third_party/WebKit/Source/platform/scroll/Scrollbar.h b/third_party/WebKit/Source/platform/scroll/Scrollbar.h
index 0d492ef1..14cc4f7c 100644
--- a/third_party/WebKit/Source/platform/scroll/Scrollbar.h
+++ b/third_party/WebKit/Source/platform/scroll/Scrollbar.h
@@ -38,8 +38,8 @@
 
 class CullRect;
 class GraphicsContext;
-class HostWindow;
 class IntRect;
+class PlatformChromeClient;
 class ScrollableArea;
 class ScrollbarTheme;
 class WebGestureEvent;
@@ -52,8 +52,8 @@
   static Scrollbar* Create(ScrollableArea* scrollable_area,
                            ScrollbarOrientation orientation,
                            ScrollbarControlSize size,
-                           HostWindow* host_window) {
-    return new Scrollbar(scrollable_area, orientation, size, host_window);
+                           PlatformChromeClient* chrome_client) {
+    return new Scrollbar(scrollable_area, orientation, size, chrome_client);
   }
 
   // Theme object ownership remains with the caller and it must outlive the
@@ -209,7 +209,7 @@
   Scrollbar(ScrollableArea*,
             ScrollbarOrientation,
             ScrollbarControlSize,
-            HostWindow* = 0,
+            PlatformChromeClient* = 0,
             ScrollbarTheme* = 0);
 
   void AutoscrollTimerFired(TimerBase*);
@@ -223,7 +223,7 @@
   ScrollbarOrientation orientation_;
   ScrollbarControlSize control_size_;
   ScrollbarTheme& theme_;
-  Member<HostWindow> host_window_;
+  Member<PlatformChromeClient> chrome_client_;
 
   int visible_size_;
   int total_size_;
diff --git a/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp b/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp
index 0e99424..a3cbba2 100644
--- a/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp
+++ b/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp
@@ -203,4 +203,8 @@
   return layer_tree_host_->have_scroll_event_handlers();
 }
 
+bool WebLayerTreeViewImplForTesting::IsForSubframe() {
+  return false;
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.h b/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.h
index 357f974..d543a05 100644
--- a/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.h
+++ b/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.h
@@ -95,6 +95,8 @@
   void DidReceiveCompositorFrameAck() override {}
   void DidCompletePageScaleAnimation() override {}
 
+  bool IsForSubframe() override;
+
   // cc::LayerTreeHostSingleThreadClient implementation.
   void DidSubmitCompositorFrame() override {}
   void DidLoseCompositorFrameSink() override {}
diff --git a/third_party/WebKit/Source/platform/wtf/typed_arrays/ArrayBufferView.h b/third_party/WebKit/Source/platform/wtf/typed_arrays/ArrayBufferView.h
index 25a447c..c7970aa 100644
--- a/third_party/WebKit/Source/platform/wtf/typed_arrays/ArrayBufferView.h
+++ b/third_party/WebKit/Source/platform/wtf/typed_arrays/ArrayBufferView.h
@@ -58,6 +58,7 @@
     DCHECK(!IsShared());
     return base_address_;
   }
+  void* BaseAddressMaybeShared() const { return base_address_; }
 
   unsigned ByteOffset() const { return byte_offset_; }
 
diff --git a/third_party/WebKit/Source/platform/wtf/typed_arrays/TypedArrayBase.h b/third_party/WebKit/Source/platform/wtf/typed_arrays/TypedArrayBase.h
index 5b024e0..415529db 100644
--- a/third_party/WebKit/Source/platform/wtf/typed_arrays/TypedArrayBase.h
+++ b/third_party/WebKit/Source/platform/wtf/typed_arrays/TypedArrayBase.h
@@ -38,6 +38,9 @@
   typedef T ValueType;
 
   T* Data() const { return static_cast<T*>(BaseAddress()); }
+  T* DataMaybeShared() const {
+    return static_cast<T*>(BaseAddressMaybeShared());
+  }
 
   bool Set(TypedArrayBase<T>* array, unsigned offset) {
     return SetImpl(array, offset * sizeof(T));
diff --git a/third_party/WebKit/Source/web/BUILD.gn b/third_party/WebKit/Source/web/BUILD.gn
index b9bd306..aff5086e 100644
--- a/third_party/WebKit/Source/web/BUILD.gn
+++ b/third_party/WebKit/Source/web/BUILD.gn
@@ -79,10 +79,8 @@
     "IndexedDBClientImpl.h",
     "InspectorEmulationAgent.cpp",
     "InspectorEmulationAgent.h",
-    "InspectorOverlay.cpp",
-    "InspectorOverlay.h",
-    "InspectorRenderingAgent.cpp",
-    "InspectorRenderingAgent.h",
+    "InspectorOverlayAgent.cpp",
+    "InspectorOverlayAgent.h",
     "LinkHighlightImpl.cpp",
     "LinkHighlightImpl.h",
     "LocalFileSystemClient.cpp",
diff --git a/third_party/WebKit/Source/web/InspectorOverlay.cpp b/third_party/WebKit/Source/web/InspectorOverlay.cpp
deleted file mode 100644
index 850d283..0000000
--- a/third_party/WebKit/Source/web/InspectorOverlay.cpp
+++ /dev/null
@@ -1,827 +0,0 @@
-/*
- * Copyright (C) 2011 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:
- *
- * 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.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 "web/InspectorOverlay.h"
-
-#include <memory>
-
-#include "bindings/core/v8/ScriptController.h"
-#include "bindings/core/v8/ScriptSourceCode.h"
-#include "bindings/core/v8/V8Binding.h"
-#include "bindings/core/v8/V8InspectorOverlayHost.h"
-#include "core/dom/Node.h"
-#include "core/dom/StaticNodeList.h"
-#include "core/dom/TaskRunnerHelper.h"
-#include "core/frame/FrameView.h"
-#include "core/frame/LocalFrame.h"
-#include "core/frame/LocalFrameClient.h"
-#include "core/frame/Settings.h"
-#include "core/frame/VisualViewport.h"
-#include "core/html/HTMLFrameOwnerElement.h"
-#include "core/input/EventHandler.h"
-#include "core/inspector/InspectorOverlayHost.h"
-#include "core/layout/api/LayoutViewItem.h"
-#include "core/loader/EmptyClients.h"
-#include "core/loader/FrameLoadRequest.h"
-#include "core/page/ChromeClient.h"
-#include "core/page/Page.h"
-#include "platform/ScriptForbiddenScope.h"
-#include "platform/graphics/Color.h"
-#include "platform/graphics/GraphicsContext.h"
-#include "platform/graphics/paint/CullRect.h"
-#include "platform/wtf/AutoReset.h"
-#include "public/platform/Platform.h"
-#include "public/platform/WebData.h"
-#include "v8/include/v8.h"
-#include "web/ChromeClientImpl.h"
-#include "web/PageOverlay.h"
-#include "web/WebInputEventConversion.h"
-#include "web/WebLocalFrameImpl.h"
-
-namespace blink {
-
-namespace {
-
-Node* HoveredNodeForPoint(LocalFrame* frame,
-                          const IntPoint& point_in_root_frame,
-                          bool ignore_pointer_events_none) {
-  HitTestRequest::HitTestRequestType hit_type =
-      HitTestRequest::kMove | HitTestRequest::kReadOnly |
-      HitTestRequest::kAllowChildFrameContent;
-  if (ignore_pointer_events_none)
-    hit_type |= HitTestRequest::kIgnorePointerEventsNone;
-  HitTestRequest request(hit_type);
-  HitTestResult result(request,
-                       frame->View()->RootFrameToContents(point_in_root_frame));
-  frame->ContentLayoutItem().HitTest(result);
-  Node* node = result.InnerPossiblyPseudoNode();
-  while (node && node->getNodeType() == Node::kTextNode)
-    node = node->parentNode();
-  return node;
-}
-
-Node* HoveredNodeForEvent(LocalFrame* frame,
-                          const WebGestureEvent& event,
-                          bool ignore_pointer_events_none) {
-  return HoveredNodeForPoint(frame,
-                             RoundedIntPoint(event.PositionInRootFrame()),
-                             ignore_pointer_events_none);
-}
-
-Node* HoveredNodeForEvent(LocalFrame* frame,
-                          const WebMouseEvent& event,
-                          bool ignore_pointer_events_none) {
-  return HoveredNodeForPoint(frame,
-                             RoundedIntPoint(event.PositionInRootFrame()),
-                             ignore_pointer_events_none);
-}
-
-Node* HoveredNodeForEvent(LocalFrame* frame,
-                          const WebTouchEvent& event,
-                          bool ignore_pointer_events_none) {
-  if (!event.touches_length)
-    return nullptr;
-  WebTouchPoint transformed_point = event.TouchPointInRootFrame(0);
-  return HoveredNodeForPoint(frame, RoundedIntPoint(transformed_point.position),
-                             ignore_pointer_events_none);
-}
-}  // namespace
-
-class InspectorOverlay::InspectorPageOverlayDelegate final
-    : public PageOverlay::Delegate {
- public:
-  explicit InspectorPageOverlayDelegate(InspectorOverlay& overlay)
-      : overlay_(&overlay) {}
-
-  void PaintPageOverlay(const PageOverlay&,
-                        GraphicsContext& graphics_context,
-                        const WebSize& web_view_size) const override {
-    if (overlay_->IsEmpty())
-      return;
-
-    FrameView* view = overlay_->OverlayMainFrame()->View();
-    DCHECK(!view->NeedsLayout());
-    view->Paint(graphics_context,
-                CullRect(IntRect(0, 0, view->Width(), view->Height())));
-  }
-
- private:
-  Persistent<InspectorOverlay> overlay_;
-};
-
-class InspectorOverlay::InspectorOverlayChromeClient final
-    : public EmptyChromeClient {
- public:
-  static InspectorOverlayChromeClient* Create(ChromeClient& client,
-                                              InspectorOverlay& overlay) {
-    return new InspectorOverlayChromeClient(client, overlay);
-  }
-
-  DEFINE_INLINE_VIRTUAL_TRACE() {
-    visitor->Trace(client_);
-    visitor->Trace(overlay_);
-    EmptyChromeClient::Trace(visitor);
-  }
-
-  void SetCursor(const Cursor& cursor, LocalFrame* local_root) override {
-    ToChromeClientImpl(client_)->SetCursorOverridden(false);
-    ToChromeClientImpl(client_)->SetCursor(cursor,
-                                           overlay_->frame_impl_->GetFrame());
-    ToChromeClientImpl(client_)->SetCursorOverridden(false);
-  }
-
-  void SetToolTip(LocalFrame& frame,
-                  const String& tooltip,
-                  TextDirection direction) override {
-    DCHECK_EQ(&frame, overlay_->OverlayMainFrame());
-    client_->SetToolTip(*overlay_->frame_impl_->GetFrame(), tooltip, direction);
-  }
-
-  void InvalidateRect(const IntRect&) override { overlay_->Invalidate(); }
-
-  void ScheduleAnimation(LocalFrame* frame) override {
-    if (overlay_->in_layout_)
-      return;
-
-    client_->ScheduleAnimation(frame);
-  }
-
- private:
-  InspectorOverlayChromeClient(ChromeClient& client, InspectorOverlay& overlay)
-      : client_(&client), overlay_(&overlay) {}
-
-  Member<ChromeClient> client_;
-  Member<InspectorOverlay> overlay_;
-};
-
-InspectorOverlay::InspectorOverlay(WebLocalFrameImpl* frame_impl)
-    : frame_impl_(frame_impl),
-      overlay_host_(InspectorOverlayHost::Create()),
-      draw_view_size_(false),
-      resize_timer_active_(false),
-      omit_tooltip_(false),
-      timer_(TaskRunnerHelper::Get(TaskType::kUnspecedTimer,
-                                   frame_impl->GetFrame()),
-             this,
-             &InspectorOverlay::OnTimer),
-      suspended_(false),
-      show_reloading_blanket_(false),
-      in_layout_(false),
-      needs_update_(false),
-      swallow_next_mouse_up_(false),
-      inspect_mode_(InspectorDOMAgent::kNotSearching) {}
-
-InspectorOverlay::~InspectorOverlay() {
-  DCHECK(!overlay_page_);
-}
-
-DEFINE_TRACE(InspectorOverlay) {
-  visitor->Trace(frame_impl_);
-  visitor->Trace(highlight_node_);
-  visitor->Trace(event_target_node_);
-  visitor->Trace(overlay_page_);
-  visitor->Trace(overlay_chrome_client_);
-  visitor->Trace(overlay_host_);
-  visitor->Trace(dom_agent_);
-  visitor->Trace(hovered_node_for_inspect_mode_);
-}
-
-void InspectorOverlay::Init(v8_inspector::V8InspectorSession* v8_session,
-                            InspectorDOMAgent* dom_agent) {
-  v8_session_ = v8_session;
-  dom_agent_ = dom_agent;
-  overlay_host_->SetListener(this);
-}
-
-void InspectorOverlay::Invalidate() {
-  if (!page_overlay_) {
-    page_overlay_ = PageOverlay::Create(
-        frame_impl_, WTF::WrapUnique(new InspectorPageOverlayDelegate(*this)));
-  }
-
-  page_overlay_->Update();
-}
-
-void InspectorOverlay::UpdateAllLifecyclePhases() {
-  if (IsEmpty())
-    return;
-
-  AutoReset<bool> scoped(&in_layout_, true);
-  if (needs_update_) {
-    needs_update_ = false;
-    RebuildOverlayPage();
-  }
-  OverlayMainFrame()->View()->UpdateAllLifecyclePhases();
-}
-
-bool InspectorOverlay::HandleInputEvent(const WebInputEvent& input_event) {
-  bool handled = false;
-
-  if (IsEmpty())
-    return false;
-
-  if (input_event.GetType() == WebInputEvent::kGestureTap) {
-    // We only have a use for gesture tap.
-    WebGestureEvent transformed_event = TransformWebGestureEvent(
-        frame_impl_->GetFrameView(),
-        static_cast<const WebGestureEvent&>(input_event));
-    handled = HandleGestureEvent(transformed_event);
-    if (handled)
-      return true;
-
-    OverlayMainFrame()->GetEventHandler().HandleGestureEvent(transformed_event);
-  }
-  if (WebInputEvent::IsMouseEventType(input_event.GetType())) {
-    WebMouseEvent mouse_event =
-        TransformWebMouseEvent(frame_impl_->GetFrameView(),
-                               static_cast<const WebMouseEvent&>(input_event));
-
-    if (mouse_event.GetType() == WebInputEvent::kMouseMove)
-      handled = HandleMouseMove(mouse_event);
-    else if (mouse_event.GetType() == WebInputEvent::kMouseDown)
-      handled = HandleMouseDown();
-    else if (mouse_event.GetType() == WebInputEvent::kMouseUp)
-      handled = HandleMouseUp();
-
-    if (handled)
-      return true;
-
-    if (mouse_event.GetType() == WebInputEvent::kMouseMove) {
-      handled = OverlayMainFrame()->GetEventHandler().HandleMouseMoveEvent(
-                    mouse_event, TransformWebMouseEventVector(
-                                     frame_impl_->GetFrameView(),
-                                     std::vector<const WebInputEvent*>())) !=
-                WebInputEventResult::kNotHandled;
-    }
-    if (mouse_event.GetType() == WebInputEvent::kMouseDown)
-      handled = OverlayMainFrame()->GetEventHandler().HandleMousePressEvent(
-                    mouse_event) != WebInputEventResult::kNotHandled;
-    if (mouse_event.GetType() == WebInputEvent::kMouseUp)
-      handled = OverlayMainFrame()->GetEventHandler().HandleMouseReleaseEvent(
-                    mouse_event) != WebInputEventResult::kNotHandled;
-  }
-
-  if (WebInputEvent::IsTouchEventType(input_event.GetType())) {
-    WebTouchEvent transformed_event =
-        TransformWebTouchEvent(frame_impl_->GetFrameView(),
-                               static_cast<const WebTouchEvent&>(input_event));
-    handled = HandleTouchEvent(transformed_event);
-    if (handled)
-      return true;
-    OverlayMainFrame()->GetEventHandler().HandleTouchEvent(
-        transformed_event, Vector<WebTouchEvent>());
-  }
-  if (WebInputEvent::IsKeyboardEventType(input_event.GetType())) {
-    OverlayMainFrame()->GetEventHandler().KeyEvent(
-        static_cast<const WebKeyboardEvent&>(input_event));
-  }
-
-  if (input_event.GetType() == WebInputEvent::kMouseWheel) {
-    WebMouseWheelEvent transformed_event = TransformWebMouseWheelEvent(
-        frame_impl_->GetFrameView(),
-        static_cast<const WebMouseWheelEvent&>(input_event));
-    handled = OverlayMainFrame()->GetEventHandler().HandleWheelEvent(
-                  transformed_event) != WebInputEventResult::kNotHandled;
-  }
-
-  return handled;
-}
-
-void InspectorOverlay::SetPausedInDebuggerMessage(const String& message) {
-  paused_in_debugger_message_ = message;
-  ScheduleUpdate();
-}
-
-void InspectorOverlay::ShowReloadingBlanket() {
-  show_reloading_blanket_ = true;
-  ScheduleUpdate();
-}
-
-void InspectorOverlay::HideReloadingBlanket() {
-  if (!show_reloading_blanket_)
-    return;
-  show_reloading_blanket_ = false;
-  if (suspended_)
-    ClearInternal();
-  else
-    ScheduleUpdate();
-}
-
-void InspectorOverlay::HideHighlight() {
-  highlight_node_.Clear();
-  event_target_node_.Clear();
-  highlight_quad_.reset();
-  ScheduleUpdate();
-}
-
-void InspectorOverlay::HighlightNode(
-    Node* node,
-    const InspectorHighlightConfig& highlight_config,
-    bool omit_tooltip) {
-  HighlightNode(node, nullptr, highlight_config, omit_tooltip);
-}
-
-void InspectorOverlay::HighlightNode(
-    Node* node,
-    Node* event_target,
-    const InspectorHighlightConfig& highlight_config,
-    bool omit_tooltip) {
-  node_highlight_config_ = highlight_config;
-  highlight_node_ = node;
-  event_target_node_ = event_target;
-  omit_tooltip_ = omit_tooltip;
-  ScheduleUpdate();
-}
-
-void InspectorOverlay::SetInspectMode(
-    InspectorDOMAgent::SearchMode search_mode,
-    std::unique_ptr<InspectorHighlightConfig> highlight_config) {
-  inspect_mode_ = search_mode;
-  ScheduleUpdate();
-
-  if (search_mode != InspectorDOMAgent::kNotSearching) {
-    inspect_mode_highlight_config_ = std::move(highlight_config);
-  } else {
-    hovered_node_for_inspect_mode_.Clear();
-    HideHighlight();
-  }
-}
-
-void InspectorOverlay::HighlightQuad(
-    std::unique_ptr<FloatQuad> quad,
-    const InspectorHighlightConfig& highlight_config) {
-  quad_highlight_config_ = highlight_config;
-  highlight_quad_ = std::move(quad);
-  omit_tooltip_ = false;
-  ScheduleUpdate();
-}
-
-bool InspectorOverlay::IsEmpty() {
-  if (show_reloading_blanket_)
-    return false;
-  if (suspended_)
-    return true;
-  bool has_visible_elements = highlight_node_ || event_target_node_ ||
-                              highlight_quad_ ||
-                              (resize_timer_active_ && draw_view_size_) ||
-                              !paused_in_debugger_message_.IsNull();
-  return !has_visible_elements &&
-         inspect_mode_ == InspectorDOMAgent::kNotSearching;
-}
-
-void InspectorOverlay::ScheduleUpdate() {
-  if (IsEmpty()) {
-    if (page_overlay_)
-      page_overlay_.reset();
-    return;
-  }
-  needs_update_ = true;
-  LocalFrame* frame = frame_impl_->GetFrame();
-  if (frame) {
-    frame->GetPage()->GetChromeClient().ScheduleAnimation(frame);
-  }
-}
-
-void InspectorOverlay::RebuildOverlayPage() {
-  FrameView* view = frame_impl_->GetFrameView();
-  LocalFrame* frame = frame_impl_->GetFrame();
-  if (!view || !frame)
-    return;
-
-  IntRect visible_rect_in_document =
-      view->GetScrollableArea()->VisibleContentRect();
-  IntSize viewport_size = frame->GetPage()->GetVisualViewport().Size();
-  OverlayMainFrame()->View()->Resize(viewport_size);
-  OverlayPage()->GetVisualViewport().SetSize(viewport_size);
-  OverlayMainFrame()->SetPageZoomFactor(WindowToViewportScale());
-
-  Reset(viewport_size, visible_rect_in_document.Location());
-
-  if (show_reloading_blanket_) {
-    EvaluateInOverlay("showReloadingBlanket", "");
-    return;
-  }
-  DrawNodeHighlight();
-  DrawQuadHighlight();
-  DrawPausedInDebuggerMessage();
-  DrawViewSize();
-}
-
-static std::unique_ptr<protocol::DictionaryValue> BuildObjectForSize(
-    const IntSize& size) {
-  std::unique_ptr<protocol::DictionaryValue> result =
-      protocol::DictionaryValue::create();
-  result->setInteger("width", size.Width());
-  result->setInteger("height", size.Height());
-  return result;
-}
-
-void InspectorOverlay::DrawNodeHighlight() {
-  if (!highlight_node_)
-    return;
-
-  String selectors = node_highlight_config_.selector_list;
-  StaticElementList* elements = nullptr;
-  DummyExceptionStateForTesting exception_state;
-  ContainerNode* query_base = highlight_node_->ContainingShadowRoot();
-  if (!query_base)
-    query_base = highlight_node_->ownerDocument();
-  if (selectors.length())
-    elements =
-        query_base->QuerySelectorAll(AtomicString(selectors), exception_state);
-  if (elements && !exception_state.HadException()) {
-    for (unsigned i = 0; i < elements->length(); ++i) {
-      Element* element = elements->item(i);
-      InspectorHighlight highlight(element, node_highlight_config_, false);
-      std::unique_ptr<protocol::DictionaryValue> highlight_json =
-          highlight.AsProtocolValue();
-      EvaluateInOverlay("drawHighlight", std::move(highlight_json));
-    }
-  }
-
-  bool append_element_info =
-      highlight_node_->IsElementNode() && !omit_tooltip_ &&
-      node_highlight_config_.show_info && highlight_node_->GetLayoutObject() &&
-      highlight_node_->GetDocument().GetFrame();
-  InspectorHighlight highlight(highlight_node_.Get(), node_highlight_config_,
-                               append_element_info);
-  if (event_target_node_)
-    highlight.AppendEventTargetQuads(event_target_node_.Get(),
-                                     node_highlight_config_);
-
-  std::unique_ptr<protocol::DictionaryValue> highlight_json =
-      highlight.AsProtocolValue();
-  EvaluateInOverlay("drawHighlight", std::move(highlight_json));
-}
-
-void InspectorOverlay::DrawQuadHighlight() {
-  if (!highlight_quad_)
-    return;
-
-  InspectorHighlight highlight(WindowToViewportScale());
-  highlight.AppendQuad(*highlight_quad_, quad_highlight_config_.content,
-                       quad_highlight_config_.content_outline);
-  EvaluateInOverlay("drawHighlight", highlight.AsProtocolValue());
-}
-
-void InspectorOverlay::DrawPausedInDebuggerMessage() {
-  if (inspect_mode_ == InspectorDOMAgent::kNotSearching &&
-      !paused_in_debugger_message_.IsNull())
-    EvaluateInOverlay("drawPausedInDebuggerMessage",
-                      paused_in_debugger_message_);
-}
-
-void InspectorOverlay::DrawViewSize() {
-  if (resize_timer_active_ && draw_view_size_)
-    EvaluateInOverlay("drawViewSize", "");
-}
-
-float InspectorOverlay::WindowToViewportScale() const {
-  LocalFrame* frame = frame_impl_->GetFrame();
-  if (!frame)
-    return 1.0f;
-  return frame->GetPage()->GetChromeClient().WindowToViewportScalar(1.0f);
-}
-
-Page* InspectorOverlay::OverlayPage() {
-  if (overlay_page_)
-    return overlay_page_.Get();
-
-  ScriptForbiddenScope::AllowUserAgentScript allow_script;
-
-  DEFINE_STATIC_LOCAL(LocalFrameClient, dummy_local_frame_client,
-                      (EmptyLocalFrameClient::Create()));
-  Page::PageClients page_clients;
-  FillWithEmptyClients(page_clients);
-  DCHECK(!overlay_chrome_client_);
-  overlay_chrome_client_ = InspectorOverlayChromeClient::Create(
-      frame_impl_->GetFrame()->GetPage()->GetChromeClient(), *this);
-  page_clients.chrome_client = overlay_chrome_client_.Get();
-  overlay_page_ = Page::Create(page_clients);
-
-  Settings& settings = frame_impl_->GetFrame()->GetPage()->GetSettings();
-  Settings& overlay_settings = overlay_page_->GetSettings();
-
-  overlay_settings.GetGenericFontFamilySettings().UpdateStandard(
-      settings.GetGenericFontFamilySettings().Standard());
-  overlay_settings.GetGenericFontFamilySettings().UpdateSerif(
-      settings.GetGenericFontFamilySettings().Serif());
-  overlay_settings.GetGenericFontFamilySettings().UpdateSansSerif(
-      settings.GetGenericFontFamilySettings().SansSerif());
-  overlay_settings.GetGenericFontFamilySettings().UpdateCursive(
-      settings.GetGenericFontFamilySettings().Cursive());
-  overlay_settings.GetGenericFontFamilySettings().UpdateFantasy(
-      settings.GetGenericFontFamilySettings().Fantasy());
-  overlay_settings.GetGenericFontFamilySettings().UpdatePictograph(
-      settings.GetGenericFontFamilySettings().Pictograph());
-  overlay_settings.SetMinimumFontSize(settings.GetMinimumFontSize());
-  overlay_settings.SetMinimumLogicalFontSize(
-      settings.GetMinimumLogicalFontSize());
-  overlay_settings.SetScriptEnabled(true);
-  overlay_settings.SetPluginsEnabled(false);
-  overlay_settings.SetLoadsImagesAutomatically(true);
-  // FIXME: http://crbug.com/363843. Inspector should probably create its
-  // own graphics layers and attach them to the tree rather than going
-  // through some non-composited paint function.
-  overlay_settings.SetAcceleratedCompositingEnabled(false);
-
-  LocalFrame* frame =
-      LocalFrame::Create(&dummy_local_frame_client, *overlay_page_, 0);
-  frame->SetView(FrameView::Create(*frame));
-  frame->Init();
-  FrameLoader& loader = frame->Loader();
-  frame->View()->SetCanHaveScrollbars(false);
-  frame->View()->SetBaseBackgroundColor(Color::kTransparent);
-
-  const WebData& overlay_page_html_resource =
-      Platform::Current()->LoadResource("InspectorOverlayPage.html");
-  loader.Load(
-      FrameLoadRequest(0, ResourceRequest(BlankURL()),
-                       SubstituteData(overlay_page_html_resource, "text/html",
-                                      "UTF-8", KURL(), kForceSynchronousLoad)));
-  v8::Isolate* isolate = ToIsolate(frame);
-  ScriptState* script_state = ToScriptStateForMainWorld(frame);
-  DCHECK(script_state);
-  ScriptState::Scope scope(script_state);
-  v8::Local<v8::Object> global = script_state->GetContext()->Global();
-  v8::Local<v8::Value> overlay_host_obj =
-      ToV8(overlay_host_.Get(), global, isolate);
-  DCHECK(!overlay_host_obj.IsEmpty());
-  global
-      ->Set(script_state->GetContext(),
-            V8AtomicString(isolate, "InspectorOverlayHost"), overlay_host_obj)
-      .ToChecked();
-
-#if OS(WIN)
-  EvaluateInOverlay("setPlatform", "windows");
-#elif OS(MACOSX)
-  EvaluateInOverlay("setPlatform", "mac");
-#elif OS(POSIX)
-  EvaluateInOverlay("setPlatform", "linux");
-#endif
-
-  return overlay_page_.Get();
-}
-
-LocalFrame* InspectorOverlay::OverlayMainFrame() {
-  return ToLocalFrame(OverlayPage()->MainFrame());
-}
-
-void InspectorOverlay::Reset(const IntSize& viewport_size,
-                             const IntPoint& document_scroll_offset) {
-  std::unique_ptr<protocol::DictionaryValue> reset_data =
-      protocol::DictionaryValue::create();
-  reset_data->setDouble(
-      "deviceScaleFactor",
-      frame_impl_->GetFrame()->GetPage()->DeviceScaleFactorDeprecated());
-  reset_data->setDouble(
-      "pageScaleFactor",
-      frame_impl_->GetFrame()->GetPage()->GetVisualViewport().Scale());
-
-  IntRect viewport_in_screen =
-      frame_impl_->GetFrame()->GetPage()->GetChromeClient().ViewportToScreen(
-          IntRect(IntPoint(), viewport_size), frame_impl_->GetFrame()->View());
-  reset_data->setObject("viewportSize",
-                        BuildObjectForSize(viewport_in_screen.Size()));
-
-  // The zoom factor in the overlay frame already has been multiplied by the
-  // window to viewport scale (aka device scale factor), so cancel it.
-  reset_data->setDouble(
-      "pageZoomFactor",
-      frame_impl_->GetFrame()->PageZoomFactor() / WindowToViewportScale());
-
-  reset_data->setInteger("scrollX", document_scroll_offset.X());
-  reset_data->setInteger("scrollY", document_scroll_offset.Y());
-  EvaluateInOverlay("reset", std::move(reset_data));
-}
-
-void InspectorOverlay::EvaluateInOverlay(const String& method,
-                                         const String& argument) {
-  ScriptForbiddenScope::AllowUserAgentScript allow_script;
-  std::unique_ptr<protocol::ListValue> command = protocol::ListValue::create();
-  command->pushValue(protocol::StringValue::create(method));
-  command->pushValue(protocol::StringValue::create(argument));
-  ToLocalFrame(OverlayPage()->MainFrame())
-      ->GetScriptController()
-      .ExecuteScriptInMainWorld(
-          "dispatch(" + command->serialize() + ")",
-          ScriptController::kExecuteScriptWhenScriptsDisabled);
-}
-
-void InspectorOverlay::EvaluateInOverlay(
-    const String& method,
-    std::unique_ptr<protocol::Value> argument) {
-  ScriptForbiddenScope::AllowUserAgentScript allow_script;
-  std::unique_ptr<protocol::ListValue> command = protocol::ListValue::create();
-  command->pushValue(protocol::StringValue::create(method));
-  command->pushValue(std::move(argument));
-  ToLocalFrame(OverlayPage()->MainFrame())
-      ->GetScriptController()
-      .ExecuteScriptInMainWorld(
-          "dispatch(" + command->serialize() + ")",
-          ScriptController::kExecuteScriptWhenScriptsDisabled);
-}
-
-String InspectorOverlay::EvaluateInOverlayForTest(const String& script) {
-  ScriptForbiddenScope::AllowUserAgentScript allow_script;
-  v8::HandleScope handle_scope(ToIsolate(OverlayMainFrame()));
-  v8::Local<v8::Value> string =
-      ToLocalFrame(OverlayPage()->MainFrame())
-          ->GetScriptController()
-          .ExecuteScriptInMainWorldAndReturnValue(
-              ScriptSourceCode(script),
-              ScriptController::kExecuteScriptWhenScriptsDisabled);
-  return ToCoreStringWithUndefinedOrNullCheck(string);
-}
-
-void InspectorOverlay::OnTimer(TimerBase*) {
-  resize_timer_active_ = false;
-  ScheduleUpdate();
-}
-
-void InspectorOverlay::ClearInternal() {
-  if (overlay_page_) {
-    overlay_page_->WillBeDestroyed();
-    overlay_page_.Clear();
-    overlay_chrome_client_.Clear();
-  }
-  resize_timer_active_ = false;
-  paused_in_debugger_message_ = String();
-  inspect_mode_ = InspectorDOMAgent::kNotSearching;
-  timer_.Stop();
-  HideHighlight();
-}
-
-void InspectorOverlay::Clear() {
-  ClearInternal();
-  v8_session_ = nullptr;
-  dom_agent_.Clear();
-  overlay_host_->SetListener(nullptr);
-}
-
-void InspectorOverlay::OverlayResumed() {
-  if (v8_session_)
-    v8_session_->resume();
-}
-
-void InspectorOverlay::OverlaySteppedOver() {
-  if (v8_session_)
-    v8_session_->stepOver();
-}
-
-void InspectorOverlay::Suspend() {
-  if (!suspended_) {
-    suspended_ = true;
-    ClearInternal();
-  }
-}
-
-void InspectorOverlay::Resume() {
-  suspended_ = false;
-}
-
-void InspectorOverlay::PageLayoutInvalidated(bool resized) {
-  if (resized && draw_view_size_) {
-    resize_timer_active_ = true;
-    timer_.StartOneShot(1, BLINK_FROM_HERE);
-  }
-  ScheduleUpdate();
-}
-
-void InspectorOverlay::SetShowViewportSizeOnResize(bool show) {
-  draw_view_size_ = show;
-}
-
-bool InspectorOverlay::HandleMouseMove(const WebMouseEvent& event) {
-  if (!ShouldSearchForNode())
-    return false;
-
-  LocalFrame* frame = frame_impl_->GetFrame();
-  if (!frame || !frame->View() || frame->ContentLayoutItem().IsNull())
-    return false;
-  Node* node = HoveredNodeForEvent(
-      frame, event, event.GetModifiers() & WebInputEvent::kShiftKey);
-
-  // Do not highlight within user agent shadow root unless requested.
-  if (inspect_mode_ != InspectorDOMAgent::kSearchingForUAShadow) {
-    ShadowRoot* shadow_root = InspectorDOMAgent::UserAgentShadowRoot(node);
-    if (shadow_root)
-      node = &shadow_root->host();
-  }
-
-  // Shadow roots don't have boxes - use host element instead.
-  if (node && node->IsShadowRoot())
-    node = node->ParentOrShadowHostNode();
-
-  if (!node)
-    return true;
-
-  if (node->IsFrameOwnerElement()) {
-    HTMLFrameOwnerElement* frame_owner = ToHTMLFrameOwnerElement(node);
-    if (frame_owner->ContentFrame() &&
-        !frame_owner->ContentFrame()->IsLocalFrame()) {
-      // Do not consume event so that remote frame can handle it.
-      HideHighlight();
-      hovered_node_for_inspect_mode_.Clear();
-      return false;
-    }
-  }
-
-  Node* event_target = (event.GetModifiers() & WebInputEvent::kShiftKey)
-                           ? HoveredNodeForEvent(frame, event, false)
-                           : nullptr;
-  if (event_target == node)
-    event_target = nullptr;
-
-  if (node && inspect_mode_highlight_config_) {
-    hovered_node_for_inspect_mode_ = node;
-    if (dom_agent_)
-      dom_agent_->NodeHighlightedInOverlay(node);
-    HighlightNode(node, event_target, *inspect_mode_highlight_config_,
-                  (event.GetModifiers() &
-                   (WebInputEvent::kControlKey | WebInputEvent::kMetaKey)));
-  }
-  return true;
-}
-
-bool InspectorOverlay::HandleMouseDown() {
-  swallow_next_mouse_up_ = false;
-  if (!ShouldSearchForNode())
-    return false;
-
-  if (hovered_node_for_inspect_mode_) {
-    swallow_next_mouse_up_ = true;
-    Inspect(hovered_node_for_inspect_mode_.Get());
-    hovered_node_for_inspect_mode_.Clear();
-    return true;
-  }
-  return false;
-}
-
-bool InspectorOverlay::HandleMouseUp() {
-  if (swallow_next_mouse_up_) {
-    swallow_next_mouse_up_ = false;
-    return true;
-  }
-  return false;
-}
-
-bool InspectorOverlay::HandleGestureEvent(const WebGestureEvent& event) {
-  if (!ShouldSearchForNode() || event.GetType() != WebInputEvent::kGestureTap)
-    return false;
-  Node* node = HoveredNodeForEvent(frame_impl_->GetFrame(), event, false);
-  if (node && inspect_mode_highlight_config_) {
-    HighlightNode(node, *inspect_mode_highlight_config_, false);
-    Inspect(node);
-    return true;
-  }
-  return false;
-}
-
-bool InspectorOverlay::HandleTouchEvent(const WebTouchEvent& event) {
-  if (!ShouldSearchForNode())
-    return false;
-  Node* node = HoveredNodeForEvent(frame_impl_->GetFrame(), event, false);
-  if (node && inspect_mode_highlight_config_) {
-    HighlightNode(node, *inspect_mode_highlight_config_, false);
-    Inspect(node);
-    return true;
-  }
-  return false;
-}
-
-bool InspectorOverlay::ShouldSearchForNode() {
-  return inspect_mode_ != InspectorDOMAgent::kNotSearching;
-}
-
-void InspectorOverlay::Inspect(Node* node) {
-  if (dom_agent_)
-    dom_agent_->Inspect(node);
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/web/InspectorOverlay.h b/third_party/WebKit/Source/web/InspectorOverlay.h
deleted file mode 100644
index 6cc0a65..0000000
--- a/third_party/WebKit/Source/web/InspectorOverlay.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2011 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:
- *
- * 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.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 InspectorOverlay_h
-#define InspectorOverlay_h
-
-#include <v8-inspector.h>
-#include <memory>
-#include "core/inspector/InspectorDOMAgent.h"
-#include "core/inspector/InspectorOverlayHost.h"
-#include "core/inspector/protocol/Forward.h"
-#include "platform/Timer.h"
-#include "platform/geometry/FloatQuad.h"
-#include "platform/geometry/LayoutRect.h"
-#include "platform/graphics/Color.h"
-#include "platform/heap/Handle.h"
-#include "platform/wtf/RefPtr.h"
-#include "platform/wtf/text/WTFString.h"
-#include "public/platform/WebInputEvent.h"
-
-namespace blink {
-
-class Color;
-class LocalFrame;
-class Node;
-class Page;
-class PageOverlay;
-class WebGestureEvent;
-class WebMouseEvent;
-class WebLocalFrameImpl;
-class WebTouchEvent;
-
-namespace protocol {
-class Value;
-}
-
-class InspectorOverlay final
-    : public GarbageCollectedFinalized<InspectorOverlay>,
-      public InspectorDOMAgent::Client,
-      public InspectorOverlayHost::Listener {
-  USING_GARBAGE_COLLECTED_MIXIN(InspectorOverlay);
-
- public:
-  explicit InspectorOverlay(WebLocalFrameImpl*);
-  ~InspectorOverlay() override;
-  DECLARE_TRACE();
-
-  void Init(v8_inspector::V8InspectorSession*, InspectorDOMAgent*);
-
-  void Clear();
-  void Suspend();
-  void Resume();
-  bool HandleInputEvent(const WebInputEvent&);
-  void PageLayoutInvalidated(bool resized);
-  void SetShowViewportSizeOnResize(bool);
-  void ShowReloadingBlanket();
-  void HideReloadingBlanket();
-  void SetPausedInDebuggerMessage(const String&);
-
-  // Does not yet include paint.
-  void UpdateAllLifecyclePhases();
-
-  PageOverlay* GetPageOverlay() { return page_overlay_.get(); };
-  String EvaluateInOverlayForTest(const String&);
-
- private:
-  class InspectorOverlayChromeClient;
-  class InspectorPageOverlayDelegate;
-
-  // InspectorOverlayHost::Listener implementation.
-  void OverlayResumed() override;
-  void OverlaySteppedOver() override;
-
-  // InspectorDOMAgent::Client implementation.
-  void HideHighlight() override;
-  void HighlightNode(Node*,
-                     const InspectorHighlightConfig&,
-                     bool omit_tooltip) override;
-  void HighlightQuad(std::unique_ptr<FloatQuad>,
-                     const InspectorHighlightConfig&) override;
-  void SetInspectMode(InspectorDOMAgent::SearchMode,
-                      std::unique_ptr<InspectorHighlightConfig>) override;
-
-  void HighlightNode(Node*,
-                     Node* event_target,
-                     const InspectorHighlightConfig&,
-                     bool omit_tooltip);
-  bool IsEmpty();
-  void DrawNodeHighlight();
-  void DrawQuadHighlight();
-  void DrawPausedInDebuggerMessage();
-  void DrawViewSize();
-
-  float WindowToViewportScale() const;
-
-  Page* OverlayPage();
-  LocalFrame* OverlayMainFrame();
-  void Reset(const IntSize& viewport_size,
-             const IntPoint& document_scroll_offset);
-  void EvaluateInOverlay(const String& method, const String& argument);
-  void EvaluateInOverlay(const String& method,
-                         std::unique_ptr<protocol::Value> argument);
-  void OnTimer(TimerBase*);
-  void RebuildOverlayPage();
-  void Invalidate();
-  void ScheduleUpdate();
-  void ClearInternal();
-
-  bool HandleMouseDown();
-  bool HandleMouseUp();
-  bool HandleGestureEvent(const WebGestureEvent&);
-  bool HandleTouchEvent(const WebTouchEvent&);
-  bool HandleMouseMove(const WebMouseEvent&);
-  bool ShouldSearchForNode();
-  void Inspect(Node*);
-
-  Member<WebLocalFrameImpl> frame_impl_;
-  String paused_in_debugger_message_;
-  Member<Node> highlight_node_;
-  Member<Node> event_target_node_;
-  InspectorHighlightConfig node_highlight_config_;
-  std::unique_ptr<FloatQuad> highlight_quad_;
-  Member<Page> overlay_page_;
-  Member<InspectorOverlayChromeClient> overlay_chrome_client_;
-  Member<InspectorOverlayHost> overlay_host_;
-  InspectorHighlightConfig quad_highlight_config_;
-  bool draw_view_size_;
-  bool resize_timer_active_;
-  bool omit_tooltip_;
-  TaskRunnerTimer<InspectorOverlay> timer_;
-  bool suspended_;
-  bool show_reloading_blanket_;
-  bool in_layout_;
-  bool needs_update_;
-  v8_inspector::V8InspectorSession* v8_session_;
-  Member<InspectorDOMAgent> dom_agent_;
-  std::unique_ptr<PageOverlay> page_overlay_;
-  Member<Node> hovered_node_for_inspect_mode_;
-  bool swallow_next_mouse_up_;
-  InspectorDOMAgent::SearchMode inspect_mode_;
-  std::unique_ptr<InspectorHighlightConfig> inspect_mode_highlight_config_;
-};
-
-}  // namespace blink
-
-#endif  // InspectorOverlay_h
diff --git a/third_party/WebKit/Source/web/InspectorOverlayAgent.cpp b/third_party/WebKit/Source/web/InspectorOverlayAgent.cpp
new file mode 100644
index 0000000..86e9716
--- /dev/null
+++ b/third_party/WebKit/Source/web/InspectorOverlayAgent.cpp
@@ -0,0 +1,1156 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 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.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 "web/InspectorOverlayAgent.h"
+
+#include <memory>
+
+#include "bindings/core/v8/ScriptController.h"
+#include "bindings/core/v8/ScriptSourceCode.h"
+#include "bindings/core/v8/V8Binding.h"
+#include "bindings/core/v8/V8InspectorOverlayHost.h"
+#include "core/dom/DOMNodeIds.h"
+#include "core/dom/Node.h"
+#include "core/dom/StaticNodeList.h"
+#include "core/dom/TaskRunnerHelper.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/LocalFrameClient.h"
+#include "core/frame/Settings.h"
+#include "core/frame/VisualViewport.h"
+#include "core/html/HTMLFrameOwnerElement.h"
+#include "core/input/EventHandler.h"
+#include "core/inspector/IdentifiersFactory.h"
+#include "core/inspector/InspectedFrames.h"
+#include "core/inspector/InspectorDOMAgent.h"
+#include "core/inspector/InspectorOverlayHost.h"
+#include "core/layout/api/LayoutViewItem.h"
+#include "core/loader/EmptyClients.h"
+#include "core/loader/FrameLoadRequest.h"
+#include "core/page/ChromeClient.h"
+#include "core/page/Page.h"
+#include "platform/ScriptForbiddenScope.h"
+#include "platform/graphics/Color.h"
+#include "platform/graphics/GraphicsContext.h"
+#include "platform/graphics/paint/CullRect.h"
+#include "platform/wtf/AutoReset.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebData.h"
+#include "v8/include/v8.h"
+#include "web/ChromeClientImpl.h"
+#include "web/PageOverlay.h"
+#include "web/WebInputEventConversion.h"
+#include "web/WebLocalFrameImpl.h"
+#include "web/WebViewImpl.h"
+
+namespace blink {
+
+using protocol::Maybe;
+using protocol::Response;
+
+namespace {
+
+namespace OverlayAgentState {
+static const char kEnabled[] = "enabled";
+static const char kShowDebugBorders[] = "showDebugBorders";
+static const char kShowFPSCounter[] = "showFPSCounter";
+static const char kShowPaintRects[] = "showPaintRects";
+static const char kShowScrollBottleneckRects[] = "showScrollBottleneckRects";
+static const char kShowSizeOnResize[] = "showSizeOnResize";
+static const char kSuspended[] = "suspended";
+static const char kPausedInDebuggerMessage[] = "pausedInDebuggerMessage";
+}
+
+Node* HoveredNodeForPoint(LocalFrame* frame,
+                          const IntPoint& point_in_root_frame,
+                          bool ignore_pointer_events_none) {
+  HitTestRequest::HitTestRequestType hit_type =
+      HitTestRequest::kMove | HitTestRequest::kReadOnly |
+      HitTestRequest::kAllowChildFrameContent;
+  if (ignore_pointer_events_none)
+    hit_type |= HitTestRequest::kIgnorePointerEventsNone;
+  HitTestRequest request(hit_type);
+  HitTestResult result(request,
+                       frame->View()->RootFrameToContents(point_in_root_frame));
+  frame->ContentLayoutItem().HitTest(result);
+  Node* node = result.InnerPossiblyPseudoNode();
+  while (node && node->getNodeType() == Node::kTextNode)
+    node = node->parentNode();
+  return node;
+}
+
+Node* HoveredNodeForEvent(LocalFrame* frame,
+                          const WebGestureEvent& event,
+                          bool ignore_pointer_events_none) {
+  return HoveredNodeForPoint(frame,
+                             RoundedIntPoint(event.PositionInRootFrame()),
+                             ignore_pointer_events_none);
+}
+
+Node* HoveredNodeForEvent(LocalFrame* frame,
+                          const WebMouseEvent& event,
+                          bool ignore_pointer_events_none) {
+  return HoveredNodeForPoint(frame,
+                             RoundedIntPoint(event.PositionInRootFrame()),
+                             ignore_pointer_events_none);
+}
+
+Node* HoveredNodeForEvent(LocalFrame* frame,
+                          const WebTouchEvent& event,
+                          bool ignore_pointer_events_none) {
+  if (!event.touches_length)
+    return nullptr;
+  WebTouchPoint transformed_point = event.TouchPointInRootFrame(0);
+  return HoveredNodeForPoint(frame, RoundedIntPoint(transformed_point.position),
+                             ignore_pointer_events_none);
+}
+
+bool ParseQuad(std::unique_ptr<protocol::Array<double>> quad_array,
+               FloatQuad* quad) {
+  const size_t kCoordinatesInQuad = 8;
+  if (!quad_array || quad_array->length() != kCoordinatesInQuad)
+    return false;
+  quad->SetP1(FloatPoint(quad_array->get(0), quad_array->get(1)));
+  quad->SetP2(FloatPoint(quad_array->get(2), quad_array->get(3)));
+  quad->SetP3(FloatPoint(quad_array->get(4), quad_array->get(5)));
+  quad->SetP4(FloatPoint(quad_array->get(6), quad_array->get(7)));
+  return true;
+}
+
+}  // namespace
+
+class InspectorOverlayAgent::InspectorPageOverlayDelegate final
+    : public PageOverlay::Delegate {
+ public:
+  explicit InspectorPageOverlayDelegate(InspectorOverlayAgent& overlay)
+      : overlay_(&overlay) {}
+
+  void PaintPageOverlay(const PageOverlay&,
+                        GraphicsContext& graphics_context,
+                        const WebSize& web_view_size) const override {
+    if (overlay_->IsEmpty())
+      return;
+
+    FrameView* view = overlay_->OverlayMainFrame()->View();
+    DCHECK(!view->NeedsLayout());
+    view->Paint(graphics_context,
+                CullRect(IntRect(0, 0, view->Width(), view->Height())));
+  }
+
+ private:
+  Persistent<InspectorOverlayAgent> overlay_;
+};
+
+class InspectorOverlayAgent::InspectorOverlayChromeClient final
+    : public EmptyChromeClient {
+ public:
+  static InspectorOverlayChromeClient* Create(ChromeClient& client,
+                                              InspectorOverlayAgent& overlay) {
+    return new InspectorOverlayChromeClient(client, overlay);
+  }
+
+  DEFINE_INLINE_VIRTUAL_TRACE() {
+    visitor->Trace(client_);
+    visitor->Trace(overlay_);
+    EmptyChromeClient::Trace(visitor);
+  }
+
+  void SetCursor(const Cursor& cursor, LocalFrame* local_root) override {
+    ToChromeClientImpl(client_)->SetCursorOverridden(false);
+    ToChromeClientImpl(client_)->SetCursor(cursor,
+                                           overlay_->frame_impl_->GetFrame());
+    ToChromeClientImpl(client_)->SetCursorOverridden(false);
+  }
+
+  void SetToolTip(LocalFrame& frame,
+                  const String& tooltip,
+                  TextDirection direction) override {
+    DCHECK_EQ(&frame, overlay_->OverlayMainFrame());
+    client_->SetToolTip(*overlay_->frame_impl_->GetFrame(), tooltip, direction);
+  }
+
+  void InvalidateRect(const IntRect&) override { overlay_->Invalidate(); }
+
+  void ScheduleAnimation(LocalFrame* frame) override {
+    if (overlay_->in_layout_)
+      return;
+
+    client_->ScheduleAnimation(frame);
+  }
+
+ private:
+  InspectorOverlayChromeClient(ChromeClient& client,
+                               InspectorOverlayAgent& overlay)
+      : client_(&client), overlay_(&overlay) {}
+
+  Member<ChromeClient> client_;
+  Member<InspectorOverlayAgent> overlay_;
+};
+
+InspectorOverlayAgent::InspectorOverlayAgent(
+    WebLocalFrameImpl* frame_impl,
+    InspectedFrames* inspected_frames,
+    v8_inspector::V8InspectorSession* v8_session,
+    InspectorDOMAgent* dom_agent)
+    : frame_impl_(frame_impl),
+      inspected_frames_(inspected_frames),
+      enabled_(false),
+      overlay_host_(new InspectorOverlayHost(this)),
+      draw_view_size_(false),
+      resize_timer_active_(false),
+      omit_tooltip_(false),
+      timer_(TaskRunnerHelper::Get(TaskType::kUnspecedTimer,
+                                   frame_impl->GetFrame()),
+             this,
+             &InspectorOverlayAgent::OnTimer),
+      suspended_(false),
+      show_reloading_blanket_(false),
+      in_layout_(false),
+      needs_update_(false),
+      v8_session_(v8_session),
+      dom_agent_(dom_agent),
+      swallow_next_mouse_up_(false),
+      inspect_mode_(kNotSearching),
+      backend_node_id_to_inspect_(0) {}
+
+InspectorOverlayAgent::~InspectorOverlayAgent() {
+  DCHECK(!overlay_page_);
+}
+
+DEFINE_TRACE(InspectorOverlayAgent) {
+  visitor->Trace(frame_impl_);
+  visitor->Trace(inspected_frames_);
+  visitor->Trace(highlight_node_);
+  visitor->Trace(event_target_node_);
+  visitor->Trace(overlay_page_);
+  visitor->Trace(overlay_chrome_client_);
+  visitor->Trace(overlay_host_);
+  visitor->Trace(dom_agent_);
+  visitor->Trace(hovered_node_for_inspect_mode_);
+  InspectorBaseAgent::Trace(visitor);
+}
+
+void InspectorOverlayAgent::Restore() {
+  if (state_->booleanProperty(OverlayAgentState::kEnabled, false))
+    enabled_ = true;
+  setShowDebugBorders(
+      state_->booleanProperty(OverlayAgentState::kShowDebugBorders, false));
+  setShowFPSCounter(
+      state_->booleanProperty(OverlayAgentState::kShowFPSCounter, false));
+  setShowPaintRects(
+      state_->booleanProperty(OverlayAgentState::kShowPaintRects, false));
+  setShowScrollBottleneckRects(state_->booleanProperty(
+      OverlayAgentState::kShowScrollBottleneckRects, false));
+  setShowViewportSizeOnResize(
+      state_->booleanProperty(OverlayAgentState::kShowSizeOnResize, false));
+  String message;
+  state_->getString(OverlayAgentState::kPausedInDebuggerMessage, &message);
+  setPausedInDebuggerMessage(message);
+  setSuspended(state_->booleanProperty(OverlayAgentState::kSuspended, false));
+}
+
+Response InspectorOverlayAgent::enable() {
+  if (!dom_agent_->Enabled())
+    return Response::Error("DOM should be enabled first");
+  state_->setBoolean(OverlayAgentState::kEnabled, true);
+  enabled_ = true;
+  if (backend_node_id_to_inspect_)
+    GetFrontend()->inspectNodeRequested(backend_node_id_to_inspect_);
+  backend_node_id_to_inspect_ = 0;
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::disable() {
+  state_->setBoolean(OverlayAgentState::kEnabled, false);
+  enabled_ = false;
+  setShowDebugBorders(false);
+  setShowFPSCounter(false);
+  setShowPaintRects(false);
+  setShowScrollBottleneckRects(false);
+  setShowViewportSizeOnResize(false);
+  setPausedInDebuggerMessage(String());
+  setSuspended(false);
+  SetSearchingForNode(kNotSearching,
+                      Maybe<protocol::Overlay::HighlightConfig>());
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::setShowDebugBorders(bool show) {
+  state_->setBoolean(OverlayAgentState::kShowDebugBorders, show);
+  if (show) {
+    Response response = CompositingEnabled();
+    if (!response.isSuccess())
+      return response;
+  }
+  frame_impl_->ViewImpl()->SetShowDebugBorders(show);
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::setShowFPSCounter(bool show) {
+  state_->setBoolean(OverlayAgentState::kShowFPSCounter, show);
+  if (show) {
+    Response response = CompositingEnabled();
+    if (!response.isSuccess())
+      return response;
+  }
+  frame_impl_->ViewImpl()->SetShowFPSCounter(show);
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::setShowPaintRects(bool show) {
+  state_->setBoolean(OverlayAgentState::kShowPaintRects, show);
+  if (show) {
+    Response response = CompositingEnabled();
+    if (!response.isSuccess())
+      return response;
+  }
+  frame_impl_->ViewImpl()->SetShowPaintRects(show);
+  if (!show && frame_impl_->GetFrameView())
+    frame_impl_->GetFrameView()->Invalidate();
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::setShowScrollBottleneckRects(bool show) {
+  state_->setBoolean(OverlayAgentState::kShowScrollBottleneckRects, show);
+  if (show) {
+    Response response = CompositingEnabled();
+    if (!response.isSuccess())
+      return response;
+  }
+  frame_impl_->ViewImpl()->SetShowScrollBottleneckRects(show);
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::setShowViewportSizeOnResize(bool show) {
+  state_->setBoolean(OverlayAgentState::kShowSizeOnResize, show);
+  draw_view_size_ = show;
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::setPausedInDebuggerMessage(
+    Maybe<String> message) {
+  String just_message = message.fromMaybe(String());
+  state_->setString(OverlayAgentState::kPausedInDebuggerMessage, just_message);
+  paused_in_debugger_message_ = just_message;
+  ScheduleUpdate();
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::setSuspended(bool suspended) {
+  state_->setBoolean(OverlayAgentState::kSuspended, suspended);
+  if (suspended && !suspended_ && !show_reloading_blanket_)
+    ClearInternal();
+  suspended_ = suspended;
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::setInspectMode(
+    const String& mode,
+    Maybe<protocol::Overlay::HighlightConfig> highlight_config) {
+  SearchMode search_mode;
+  if (mode == protocol::Overlay::InspectModeEnum::SearchForNode) {
+    search_mode = kSearchingForNormal;
+  } else if (mode == protocol::Overlay::InspectModeEnum::SearchForUAShadowDOM) {
+    search_mode = kSearchingForUAShadow;
+  } else if (mode == protocol::Overlay::InspectModeEnum::None) {
+    search_mode = kNotSearching;
+  } else {
+    return Response::Error(
+        String("Unknown mode \"" + mode + "\" was provided."));
+  }
+
+  if (search_mode != kNotSearching) {
+    Response response = dom_agent_->PushDocumentUponHandlelessOperation();
+    if (!response.isSuccess())
+      return response;
+  }
+
+  return SetSearchingForNode(search_mode, std::move(highlight_config));
+}
+
+Response InspectorOverlayAgent::highlightRect(
+    int x,
+    int y,
+    int width,
+    int height,
+    Maybe<protocol::DOM::RGBA> color,
+    Maybe<protocol::DOM::RGBA> outline_color) {
+  std::unique_ptr<FloatQuad> quad =
+      WTF::WrapUnique(new FloatQuad(FloatRect(x, y, width, height)));
+  InnerHighlightQuad(std::move(quad), std::move(color),
+                     std::move(outline_color));
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::highlightQuad(
+    std::unique_ptr<protocol::Array<double>> quad_array,
+    Maybe<protocol::DOM::RGBA> color,
+    Maybe<protocol::DOM::RGBA> outline_color) {
+  std::unique_ptr<FloatQuad> quad = WTF::MakeUnique<FloatQuad>();
+  if (!ParseQuad(std::move(quad_array), quad.get()))
+    return Response::Error("Invalid Quad format");
+  InnerHighlightQuad(std::move(quad), std::move(color),
+                     std::move(outline_color));
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::highlightNode(
+    std::unique_ptr<protocol::Overlay::HighlightConfig>
+        highlight_inspector_object,
+    Maybe<int> node_id,
+    Maybe<int> backend_node_id,
+    Maybe<String> object_id) {
+  Node* node = nullptr;
+  Response response;
+  if (node_id.isJust()) {
+    response = dom_agent_->AssertNode(node_id.fromJust(), node);
+  } else if (backend_node_id.isJust()) {
+    node = DOMNodeIds::NodeForId(backend_node_id.fromJust());
+    response = !node ? Response::Error("No node found for given backend id")
+                     : Response::OK();
+  } else if (object_id.isJust()) {
+    response = dom_agent_->NodeForRemoteObjectId(object_id.fromJust(), node);
+  } else {
+    response = Response::Error(
+        "Either nodeId, backendNodeId or objectId must be specified");
+  }
+
+  if (!response.isSuccess())
+    return response;
+
+  std::unique_ptr<InspectorHighlightConfig> highlight_config;
+  response = HighlightConfigFromInspectorObject(
+      std::move(highlight_inspector_object), &highlight_config);
+  if (!response.isSuccess())
+    return response;
+
+  InnerHighlightNode(node, nullptr, *highlight_config, false);
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::highlightFrame(
+    const String& frame_id,
+    Maybe<protocol::DOM::RGBA> color,
+    Maybe<protocol::DOM::RGBA> outline_color) {
+  LocalFrame* frame =
+      IdentifiersFactory::FrameById(inspected_frames_, frame_id);
+  // FIXME: Inspector doesn't currently work cross process.
+  if (frame && frame->DeprecatedLocalOwner()) {
+    std::unique_ptr<InspectorHighlightConfig> highlight_config =
+        WTF::MakeUnique<InspectorHighlightConfig>();
+    highlight_config->show_info = true;  // Always show tooltips for frames.
+    highlight_config->content =
+        InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr));
+    highlight_config->content_outline =
+        InspectorDOMAgent::ParseColor(outline_color.fromMaybe(nullptr));
+    InnerHighlightNode(frame->DeprecatedLocalOwner(), nullptr,
+                       *highlight_config, false);
+  }
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::hideHighlight() {
+  InnerHideHighlight();
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::getHighlightObjectForTest(
+    int node_id,
+    std::unique_ptr<protocol::DictionaryValue>* result) {
+  Node* node = nullptr;
+  Response response = dom_agent_->AssertNode(node_id, node);
+  if (!response.isSuccess())
+    return response;
+  InspectorHighlight highlight(node, InspectorHighlight::DefaultConfig(), true);
+  *result = highlight.AsProtocolValue();
+  return Response::OK();
+}
+
+void InspectorOverlayAgent::Invalidate() {
+  if (!page_overlay_) {
+    page_overlay_ = PageOverlay::Create(
+        frame_impl_, WTF::WrapUnique(new InspectorPageOverlayDelegate(*this)));
+  }
+
+  page_overlay_->Update();
+}
+
+void InspectorOverlayAgent::UpdateAllLifecyclePhases() {
+  if (IsEmpty())
+    return;
+
+  AutoReset<bool> scoped(&in_layout_, true);
+  if (needs_update_) {
+    needs_update_ = false;
+    RebuildOverlayPage();
+  }
+  OverlayMainFrame()->View()->UpdateAllLifecyclePhases();
+}
+
+bool InspectorOverlayAgent::HandleInputEvent(const WebInputEvent& input_event) {
+  bool handled = false;
+
+  if (IsEmpty())
+    return false;
+
+  if (input_event.GetType() == WebInputEvent::kGestureTap) {
+    // We only have a use for gesture tap.
+    WebGestureEvent transformed_event = TransformWebGestureEvent(
+        frame_impl_->GetFrameView(),
+        static_cast<const WebGestureEvent&>(input_event));
+    handled = HandleGestureEvent(transformed_event);
+    if (handled)
+      return true;
+
+    OverlayMainFrame()->GetEventHandler().HandleGestureEvent(transformed_event);
+  }
+  if (WebInputEvent::IsMouseEventType(input_event.GetType())) {
+    WebMouseEvent mouse_event =
+        TransformWebMouseEvent(frame_impl_->GetFrameView(),
+                               static_cast<const WebMouseEvent&>(input_event));
+
+    if (mouse_event.GetType() == WebInputEvent::kMouseMove)
+      handled = HandleMouseMove(mouse_event);
+    else if (mouse_event.GetType() == WebInputEvent::kMouseDown)
+      handled = HandleMouseDown();
+    else if (mouse_event.GetType() == WebInputEvent::kMouseUp)
+      handled = HandleMouseUp();
+
+    if (handled)
+      return true;
+
+    if (mouse_event.GetType() == WebInputEvent::kMouseMove) {
+      handled = OverlayMainFrame()->GetEventHandler().HandleMouseMoveEvent(
+                    mouse_event, TransformWebMouseEventVector(
+                                     frame_impl_->GetFrameView(),
+                                     std::vector<const WebInputEvent*>())) !=
+                WebInputEventResult::kNotHandled;
+    }
+    if (mouse_event.GetType() == WebInputEvent::kMouseDown) {
+      handled = OverlayMainFrame()->GetEventHandler().HandleMousePressEvent(
+                    mouse_event) != WebInputEventResult::kNotHandled;
+    }
+    if (mouse_event.GetType() == WebInputEvent::kMouseUp) {
+      handled = OverlayMainFrame()->GetEventHandler().HandleMouseReleaseEvent(
+                    mouse_event) != WebInputEventResult::kNotHandled;
+    }
+  }
+
+  if (WebInputEvent::IsTouchEventType(input_event.GetType())) {
+    WebTouchEvent transformed_event =
+        TransformWebTouchEvent(frame_impl_->GetFrameView(),
+                               static_cast<const WebTouchEvent&>(input_event));
+    handled = HandleTouchEvent(transformed_event);
+    if (handled)
+      return true;
+    OverlayMainFrame()->GetEventHandler().HandleTouchEvent(
+        transformed_event, Vector<WebTouchEvent>());
+  }
+  if (WebInputEvent::IsKeyboardEventType(input_event.GetType())) {
+    OverlayMainFrame()->GetEventHandler().KeyEvent(
+        static_cast<const WebKeyboardEvent&>(input_event));
+  }
+
+  if (input_event.GetType() == WebInputEvent::kMouseWheel) {
+    WebMouseWheelEvent transformed_event = TransformWebMouseWheelEvent(
+        frame_impl_->GetFrameView(),
+        static_cast<const WebMouseWheelEvent&>(input_event));
+    handled = OverlayMainFrame()->GetEventHandler().HandleWheelEvent(
+                  transformed_event) != WebInputEventResult::kNotHandled;
+  }
+
+  return handled;
+}
+
+void InspectorOverlayAgent::ShowReloadingBlanket() {
+  show_reloading_blanket_ = true;
+  ScheduleUpdate();
+}
+
+void InspectorOverlayAgent::HideReloadingBlanket() {
+  if (!show_reloading_blanket_)
+    return;
+  show_reloading_blanket_ = false;
+  if (suspended_)
+    ClearInternal();
+  else
+    ScheduleUpdate();
+}
+
+void InspectorOverlayAgent::InnerHideHighlight() {
+  highlight_node_.Clear();
+  event_target_node_.Clear();
+  highlight_quad_.reset();
+  ScheduleUpdate();
+}
+
+void InspectorOverlayAgent::InnerHighlightNode(
+    Node* node,
+    Node* event_target,
+    const InspectorHighlightConfig& highlight_config,
+    bool omit_tooltip) {
+  node_highlight_config_ = highlight_config;
+  highlight_node_ = node;
+  event_target_node_ = event_target;
+  omit_tooltip_ = omit_tooltip;
+  ScheduleUpdate();
+}
+
+void InspectorOverlayAgent::InnerHighlightQuad(
+    std::unique_ptr<FloatQuad> quad,
+    Maybe<protocol::DOM::RGBA> color,
+    Maybe<protocol::DOM::RGBA> outline_color) {
+  quad_content_color_ = InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr));
+  quad_content_outline_color_ =
+      InspectorDOMAgent::ParseColor(outline_color.fromMaybe(nullptr));
+  highlight_quad_ = std::move(quad);
+  omit_tooltip_ = false;
+  ScheduleUpdate();
+}
+
+bool InspectorOverlayAgent::IsEmpty() {
+  if (show_reloading_blanket_)
+    return false;
+  if (suspended_)
+    return true;
+  bool has_visible_elements = highlight_node_ || event_target_node_ ||
+                              highlight_quad_ ||
+                              (resize_timer_active_ && draw_view_size_) ||
+                              !paused_in_debugger_message_.IsNull();
+  return !has_visible_elements && inspect_mode_ == kNotSearching;
+}
+
+void InspectorOverlayAgent::ScheduleUpdate() {
+  if (IsEmpty()) {
+    if (page_overlay_)
+      page_overlay_.reset();
+    return;
+  }
+  needs_update_ = true;
+  LocalFrame* frame = frame_impl_->GetFrame();
+  if (frame) {
+    frame->GetPage()->GetChromeClient().ScheduleAnimation(frame);
+  }
+}
+
+void InspectorOverlayAgent::RebuildOverlayPage() {
+  FrameView* view = frame_impl_->GetFrameView();
+  LocalFrame* frame = frame_impl_->GetFrame();
+  if (!view || !frame)
+    return;
+
+  IntRect visible_rect_in_document =
+      view->GetScrollableArea()->VisibleContentRect();
+  IntSize viewport_size = frame->GetPage()->GetVisualViewport().Size();
+  OverlayMainFrame()->View()->Resize(viewport_size);
+  OverlayPage()->GetVisualViewport().SetSize(viewport_size);
+  OverlayMainFrame()->SetPageZoomFactor(WindowToViewportScale());
+
+  Reset(viewport_size, visible_rect_in_document.Location());
+
+  if (show_reloading_blanket_) {
+    EvaluateInOverlay("showReloadingBlanket", "");
+    return;
+  }
+  DrawNodeHighlight();
+  DrawQuadHighlight();
+  DrawPausedInDebuggerMessage();
+  DrawViewSize();
+}
+
+static std::unique_ptr<protocol::DictionaryValue> BuildObjectForSize(
+    const IntSize& size) {
+  std::unique_ptr<protocol::DictionaryValue> result =
+      protocol::DictionaryValue::create();
+  result->setInteger("width", size.Width());
+  result->setInteger("height", size.Height());
+  return result;
+}
+
+void InspectorOverlayAgent::DrawNodeHighlight() {
+  if (!highlight_node_)
+    return;
+
+  String selectors = node_highlight_config_.selector_list;
+  StaticElementList* elements = nullptr;
+  DummyExceptionStateForTesting exception_state;
+  ContainerNode* query_base = highlight_node_->ContainingShadowRoot();
+  if (!query_base)
+    query_base = highlight_node_->ownerDocument();
+  if (selectors.length()) {
+    elements =
+        query_base->QuerySelectorAll(AtomicString(selectors), exception_state);
+  }
+  if (elements && !exception_state.HadException()) {
+    for (unsigned i = 0; i < elements->length(); ++i) {
+      Element* element = elements->item(i);
+      InspectorHighlight highlight(element, node_highlight_config_, false);
+      std::unique_ptr<protocol::DictionaryValue> highlight_json =
+          highlight.AsProtocolValue();
+      EvaluateInOverlay("drawHighlight", std::move(highlight_json));
+    }
+  }
+
+  bool append_element_info =
+      highlight_node_->IsElementNode() && !omit_tooltip_ &&
+      node_highlight_config_.show_info && highlight_node_->GetLayoutObject() &&
+      highlight_node_->GetDocument().GetFrame();
+  InspectorHighlight highlight(highlight_node_.Get(), node_highlight_config_,
+                               append_element_info);
+  if (event_target_node_) {
+    highlight.AppendEventTargetQuads(event_target_node_.Get(),
+                                     node_highlight_config_);
+  }
+
+  std::unique_ptr<protocol::DictionaryValue> highlight_json =
+      highlight.AsProtocolValue();
+  EvaluateInOverlay("drawHighlight", std::move(highlight_json));
+}
+
+void InspectorOverlayAgent::DrawQuadHighlight() {
+  if (!highlight_quad_)
+    return;
+
+  InspectorHighlight highlight(WindowToViewportScale());
+  highlight.AppendQuad(*highlight_quad_, quad_content_color_,
+                       quad_content_outline_color_);
+  EvaluateInOverlay("drawHighlight", highlight.AsProtocolValue());
+}
+
+void InspectorOverlayAgent::DrawPausedInDebuggerMessage() {
+  if (inspect_mode_ == kNotSearching && !paused_in_debugger_message_.IsNull()) {
+    EvaluateInOverlay("drawPausedInDebuggerMessage",
+                      paused_in_debugger_message_);
+  }
+}
+
+void InspectorOverlayAgent::DrawViewSize() {
+  if (resize_timer_active_ && draw_view_size_)
+    EvaluateInOverlay("drawViewSize", "");
+}
+
+float InspectorOverlayAgent::WindowToViewportScale() const {
+  LocalFrame* frame = frame_impl_->GetFrame();
+  if (!frame)
+    return 1.0f;
+  return frame->GetPage()->GetChromeClient().WindowToViewportScalar(1.0f);
+}
+
+Page* InspectorOverlayAgent::OverlayPage() {
+  if (overlay_page_)
+    return overlay_page_.Get();
+
+  ScriptForbiddenScope::AllowUserAgentScript allow_script;
+
+  DEFINE_STATIC_LOCAL(LocalFrameClient, dummy_local_frame_client,
+                      (EmptyLocalFrameClient::Create()));
+  Page::PageClients page_clients;
+  FillWithEmptyClients(page_clients);
+  DCHECK(!overlay_chrome_client_);
+  overlay_chrome_client_ = InspectorOverlayChromeClient::Create(
+      frame_impl_->GetFrame()->GetPage()->GetChromeClient(), *this);
+  page_clients.chrome_client = overlay_chrome_client_.Get();
+  overlay_page_ = Page::Create(page_clients);
+
+  Settings& settings = frame_impl_->GetFrame()->GetPage()->GetSettings();
+  Settings& overlay_settings = overlay_page_->GetSettings();
+
+  overlay_settings.GetGenericFontFamilySettings().UpdateStandard(
+      settings.GetGenericFontFamilySettings().Standard());
+  overlay_settings.GetGenericFontFamilySettings().UpdateSerif(
+      settings.GetGenericFontFamilySettings().Serif());
+  overlay_settings.GetGenericFontFamilySettings().UpdateSansSerif(
+      settings.GetGenericFontFamilySettings().SansSerif());
+  overlay_settings.GetGenericFontFamilySettings().UpdateCursive(
+      settings.GetGenericFontFamilySettings().Cursive());
+  overlay_settings.GetGenericFontFamilySettings().UpdateFantasy(
+      settings.GetGenericFontFamilySettings().Fantasy());
+  overlay_settings.GetGenericFontFamilySettings().UpdatePictograph(
+      settings.GetGenericFontFamilySettings().Pictograph());
+  overlay_settings.SetMinimumFontSize(settings.GetMinimumFontSize());
+  overlay_settings.SetMinimumLogicalFontSize(
+      settings.GetMinimumLogicalFontSize());
+  overlay_settings.SetScriptEnabled(true);
+  overlay_settings.SetPluginsEnabled(false);
+  overlay_settings.SetLoadsImagesAutomatically(true);
+  // FIXME: http://crbug.com/363843. Inspector should probably create its
+  // own graphics layers and attach them to the tree rather than going
+  // through some non-composited paint function.
+  overlay_settings.SetAcceleratedCompositingEnabled(false);
+
+  LocalFrame* frame =
+      LocalFrame::Create(&dummy_local_frame_client, *overlay_page_, 0);
+  frame->SetView(FrameView::Create(*frame));
+  frame->Init();
+  FrameLoader& loader = frame->Loader();
+  frame->View()->SetCanHaveScrollbars(false);
+  frame->View()->SetBaseBackgroundColor(Color::kTransparent);
+
+  const WebData& overlay_page_html_resource =
+      Platform::Current()->LoadResource("InspectorOverlayPage.html");
+  loader.Load(
+      FrameLoadRequest(0, ResourceRequest(BlankURL()),
+                       SubstituteData(overlay_page_html_resource, "text/html",
+                                      "UTF-8", KURL(), kForceSynchronousLoad)));
+  v8::Isolate* isolate = ToIsolate(frame);
+  ScriptState* script_state = ToScriptStateForMainWorld(frame);
+  DCHECK(script_state);
+  ScriptState::Scope scope(script_state);
+  v8::Local<v8::Object> global = script_state->GetContext()->Global();
+  v8::Local<v8::Value> overlay_host_obj =
+      ToV8(overlay_host_.Get(), global, isolate);
+  DCHECK(!overlay_host_obj.IsEmpty());
+  global
+      ->Set(script_state->GetContext(),
+            V8AtomicString(isolate, "InspectorOverlayHost"), overlay_host_obj)
+      .ToChecked();
+
+#if OS(WIN)
+  EvaluateInOverlay("setPlatform", "windows");
+#elif OS(MACOSX)
+  EvaluateInOverlay("setPlatform", "mac");
+#elif OS(POSIX)
+  EvaluateInOverlay("setPlatform", "linux");
+#endif
+
+  return overlay_page_.Get();
+}
+
+LocalFrame* InspectorOverlayAgent::OverlayMainFrame() {
+  return ToLocalFrame(OverlayPage()->MainFrame());
+}
+
+void InspectorOverlayAgent::Reset(const IntSize& viewport_size,
+                                  const IntPoint& document_scroll_offset) {
+  std::unique_ptr<protocol::DictionaryValue> reset_data =
+      protocol::DictionaryValue::create();
+  reset_data->setDouble(
+      "deviceScaleFactor",
+      frame_impl_->GetFrame()->GetPage()->DeviceScaleFactorDeprecated());
+  reset_data->setDouble(
+      "pageScaleFactor",
+      frame_impl_->GetFrame()->GetPage()->GetVisualViewport().Scale());
+
+  IntRect viewport_in_screen =
+      frame_impl_->GetFrame()->GetPage()->GetChromeClient().ViewportToScreen(
+          IntRect(IntPoint(), viewport_size), frame_impl_->GetFrame()->View());
+  reset_data->setObject("viewportSize",
+                        BuildObjectForSize(viewport_in_screen.Size()));
+
+  // The zoom factor in the overlay frame already has been multiplied by the
+  // window to viewport scale (aka device scale factor), so cancel it.
+  reset_data->setDouble(
+      "pageZoomFactor",
+      frame_impl_->GetFrame()->PageZoomFactor() / WindowToViewportScale());
+
+  reset_data->setInteger("scrollX", document_scroll_offset.X());
+  reset_data->setInteger("scrollY", document_scroll_offset.Y());
+  EvaluateInOverlay("reset", std::move(reset_data));
+}
+
+void InspectorOverlayAgent::EvaluateInOverlay(const String& method,
+                                              const String& argument) {
+  ScriptForbiddenScope::AllowUserAgentScript allow_script;
+  std::unique_ptr<protocol::ListValue> command = protocol::ListValue::create();
+  command->pushValue(protocol::StringValue::create(method));
+  command->pushValue(protocol::StringValue::create(argument));
+  ToLocalFrame(OverlayPage()->MainFrame())
+      ->GetScriptController()
+      .ExecuteScriptInMainWorld(
+          "dispatch(" + command->serialize() + ")",
+          ScriptController::kExecuteScriptWhenScriptsDisabled);
+}
+
+void InspectorOverlayAgent::EvaluateInOverlay(
+    const String& method,
+    std::unique_ptr<protocol::Value> argument) {
+  ScriptForbiddenScope::AllowUserAgentScript allow_script;
+  std::unique_ptr<protocol::ListValue> command = protocol::ListValue::create();
+  command->pushValue(protocol::StringValue::create(method));
+  command->pushValue(std::move(argument));
+  ToLocalFrame(OverlayPage()->MainFrame())
+      ->GetScriptController()
+      .ExecuteScriptInMainWorld(
+          "dispatch(" + command->serialize() + ")",
+          ScriptController::kExecuteScriptWhenScriptsDisabled);
+}
+
+String InspectorOverlayAgent::EvaluateInOverlayForTest(const String& script) {
+  ScriptForbiddenScope::AllowUserAgentScript allow_script;
+  v8::HandleScope handle_scope(ToIsolate(OverlayMainFrame()));
+  v8::Local<v8::Value> string =
+      ToLocalFrame(OverlayPage()->MainFrame())
+          ->GetScriptController()
+          .ExecuteScriptInMainWorldAndReturnValue(
+              ScriptSourceCode(script),
+              ScriptController::kExecuteScriptWhenScriptsDisabled);
+  return ToCoreStringWithUndefinedOrNullCheck(string);
+}
+
+void InspectorOverlayAgent::OnTimer(TimerBase*) {
+  resize_timer_active_ = false;
+  ScheduleUpdate();
+}
+
+void InspectorOverlayAgent::ClearInternal() {
+  if (overlay_page_) {
+    overlay_page_->WillBeDestroyed();
+    overlay_page_.Clear();
+    overlay_chrome_client_.Clear();
+  }
+  resize_timer_active_ = false;
+  paused_in_debugger_message_ = String();
+  inspect_mode_ = kNotSearching;
+  timer_.Stop();
+  InnerHideHighlight();
+}
+
+void InspectorOverlayAgent::OverlayResumed() {
+  if (v8_session_)
+    v8_session_->resume();
+}
+
+void InspectorOverlayAgent::OverlaySteppedOver() {
+  if (v8_session_)
+    v8_session_->stepOver();
+}
+
+void InspectorOverlayAgent::PageLayoutInvalidated(bool resized) {
+  if (resized && draw_view_size_) {
+    resize_timer_active_ = true;
+    timer_.StartOneShot(1, BLINK_FROM_HERE);
+  }
+  ScheduleUpdate();
+}
+
+bool InspectorOverlayAgent::HandleMouseMove(const WebMouseEvent& event) {
+  if (!ShouldSearchForNode())
+    return false;
+
+  LocalFrame* frame = frame_impl_->GetFrame();
+  if (!frame || !frame->View() || frame->ContentLayoutItem().IsNull())
+    return false;
+  Node* node = HoveredNodeForEvent(
+      frame, event, event.GetModifiers() & WebInputEvent::kShiftKey);
+
+  // Do not highlight within user agent shadow root unless requested.
+  if (inspect_mode_ != kSearchingForUAShadow) {
+    ShadowRoot* shadow_root = InspectorDOMAgent::UserAgentShadowRoot(node);
+    if (shadow_root)
+      node = &shadow_root->host();
+  }
+
+  // Shadow roots don't have boxes - use host element instead.
+  if (node && node->IsShadowRoot())
+    node = node->ParentOrShadowHostNode();
+
+  if (!node)
+    return true;
+
+  if (node->IsFrameOwnerElement()) {
+    HTMLFrameOwnerElement* frame_owner = ToHTMLFrameOwnerElement(node);
+    if (frame_owner->ContentFrame() &&
+        !frame_owner->ContentFrame()->IsLocalFrame()) {
+      // Do not consume event so that remote frame can handle it.
+      InnerHideHighlight();
+      hovered_node_for_inspect_mode_.Clear();
+      return false;
+    }
+  }
+
+  Node* event_target = (event.GetModifiers() & WebInputEvent::kShiftKey)
+                           ? HoveredNodeForEvent(frame, event, false)
+                           : nullptr;
+  if (event_target == node)
+    event_target = nullptr;
+
+  if (node && inspect_mode_highlight_config_) {
+    hovered_node_for_inspect_mode_ = node;
+    NodeHighlightRequested(node);
+    bool omit_tooltip = event.GetModifiers() &
+                        (WebInputEvent::kControlKey | WebInputEvent::kMetaKey);
+    InnerHighlightNode(node, event_target, *inspect_mode_highlight_config_,
+                       omit_tooltip);
+  }
+  return true;
+}
+
+bool InspectorOverlayAgent::HandleMouseDown() {
+  swallow_next_mouse_up_ = false;
+  if (!ShouldSearchForNode())
+    return false;
+
+  if (hovered_node_for_inspect_mode_) {
+    swallow_next_mouse_up_ = true;
+    Inspect(hovered_node_for_inspect_mode_.Get());
+    hovered_node_for_inspect_mode_.Clear();
+    return true;
+  }
+  return false;
+}
+
+bool InspectorOverlayAgent::HandleMouseUp() {
+  if (swallow_next_mouse_up_) {
+    swallow_next_mouse_up_ = false;
+    return true;
+  }
+  return false;
+}
+
+bool InspectorOverlayAgent::HandleGestureEvent(const WebGestureEvent& event) {
+  if (!ShouldSearchForNode() || event.GetType() != WebInputEvent::kGestureTap)
+    return false;
+  Node* node = HoveredNodeForEvent(frame_impl_->GetFrame(), event, false);
+  if (node && inspect_mode_highlight_config_) {
+    InnerHighlightNode(node, nullptr, *inspect_mode_highlight_config_, false);
+    Inspect(node);
+    return true;
+  }
+  return false;
+}
+
+bool InspectorOverlayAgent::HandleTouchEvent(const WebTouchEvent& event) {
+  if (!ShouldSearchForNode())
+    return false;
+  Node* node = HoveredNodeForEvent(frame_impl_->GetFrame(), event, false);
+  if (node && inspect_mode_highlight_config_) {
+    InnerHighlightNode(node, nullptr, *inspect_mode_highlight_config_, false);
+    Inspect(node);
+    return true;
+  }
+  return false;
+}
+
+Response InspectorOverlayAgent::CompositingEnabled() {
+  bool main_frame = frame_impl_->ViewImpl() && !frame_impl_->Parent();
+  if (!main_frame || !frame_impl_->ViewImpl()
+                          ->GetPage()
+                          ->GetSettings()
+                          .GetAcceleratedCompositingEnabled())
+    return Response::Error("Compositing mode is not supported");
+  return Response::OK();
+}
+
+bool InspectorOverlayAgent::ShouldSearchForNode() {
+  return inspect_mode_ != kNotSearching;
+}
+
+void InspectorOverlayAgent::Inspect(Node* inspected_node) {
+  if (!inspected_node)
+    return;
+
+  Node* node = inspected_node;
+  while (node && !node->IsElementNode() && !node->IsDocumentNode() &&
+         !node->IsDocumentFragment())
+    node = node->ParentOrShadowHostNode();
+  if (!node)
+    return;
+
+  int backend_node_id = DOMNodeIds::IdForNode(node);
+  if (!enabled_) {
+    backend_node_id_to_inspect_ = backend_node_id;
+    return;
+  }
+
+  GetFrontend()->inspectNodeRequested(backend_node_id);
+}
+
+void InspectorOverlayAgent::NodeHighlightRequested(Node* node) {
+  if (!enabled_)
+    return;
+
+  while (node && !node->IsElementNode() && !node->IsDocumentNode() &&
+         !node->IsDocumentFragment())
+    node = node->ParentOrShadowHostNode();
+
+  if (!node)
+    return;
+
+  int node_id = dom_agent_->PushNodePathToFrontend(node);
+  GetFrontend()->nodeHighlightRequested(node_id);
+}
+
+Response InspectorOverlayAgent::SetSearchingForNode(
+    SearchMode search_mode,
+    Maybe<protocol::Overlay::HighlightConfig> highlight_inspector_object) {
+  if (search_mode == kNotSearching) {
+    inspect_mode_ = search_mode;
+    ScheduleUpdate();
+    hovered_node_for_inspect_mode_.Clear();
+    InnerHideHighlight();
+    return Response::OK();
+  }
+
+  std::unique_ptr<InspectorHighlightConfig> config;
+  Response response = HighlightConfigFromInspectorObject(
+      std::move(highlight_inspector_object), &config);
+  if (!response.isSuccess())
+    return response;
+  inspect_mode_ = search_mode;
+  inspect_mode_highlight_config_ = std::move(config);
+  ScheduleUpdate();
+  return Response::OK();
+}
+
+Response InspectorOverlayAgent::HighlightConfigFromInspectorObject(
+    Maybe<protocol::Overlay::HighlightConfig> highlight_inspector_object,
+    std::unique_ptr<InspectorHighlightConfig>* out_config) {
+  if (!highlight_inspector_object.isJust()) {
+    return Response::Error(
+        "Internal error: highlight configuration parameter is missing");
+  }
+
+  protocol::Overlay::HighlightConfig* config =
+      highlight_inspector_object.fromJust();
+  std::unique_ptr<InspectorHighlightConfig> highlight_config =
+      WTF::MakeUnique<InspectorHighlightConfig>();
+  highlight_config->show_info = config->getShowInfo(false);
+  highlight_config->show_rulers = config->getShowRulers(false);
+  highlight_config->show_extension_lines = config->getShowExtensionLines(false);
+  highlight_config->display_as_material = config->getDisplayAsMaterial(false);
+  highlight_config->content =
+      InspectorDOMAgent::ParseColor(config->getContentColor(nullptr));
+  highlight_config->padding =
+      InspectorDOMAgent::ParseColor(config->getPaddingColor(nullptr));
+  highlight_config->border =
+      InspectorDOMAgent::ParseColor(config->getBorderColor(nullptr));
+  highlight_config->margin =
+      InspectorDOMAgent::ParseColor(config->getMarginColor(nullptr));
+  highlight_config->event_target =
+      InspectorDOMAgent::ParseColor(config->getEventTargetColor(nullptr));
+  highlight_config->shape =
+      InspectorDOMAgent::ParseColor(config->getShapeColor(nullptr));
+  highlight_config->shape_margin =
+      InspectorDOMAgent::ParseColor(config->getShapeMarginColor(nullptr));
+  highlight_config->selector_list = config->getSelectorList("");
+
+  *out_config = std::move(highlight_config);
+  return Response::OK();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/web/InspectorOverlayAgent.h b/third_party/WebKit/Source/web/InspectorOverlayAgent.h
new file mode 100644
index 0000000..9662583
--- /dev/null
+++ b/third_party/WebKit/Source/web/InspectorOverlayAgent.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * 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.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 InspectorOverlayAgent_h
+#define InspectorOverlayAgent_h
+
+#include <v8-inspector.h>
+#include <memory>
+#include "core/inspector/InspectorBaseAgent.h"
+#include "core/inspector/InspectorHighlight.h"
+#include "core/inspector/InspectorOverlayHost.h"
+#include "core/inspector/protocol/Overlay.h"
+#include "platform/Timer.h"
+#include "platform/geometry/FloatQuad.h"
+#include "platform/geometry/LayoutRect.h"
+#include "platform/graphics/Color.h"
+#include "platform/heap/Handle.h"
+#include "platform/wtf/RefPtr.h"
+#include "platform/wtf/text/WTFString.h"
+#include "public/platform/WebInputEvent.h"
+
+namespace blink {
+
+class Color;
+class InspectedFrames;
+class InspectorDOMAgent;
+class LocalFrame;
+class Node;
+class Page;
+class PageOverlay;
+class WebGestureEvent;
+class WebMouseEvent;
+class WebLocalFrameImpl;
+class WebTouchEvent;
+
+class InspectorOverlayAgent final
+    : public InspectorBaseAgent<protocol::Overlay::Metainfo>,
+      public InspectorOverlayHost::Listener {
+  USING_GARBAGE_COLLECTED_MIXIN(InspectorOverlayAgent);
+
+ public:
+  InspectorOverlayAgent(WebLocalFrameImpl*,
+                        InspectedFrames*,
+                        v8_inspector::V8InspectorSession*,
+                        InspectorDOMAgent*);
+  ~InspectorOverlayAgent() override;
+  DECLARE_TRACE();
+
+  // protocol::Dispatcher::OverlayCommandHandler implementation.
+  protocol::Response enable() override;
+  protocol::Response disable() override;
+  protocol::Response setShowPaintRects(bool) override;
+  protocol::Response setShowDebugBorders(bool) override;
+  protocol::Response setShowFPSCounter(bool) override;
+  protocol::Response setShowScrollBottleneckRects(bool) override;
+  protocol::Response setShowViewportSizeOnResize(bool) override;
+  protocol::Response setPausedInDebuggerMessage(
+      protocol::Maybe<String>) override;
+  protocol::Response setSuspended(bool) override;
+  protocol::Response setInspectMode(
+      const String& mode,
+      protocol::Maybe<protocol::Overlay::HighlightConfig>) override;
+  protocol::Response highlightRect(
+      int x,
+      int y,
+      int width,
+      int height,
+      protocol::Maybe<protocol::DOM::RGBA> color,
+      protocol::Maybe<protocol::DOM::RGBA> outline_color) override;
+  protocol::Response highlightQuad(
+      std::unique_ptr<protocol::Array<double>> quad,
+      protocol::Maybe<protocol::DOM::RGBA> color,
+      protocol::Maybe<protocol::DOM::RGBA> outline_color) override;
+  protocol::Response highlightNode(
+      std::unique_ptr<protocol::Overlay::HighlightConfig>,
+      protocol::Maybe<int> node_id,
+      protocol::Maybe<int> backend_node_id,
+      protocol::Maybe<String> object_id) override;
+  protocol::Response hideHighlight() override;
+  protocol::Response highlightFrame(
+      const String& frame_id,
+      protocol::Maybe<protocol::DOM::RGBA> content_color,
+      protocol::Maybe<protocol::DOM::RGBA> content_outline_color) override;
+  protocol::Response getHighlightObjectForTest(
+      int node_id,
+      std::unique_ptr<protocol::DictionaryValue>* highlight) override;
+
+  // InspectorBaseAgent overrides.
+  void Restore() override;
+
+  void Inspect(Node*);
+  bool HandleInputEvent(const WebInputEvent&);
+  void PageLayoutInvalidated(bool resized);
+  void ShowReloadingBlanket();
+  void HideReloadingBlanket();
+  // Does not yet include paint.
+  void UpdateAllLifecyclePhases();
+  PageOverlay* GetPageOverlay() { return page_overlay_.get(); };
+  String EvaluateInOverlayForTest(const String&);
+
+ private:
+  class InspectorOverlayChromeClient;
+  class InspectorPageOverlayDelegate;
+
+  enum SearchMode {
+    kNotSearching,
+    kSearchingForNormal,
+    kSearchingForUAShadow,
+  };
+
+  // InspectorOverlayHost::Listener implementation.
+  void OverlayResumed() override;
+  void OverlaySteppedOver() override;
+
+  bool IsEmpty();
+  void DrawNodeHighlight();
+  void DrawQuadHighlight();
+  void DrawPausedInDebuggerMessage();
+  void DrawViewSize();
+
+  float WindowToViewportScale() const;
+
+  Page* OverlayPage();
+  LocalFrame* OverlayMainFrame();
+  void Reset(const IntSize& viewport_size,
+             const IntPoint& document_scroll_offset);
+  void EvaluateInOverlay(const String& method, const String& argument);
+  void EvaluateInOverlay(const String& method,
+                         std::unique_ptr<protocol::Value> argument);
+  void OnTimer(TimerBase*);
+  void RebuildOverlayPage();
+  void Invalidate();
+  void ScheduleUpdate();
+  void ClearInternal();
+
+  bool HandleMouseDown();
+  bool HandleMouseUp();
+  bool HandleGestureEvent(const WebGestureEvent&);
+  bool HandleTouchEvent(const WebTouchEvent&);
+  bool HandleMouseMove(const WebMouseEvent&);
+
+  protocol::Response CompositingEnabled();
+
+  bool ShouldSearchForNode();
+  void NodeHighlightRequested(Node*);
+  protocol::Response SetSearchingForNode(
+      SearchMode,
+      protocol::Maybe<protocol::Overlay::HighlightConfig>);
+  protocol::Response HighlightConfigFromInspectorObject(
+      protocol::Maybe<protocol::Overlay::HighlightConfig>
+          highlight_inspector_object,
+      std::unique_ptr<InspectorHighlightConfig>*);
+  void InnerHighlightQuad(std::unique_ptr<FloatQuad>,
+                          protocol::Maybe<protocol::DOM::RGBA> color,
+                          protocol::Maybe<protocol::DOM::RGBA> outline_color);
+  void InnerHighlightNode(Node*,
+                          Node* event_target,
+                          const InspectorHighlightConfig&,
+                          bool omit_tooltip);
+  void InnerHideHighlight();
+
+  Member<WebLocalFrameImpl> frame_impl_;
+  Member<InspectedFrames> inspected_frames_;
+  bool enabled_;
+  String paused_in_debugger_message_;
+  Member<Node> highlight_node_;
+  Member<Node> event_target_node_;
+  InspectorHighlightConfig node_highlight_config_;
+  std::unique_ptr<FloatQuad> highlight_quad_;
+  Member<Page> overlay_page_;
+  Member<InspectorOverlayChromeClient> overlay_chrome_client_;
+  Member<InspectorOverlayHost> overlay_host_;
+  Color quad_content_color_;
+  Color quad_content_outline_color_;
+  bool draw_view_size_;
+  bool resize_timer_active_;
+  bool omit_tooltip_;
+  TaskRunnerTimer<InspectorOverlayAgent> timer_;
+  bool suspended_;
+  bool show_reloading_blanket_;
+  bool in_layout_;
+  bool needs_update_;
+  v8_inspector::V8InspectorSession* v8_session_;
+  Member<InspectorDOMAgent> dom_agent_;
+  std::unique_ptr<PageOverlay> page_overlay_;
+  Member<Node> hovered_node_for_inspect_mode_;
+  bool swallow_next_mouse_up_;
+  SearchMode inspect_mode_;
+  std::unique_ptr<InspectorHighlightConfig> inspect_mode_highlight_config_;
+  int backend_node_id_to_inspect_;
+};
+
+}  // namespace blink
+
+#endif  // InspectorOverlayAgent_h
diff --git a/third_party/WebKit/Source/web/InspectorRenderingAgent.cpp b/third_party/WebKit/Source/web/InspectorRenderingAgent.cpp
deleted file mode 100644
index 75ef216..0000000
--- a/third_party/WebKit/Source/web/InspectorRenderingAgent.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "web/InspectorRenderingAgent.h"
-
-#include "core/frame/FrameView.h"
-#include "core/frame/Settings.h"
-#include "core/page/Page.h"
-#include "web/InspectorOverlay.h"
-#include "web/WebLocalFrameImpl.h"
-#include "web/WebViewImpl.h"
-
-namespace blink {
-
-using protocol::Response;
-
-namespace RenderingAgentState {
-static const char kShowDebugBorders[] = "showDebugBorders";
-static const char kShowFPSCounter[] = "showFPSCounter";
-static const char kShowPaintRects[] = "showPaintRects";
-static const char kShowScrollBottleneckRects[] = "showScrollBottleneckRects";
-static const char kShowSizeOnResize[] = "showSizeOnResize";
-}
-
-InspectorRenderingAgent* InspectorRenderingAgent::Create(
-    WebLocalFrameImpl* web_local_frame_impl,
-    InspectorOverlay* overlay) {
-  return new InspectorRenderingAgent(web_local_frame_impl, overlay);
-}
-
-InspectorRenderingAgent::InspectorRenderingAgent(
-    WebLocalFrameImpl* web_local_frame_impl,
-    InspectorOverlay* overlay)
-    : web_local_frame_impl_(web_local_frame_impl), overlay_(overlay) {}
-
-WebViewImpl* InspectorRenderingAgent::GetWebViewImpl() {
-  return web_local_frame_impl_->ViewImpl();
-}
-
-void InspectorRenderingAgent::Restore() {
-  setShowDebugBorders(
-      state_->booleanProperty(RenderingAgentState::kShowDebugBorders, false));
-  setShowFPSCounter(
-      state_->booleanProperty(RenderingAgentState::kShowFPSCounter, false));
-  setShowPaintRects(
-      state_->booleanProperty(RenderingAgentState::kShowPaintRects, false));
-  setShowScrollBottleneckRects(state_->booleanProperty(
-      RenderingAgentState::kShowScrollBottleneckRects, false));
-  setShowViewportSizeOnResize(
-      state_->booleanProperty(RenderingAgentState::kShowSizeOnResize, false));
-}
-
-Response InspectorRenderingAgent::disable() {
-  setShowDebugBorders(false);
-  setShowFPSCounter(false);
-  setShowPaintRects(false);
-  setShowScrollBottleneckRects(false);
-  setShowViewportSizeOnResize(false);
-  return Response::OK();
-}
-
-Response InspectorRenderingAgent::setShowDebugBorders(bool show) {
-  state_->setBoolean(RenderingAgentState::kShowDebugBorders, show);
-  if (show) {
-    Response response = CompositingEnabled();
-    if (!response.isSuccess())
-      return response;
-  }
-  GetWebViewImpl()->SetShowDebugBorders(show);
-  return Response::OK();
-}
-
-Response InspectorRenderingAgent::setShowFPSCounter(bool show) {
-  state_->setBoolean(RenderingAgentState::kShowFPSCounter, show);
-  if (show) {
-    Response response = CompositingEnabled();
-    if (!response.isSuccess())
-      return response;
-  }
-  GetWebViewImpl()->SetShowFPSCounter(show);
-  return Response::OK();
-}
-
-Response InspectorRenderingAgent::setShowPaintRects(bool show) {
-  state_->setBoolean(RenderingAgentState::kShowPaintRects, show);
-  GetWebViewImpl()->SetShowPaintRects(show);
-  if (!show && web_local_frame_impl_->GetFrameView())
-    web_local_frame_impl_->GetFrameView()->Invalidate();
-  return Response::OK();
-}
-
-Response InspectorRenderingAgent::setShowScrollBottleneckRects(bool show) {
-  state_->setBoolean(RenderingAgentState::kShowScrollBottleneckRects, show);
-  if (show) {
-    Response response = CompositingEnabled();
-    if (!response.isSuccess())
-      return response;
-  }
-  GetWebViewImpl()->SetShowScrollBottleneckRects(show);
-  return Response::OK();
-}
-
-Response InspectorRenderingAgent::setShowViewportSizeOnResize(bool show) {
-  state_->setBoolean(RenderingAgentState::kShowSizeOnResize, show);
-  if (overlay_)
-    overlay_->SetShowViewportSizeOnResize(show);
-  return Response::OK();
-}
-
-Response InspectorRenderingAgent::CompositingEnabled() {
-  if (!GetWebViewImpl()
-           ->GetPage()
-           ->GetSettings()
-           .GetAcceleratedCompositingEnabled())
-    return Response::Error("Compositing mode is not supported");
-  return Response::OK();
-}
-
-DEFINE_TRACE(InspectorRenderingAgent) {
-  visitor->Trace(web_local_frame_impl_);
-  visitor->Trace(overlay_);
-  InspectorBaseAgent::Trace(visitor);
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/web/InspectorRenderingAgent.h b/third_party/WebKit/Source/web/InspectorRenderingAgent.h
deleted file mode 100644
index a22ba79..0000000
--- a/third_party/WebKit/Source/web/InspectorRenderingAgent.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef InspectorRenderingAgent_h
-#define InspectorRenderingAgent_h
-
-#include "core/inspector/InspectorBaseAgent.h"
-#include "core/inspector/protocol/Rendering.h"
-
-namespace blink {
-
-class InspectorOverlay;
-class WebLocalFrameImpl;
-class WebViewImpl;
-
-class InspectorRenderingAgent final
-    : public InspectorBaseAgent<protocol::Rendering::Metainfo> {
-  WTF_MAKE_NONCOPYABLE(InspectorRenderingAgent);
-
- public:
-  static InspectorRenderingAgent* Create(WebLocalFrameImpl*, InspectorOverlay*);
-
-  // protocol::Dispatcher::PageCommandHandler implementation.
-  protocol::Response setShowPaintRects(bool) override;
-  protocol::Response setShowDebugBorders(bool) override;
-  protocol::Response setShowFPSCounter(bool) override;
-  protocol::Response setShowScrollBottleneckRects(bool) override;
-  protocol::Response setShowViewportSizeOnResize(bool) override;
-
-  // InspectorBaseAgent overrides.
-  protocol::Response disable() override;
-  void Restore() override;
-
-  DECLARE_VIRTUAL_TRACE();
-
- private:
-  InspectorRenderingAgent(WebLocalFrameImpl*, InspectorOverlay*);
-  protocol::Response CompositingEnabled();
-  WebViewImpl* GetWebViewImpl();
-
-  Member<WebLocalFrameImpl> web_local_frame_impl_;
-  Member<InspectorOverlay> overlay_;
-};
-
-}  // namespace blink
-
-#endif  // !defined(InspectorRenderingAgent_h)
diff --git a/third_party/WebKit/Source/web/ValidationMessageClientImpl.cpp b/third_party/WebKit/Source/web/ValidationMessageClientImpl.cpp
index f92b657..0608b48 100644
--- a/third_party/WebKit/Source/web/ValidationMessageClientImpl.cpp
+++ b/third_party/WebKit/Source/web/ValidationMessageClientImpl.cpp
@@ -28,7 +28,7 @@
 #include "core/dom/Element.h"
 #include "core/dom/TaskRunnerHelper.h"
 #include "core/frame/FrameView.h"
-#include "platform/HostWindow.h"
+#include "platform/PlatformChromeClient.h"
 #include "platform/wtf/CurrentTime.h"
 #include "public/platform/WebRect.h"
 #include "public/platform/WebString.h"
@@ -73,8 +73,8 @@
   IntRect anchor_in_viewport =
       CurrentView()->ContentsToViewport(anchor.PixelSnappedBoundingBox());
   last_anchor_rect_in_screen_ =
-      CurrentView()->GetHostWindow()->ViewportToScreen(anchor_in_viewport,
-                                                       CurrentView());
+      CurrentView()->GetChromeClient()->ViewportToScreen(anchor_in_viewport,
+                                                         CurrentView());
   last_page_scale_factor_ = web_view_.PageScaleFactor();
   message_ = message;
   const double kMinimumSecondToShowValidationMessage = 5.0;
@@ -137,7 +137,7 @@
   }
 
   IntRect new_anchor_rect_in_viewport_in_screen =
-      CurrentView()->GetHostWindow()->ViewportToScreen(
+      CurrentView()->GetChromeClient()->ViewportToScreen(
           new_anchor_rect_in_viewport, CurrentView());
   if (new_anchor_rect_in_viewport_in_screen == last_anchor_rect_in_screen_ &&
       web_view_.PageScaleFactor() == last_page_scale_factor_)
diff --git a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
index 3609203..b2577a4 100644
--- a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
+++ b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
@@ -84,8 +84,7 @@
 #include "public/web/WebSettings.h"
 #include "web/DevToolsEmulator.h"
 #include "web/InspectorEmulationAgent.h"
-#include "web/InspectorOverlay.h"
-#include "web/InspectorRenderingAgent.h"
+#include "web/InspectorOverlayAgent.h"
 #include "web/WebFrameWidgetImpl.h"
 #include "web/WebInputEventConversion.h"
 #include "web/WebLocalFrameImpl.h"
@@ -233,11 +232,9 @@
 WebDevToolsAgentImpl* WebDevToolsAgentImpl::Create(
     WebLocalFrameImpl* frame,
     WebDevToolsAgentClient* client) {
-  InspectorOverlay* overlay = new InspectorOverlay(frame);
-
   if (!IsMainFrame(frame)) {
     WebDevToolsAgentImpl* agent =
-        new WebDevToolsAgentImpl(frame, client, overlay, false);
+        new WebDevToolsAgentImpl(frame, client, false);
     if (frame->FrameWidget())
       agent->LayerTreeViewChanged(
           ToWebFrameWidgetImpl(frame->FrameWidget())->LayerTreeView());
@@ -245,8 +242,7 @@
   }
 
   WebViewImpl* view = frame->ViewImpl();
-  WebDevToolsAgentImpl* agent =
-      new WebDevToolsAgentImpl(frame, client, overlay, true);
+  WebDevToolsAgentImpl* agent = new WebDevToolsAgentImpl(frame, client, true);
   agent->LayerTreeViewChanged(view->LayerTreeView());
   return agent;
 }
@@ -254,7 +250,6 @@
 WebDevToolsAgentImpl::WebDevToolsAgentImpl(
     WebLocalFrameImpl* web_local_frame_impl,
     WebDevToolsAgentClient* client,
-    InspectorOverlay* overlay,
     bool include_view_agents)
     : client_(client),
       web_local_frame_impl_(web_local_frame_impl),
@@ -262,16 +257,15 @@
           web_local_frame_impl_->GetFrame()->InstrumentingAgents()),
       resource_content_loader_(InspectorResourceContentLoader::Create(
           web_local_frame_impl_->GetFrame())),
-      overlay_(overlay),
       inspected_frames_(
           InspectedFrames::Create(web_local_frame_impl_->GetFrame())),
       resource_container_(new InspectorResourceContainer(inspected_frames_)),
-      dom_agent_(nullptr),
       page_agent_(nullptr),
       network_agent_(nullptr),
       layer_tree_agent_(nullptr),
       tracing_agent_(nullptr),
       trace_events_agent_(new InspectorTraceEvents()),
+      overlay_agent_(nullptr),
       include_view_agents_(include_view_agents),
       layer_tree_id_(0) {
   DCHECK(IsMainThread());
@@ -287,15 +281,14 @@
   visitor->Trace(web_local_frame_impl_);
   visitor->Trace(instrumenting_agents_);
   visitor->Trace(resource_content_loader_);
-  visitor->Trace(overlay_);
   visitor->Trace(inspected_frames_);
   visitor->Trace(resource_container_);
-  visitor->Trace(dom_agent_);
   visitor->Trace(page_agent_);
   visitor->Trace(network_agent_);
   visitor->Trace(layer_tree_agent_);
   visitor->Trace(tracing_agent_);
   visitor->Trace(trace_events_agent_);
+  visitor->Trace(overlay_agent_);
   visitor->Trace(session_);
 }
 
@@ -323,8 +316,7 @@
       main_thread_debugger->ContextGroupId(inspected_frames_->Root()), state);
 
   InspectorDOMAgent* dom_agent = new InspectorDOMAgent(
-      isolate, inspected_frames_.Get(), session_->V8Session(), overlay_.Get());
-  dom_agent_ = dom_agent;
+      isolate, inspected_frames_.Get(), session_->V8Session());
   session_->Append(dom_agent);
 
   InspectorLayerTreeAgent* layer_tree_agent =
@@ -338,7 +330,7 @@
   session_->Append(network_agent);
 
   InspectorCSSAgent* css_agent = InspectorCSSAgent::Create(
-      dom_agent_, inspected_frames_.Get(), network_agent_,
+      dom_agent, inspected_frames_.Get(), network_agent_,
       resource_content_loader_.Get(), resource_container_.Get());
   session_->Append(css_agent);
 
@@ -362,8 +354,8 @@
   tracing_agent_ = tracing_agent;
   session_->Append(tracing_agent);
 
-  session_->Append(new InspectorDOMDebuggerAgent(isolate, dom_agent_,
-                                                 session_->V8Session()));
+  session_->Append(
+      new InspectorDOMDebuggerAgent(isolate, dom_agent, session_->V8Session()));
 
   session_->Append(InspectorInputAgent::Create(inspected_frames_.Get()));
 
@@ -380,6 +372,12 @@
   session_->Append(
       new DeviceOrientationInspectorAgent(inspected_frames_.Get()));
 
+  InspectorOverlayAgent* overlay_agent =
+      new InspectorOverlayAgent(web_local_frame_impl_, inspected_frames_.Get(),
+                                session_->V8Session(), dom_agent);
+  overlay_agent_ = overlay_agent;
+  session_->Append(overlay_agent);
+
   tracing_agent_->SetLayerTreeId(layer_tree_id_);
   network_agent_->SetHostId(host_id);
 
@@ -388,33 +386,25 @@
     // during remote->local transition we cannot access mainFrameImpl() yet, so
     // we have to store the frame which will become the main frame later.
     session_->Append(
-        InspectorRenderingAgent::Create(web_local_frame_impl_, overlay_.Get()));
-    session_->Append(
         InspectorEmulationAgent::Create(web_local_frame_impl_, this));
     // TODO(dgozman): migrate each of the following agents to frame once module
     // is ready.
     Page* page = web_local_frame_impl_->ViewImpl()->GetPage();
     session_->Append(InspectorDatabaseAgent::Create(page));
-    session_->Append(new InspectorAccessibilityAgent(page, dom_agent_));
+    session_->Append(new InspectorAccessibilityAgent(page, dom_agent));
     session_->Append(InspectorDOMStorageAgent::Create(page));
     session_->Append(InspectorCacheStorageAgent::Create());
   }
 
-  if (overlay_)
-    overlay_->Init(session_->V8Session(), dom_agent_);
-
   Platform::Current()->CurrentThread()->AddTaskObserver(this);
 }
 
 void WebDevToolsAgentImpl::DestroySession() {
-  if (overlay_)
-    overlay_->Clear();
-
+  overlay_agent_.Clear();
   tracing_agent_.Clear();
   layer_tree_agent_.Clear();
   network_agent_.Clear();
   page_agent_.Clear();
-  dom_agent_.Clear();
 
   session_->Dispose();
   session_.Clear();
@@ -497,13 +487,13 @@
 }
 
 void WebDevToolsAgentImpl::ShowReloadingBlanket() {
-  if (overlay_)
-    overlay_->ShowReloadingBlanket();
+  if (overlay_agent_)
+    overlay_agent_->ShowReloadingBlanket();
 }
 
 void WebDevToolsAgentImpl::HideReloadingBlanket() {
-  if (overlay_)
-    overlay_->HideReloadingBlanket();
+  if (overlay_agent_)
+    overlay_agent_->HideReloadingBlanket();
 }
 
 void WebDevToolsAgentImpl::SetCPUThrottlingRate(double rate) {
@@ -537,7 +527,7 @@
 void WebDevToolsAgentImpl::InspectElementAt(
     int session_id,
     const WebPoint& point_in_root_frame) {
-  if (!dom_agent_ || !session_ || session_->SessionId() != session_id)
+  if (!overlay_agent_ || !session_ || session_->SessionId() != session_id)
     return;
   HitTestRequest::HitTestRequestType hit_type =
       HitTestRequest::kMove | HitTestRequest::kReadOnly |
@@ -557,7 +547,7 @@
   Node* node = result.InnerNode();
   if (!node && web_local_frame_impl_->GetFrame()->GetDocument())
     node = web_local_frame_impl_->GetFrame()->GetDocument()->documentElement();
-  dom_agent_->Inspect(node);
+  overlay_agent_->Inspect(node);
 }
 
 void WebDevToolsAgentImpl::FailedToRequestDevTools() {
@@ -574,19 +564,8 @@
 }
 
 void WebDevToolsAgentImpl::PageLayoutInvalidated(bool resized) {
-  if (overlay_)
-    overlay_->PageLayoutInvalidated(resized);
-}
-
-void WebDevToolsAgentImpl::ConfigureOverlay(bool suspended,
-                                            const String& message) {
-  if (!overlay_)
-    return;
-  overlay_->SetPausedInDebuggerMessage(message);
-  if (suspended)
-    overlay_->Suspend();
-  else
-    overlay_->Resume();
+  if (overlay_agent_)
+    overlay_agent_->PageLayoutInvalidated(resized);
 }
 
 void WebDevToolsAgentImpl::WaitForCreateWindow(LocalFrame* frame) {
@@ -599,10 +578,10 @@
 
 WebString WebDevToolsAgentImpl::EvaluateInWebInspectorOverlay(
     const WebString& script) {
-  if (!overlay_)
+  if (!overlay_agent_)
     return WebString();
 
-  return overlay_->EvaluateInOverlayForTest(script);
+  return overlay_agent_->EvaluateInOverlayForTest(script);
 }
 
 bool WebDevToolsAgentImpl::CacheDisabled() {
diff --git a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h
index d37a8e413..a42daf4 100644
--- a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h
+++ b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h
@@ -48,7 +48,7 @@
 
 class GraphicsLayer;
 class InspectedFrames;
-class InspectorOverlay;
+class InspectorOverlayAgent;
 class InspectorResourceContainer;
 class InspectorResourceContentLoader;
 class InspectorTraceEvents;
@@ -74,7 +74,7 @@
 
   void WillBeDestroyed();
   WebDevToolsAgentClient* Client() { return client_; }
-  InspectorOverlay* Overlay() const { return overlay_.Get(); }
+  InspectorOverlayAgent* OverlayAgent() const { return overlay_agent_.Get(); }
   void FlushProtocolNotifications();
 
   // Instrumentation from web/ layer.
@@ -105,7 +105,6 @@
  private:
   WebDevToolsAgentImpl(WebLocalFrameImpl*,
                        WebDevToolsAgentClient*,
-                       InspectorOverlay*,
                        bool include_view_agents);
 
   // InspectorTracingAgent::Client implementation.
@@ -119,7 +118,6 @@
 
   // InspectorPageAgent::Client implementation.
   void PageLayoutInvalidated(bool resized) override;
-  void ConfigureOverlay(bool suspended, const String& message) override;
   void WaitForCreateWindow(LocalFrame*) override;
 
   // InspectorSession::Client implementation.
@@ -150,16 +148,15 @@
 
   Member<CoreProbeSink> instrumenting_agents_;
   Member<InspectorResourceContentLoader> resource_content_loader_;
-  Member<InspectorOverlay> overlay_;
   Member<InspectedFrames> inspected_frames_;
   Member<InspectorResourceContainer> resource_container_;
 
-  Member<InspectorDOMAgent> dom_agent_;
   Member<InspectorPageAgent> page_agent_;
   Member<InspectorNetworkAgent> network_agent_;
   Member<InspectorLayerTreeAgent> layer_tree_agent_;
   Member<InspectorTracingAgent> tracing_agent_;
   Member<InspectorTraceEvents> trace_events_agent_;
+  Member<InspectorOverlayAgent> overlay_agent_;
 
   Member<InspectorSession> session_;
   bool include_view_agents_;
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
index fe1b404c..d902bc9 100644
--- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
+++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
@@ -67,7 +67,7 @@
 #include "web/CompositorMutatorImpl.h"
 #include "web/CompositorWorkerProxyClientImpl.h"
 #include "web/ContextMenuAllowedScope.h"
-#include "web/InspectorOverlay.h"
+#include "web/InspectorOverlayAgent.h"
 #include "web/PageOverlay.h"
 #include "web/WebDevToolsAgentImpl.h"
 #include "web/WebInputEventConversion.h"
@@ -250,7 +250,7 @@
   if (!local_root_)
     return;
 
-  if (InspectorOverlay* overlay = GetInspectorOverlay()) {
+  if (InspectorOverlayAgent* overlay = GetInspectorOverlay()) {
     overlay->UpdateAllLifecyclePhases();
     // TODO(chrishtr): integrate paint into the overlay's lifecycle.
     if (overlay->GetPageOverlay() &&
@@ -362,7 +362,7 @@
   if (!GetPage())
     return WebInputEventResult::kNotHandled;
 
-  if (InspectorOverlay* overlay = GetInspectorOverlay()) {
+  if (InspectorOverlayAgent* overlay = GetInspectorOverlay()) {
     if (overlay->HandleInputEvent(input_event))
       return WebInputEventResult::kHandledSuppressed;
   }
@@ -1154,11 +1154,11 @@
   return result;
 }
 
-InspectorOverlay* WebFrameWidgetImpl::GetInspectorOverlay() {
+InspectorOverlayAgent* WebFrameWidgetImpl::GetInspectorOverlay() {
   if (!local_root_)
     return nullptr;
   if (WebDevToolsAgentImpl* devtools = local_root_->DevToolsAgentImpl())
-    return devtools->Overlay();
+    return devtools->OverlayAgent();
   return nullptr;
 }
 
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.h b/third_party/WebKit/Source/web/WebFrameWidgetImpl.h
index ac28f742..3bd30608 100644
--- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.h
+++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.h
@@ -51,7 +51,7 @@
 class CompositorAnimationHost;
 class Frame;
 class Element;
-class InspectorOverlay;
+class InspectorOverlayAgent;
 class LocalFrame;
 class PaintLayerCompositor;
 class UserGestureToken;
@@ -184,7 +184,7 @@
   WebInputEventResult HandleKeyEvent(const WebKeyboardEvent&) override;
   WebInputEventResult HandleCharEvent(const WebKeyboardEvent&) override;
 
-  InspectorOverlay* GetInspectorOverlay();
+  InspectorOverlayAgent* GetInspectorOverlay();
 
   // This method returns the focused frame belonging to this WebWidget, that
   // is, a focused frame with the same local root as the one corresponding
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
index fcc8889..366eb890 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -69,7 +69,6 @@
 #include "core/paint/LayoutObjectDrawingRecorder.h"
 #include "core/paint/PaintLayer.h"
 #include "modules/plugins/PluginOcclusionSupport.h"
-#include "platform/HostWindow.h"
 #include "platform/KeyboardCodes.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/UserGestureIndicator.h"
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp
index 1b96494..52d580f 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -160,7 +160,7 @@
 #include "web/DedicatedWorkerMessagingProxyProviderImpl.h"
 #include "web/DevToolsEmulator.h"
 #include "web/FullscreenController.h"
-#include "web/InspectorOverlay.h"
+#include "web/InspectorOverlayAgent.h"
 #include "web/LinkHighlightImpl.h"
 #include "web/PageOverlay.h"
 #include "web/PrerendererClientImpl.h"
@@ -433,9 +433,9 @@
   return main_frame ? main_frame->DevToolsAgentImpl() : nullptr;
 }
 
-InspectorOverlay* WebViewImpl::GetInspectorOverlay() {
+InspectorOverlayAgent* WebViewImpl::GetInspectorOverlay() {
   if (WebDevToolsAgentImpl* devtools = MainFrameDevToolsAgentImpl())
-    return devtools->Overlay();
+    return devtools->OverlayAgent();
   return nullptr;
 }
 
@@ -2032,7 +2032,7 @@
   PageWidgetDelegate::UpdateAllLifecyclePhases(*page_,
                                                *MainFrameImpl()->GetFrame());
 
-  if (InspectorOverlay* overlay = GetInspectorOverlay()) {
+  if (InspectorOverlayAgent* overlay = GetInspectorOverlay()) {
     overlay->UpdateAllLifecyclePhases();
     // TODO(chrishtr): integrate paint into the overlay's lifecycle.
     if (overlay->GetPageOverlay() &&
@@ -2175,7 +2175,7 @@
   if (dev_tools_emulator_->HandleInputEvent(input_event))
     return WebInputEventResult::kHandledSuppressed;
 
-  if (InspectorOverlay* overlay = GetInspectorOverlay()) {
+  if (InspectorOverlayAgent* overlay = GetInspectorOverlay()) {
     if (overlay->HandleInputEvent(input_event))
       return WebInputEventResult::kHandledSuppressed;
   }
@@ -4138,7 +4138,7 @@
 void WebViewImpl::UpdatePageOverlays() {
   if (page_color_overlay_)
     page_color_overlay_->Update();
-  if (InspectorOverlay* overlay = GetInspectorOverlay()) {
+  if (InspectorOverlayAgent* overlay = GetInspectorOverlay()) {
     PageOverlay* inspector_page_overlay = overlay->GetPageOverlay();
     if (inspector_page_overlay)
       inspector_page_overlay->Update();
diff --git a/third_party/WebKit/Source/web/WebViewImpl.h b/third_party/WebKit/Source/web/WebViewImpl.h
index 4b2a880..b2795a92 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.h
+++ b/third_party/WebKit/Source/web/WebViewImpl.h
@@ -76,7 +76,7 @@
 class DevToolsEmulator;
 class Frame;
 class FullscreenController;
-class InspectorOverlay;
+class InspectorOverlayAgent;
 class LinkHighlightImpl;
 class PageOverlay;
 class PageScaleConstraintsSet;
@@ -500,7 +500,7 @@
   WebInputMethodControllerImpl* GetActiveWebInputMethodController() const;
 
  private:
-  InspectorOverlay* GetInspectorOverlay();
+  InspectorOverlayAgent* GetInspectorOverlay();
 
   void SetPageScaleFactorAndLocation(float, const FloatPoint&);
   void PropagateZoomFactorToLocalFrameRoots(Frame*, float);
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index 321d99f..f1ac2847 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -7483,7 +7483,6 @@
   EXPECT_EQ(image.Size().width, 10);
   EXPECT_EQ(image.Size().height, 10);
   SkBitmap bitmap = image.GetSkBitmap();
-  SkAutoLockPixels locker(bitmap);
   EXPECT_EQ(bitmap.getColor(0, 0), SK_ColorBLUE);
 }
 
@@ -8584,7 +8583,6 @@
   EXPECT_EQ(reference_bitmap_size.Width(), drag_image->Size().Width());
   EXPECT_EQ(reference_bitmap_size.Height(), drag_image->Size().Height());
   const SkBitmap& drag_bitmap = drag_image->Bitmap();
-  SkAutoLockPixels lock_pixel(drag_bitmap);
   EXPECT_EQ(
       0, memcmp(bitmap.getPixels(), drag_bitmap.getPixels(), bitmap.getSize()));
 }
@@ -10626,7 +10624,6 @@
       static_cast<WebMockClipboard*>(Platform::Current()->Clipboard())
           ->ReadRawImage(WebClipboard::Buffer());
 
-  SkAutoLockPixels auto_lock(image.GetSkBitmap());
   EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image.GetSkBitmap().getColor(0, 0));
 };
 
@@ -10654,7 +10651,6 @@
       static_cast<WebMockClipboard*>(Platform::Current()->Clipboard())
           ->ReadRawImage(WebClipboard::Buffer());
 
-  SkAutoLockPixels auto_lock(image.GetSkBitmap());
   EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image.GetSkBitmap().getColor(0, 0));
 };
 
diff --git a/third_party/WebKit/Source/web/tests/WebImageTest.cpp b/third_party/WebKit/Source/web/tests/WebImageTest.cpp
index dc938eab..adb7140 100644
--- a/third_party/WebKit/Source/web/tests/WebImageTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebImageTest.cpp
@@ -50,7 +50,6 @@
 
   WebImage image = WebImage::FromData(WebData(data), WebSize());
   EXPECT_TRUE(image.Size() == WebSize(1, 1));
-  SkAutoLockPixels auto_lock(image.GetSkBitmap());
   EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255),
             image.GetSkBitmap().getColor(0, 0));
 }
@@ -63,10 +62,8 @@
   ASSERT_EQ(2u, images.size());
   EXPECT_TRUE(images[0].Size() == WebSize(2, 2));
   EXPECT_TRUE(images[1].Size() == WebSize(1, 1));
-  SkAutoLockPixels auto_lock1(images[0].GetSkBitmap());
   EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255),
             images[0].GetSkBitmap().getColor(0, 0));
-  SkAutoLockPixels auto_lock2(images[1].GetSkBitmap());
   EXPECT_EQ(SkColorSetARGB(255, 0, 0, 0),
             images[1].GetSkBitmap().getColor(0, 0));
 }
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git.py
index 49eee785..72c72ac 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git.py
@@ -46,27 +46,26 @@
     # 1 or 128, mostly.
     ERROR_FILE_IS_MISSING = 128
 
-    executable_name = 'git'
-
-    def __init__(self, cwd=None, executive=None, filesystem=None):
+    def __init__(self, cwd=None, executive=None, filesystem=None, platform=None):
         self._executive = executive or Executive()
         self._filesystem = filesystem or FileSystem()
+        self._executable_name = self.find_executable_name(self._executive, platform)
 
         self.cwd = cwd or self._filesystem.abspath(self._filesystem.getcwd())
-        if not Git.in_working_directory(self.cwd, executive=self._executive):
+        if not self.in_working_directory(self.cwd):
             module_directory = self._filesystem.abspath(
                 self._filesystem.dirname(self._filesystem.path_to_module(self.__module__)))
             _log.info('The current directory (%s) is not in a git repo, trying directory %s.',
                       cwd, module_directory)
-            if Git.in_working_directory(module_directory, executive=self._executive):
+            if self.in_working_directory(module_directory):
                 self.cwd = module_directory
             _log.error('Failed to find Git repo for %s or %s', cwd, module_directory)
 
-        self._init_executable_name()
         self.checkout_root = self.find_checkout_root(self.cwd)
 
-    def _init_executable_name(self):
-        """Sets the executable name on Windows.
+    @staticmethod
+    def find_executable_name(executive, platform):
+        """Finds the git executable name which may be different on Windows.
 
         The Win port uses the depot_tools package, which contains a number
         of development tools, including Python and git. Instead of using a
@@ -78,19 +77,18 @@
         FIXME: This is a hack and should be resolved in a different way if
         possible.
         """
+        if not platform or not platform.is_win():
+            return 'git'
         try:
-            self._executive.run_command(['git', 'help'])
+            executive.run_command(['git', 'help'])
+            return 'git'
         except OSError:
-            try:
-                self._executive.run_command(['git.bat', 'help'])
-                _log.debug('Engaging git.bat Windows hack.')
-                self.executable_name = 'git.bat'
-            except OSError:
-                _log.debug('Failed to engage git.bat Windows hack.')
+            _log.debug('Using "git.bat" as git executable.')
+            return 'git.bat'
 
     def run(self, command_args, cwd=None, stdin=None, decode_output=True, return_exit_code=False):
         """Invokes git with the given args."""
-        full_command_args = [self.executable_name] + command_args
+        full_command_args = [self._executable_name] + command_args
         cwd = cwd or self.checkout_root
         return self._executive.run_command(
             full_command_args,
@@ -103,18 +101,14 @@
         """Converts repository-relative paths to absolute paths."""
         return self._filesystem.join(self.checkout_root, repository_relative_path)
 
-    @classmethod
-    def in_working_directory(cls, path, executive=None):
+    def in_working_directory(self, path):
         try:
-            executive = executive or Executive()
-            return executive.run_command(
-                [cls.executable_name, 'rev-parse', '--is-inside-work-tree'],
+            self._executive.run_command(
+                [self._executable_name, 'rev-parse', '--is-inside-work-tree'],
                 cwd=path, error_handler=Executive.ignore_error).rstrip() == 'true'
         except OSError:
             # The Windows bots seem to throw a WindowsError when git isn't installed.
-            # TODO(qyearsley): This might be because the git executable name
-            # isn't initialized yet; maybe this would be fixed by using the
-            # _init_executable_name hack above.
+            # TODO(qyearsley): Check if this is still necessary and remove if possible.
             _log.warn('Got OSError when running Git.in_working_directory.')
             return False
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git_mock.py
index 56048f87..11faf9a 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git_mock.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git_mock.py
@@ -11,9 +11,7 @@
     # Arguments are listed below, even if they're unused, in order to match
     # the Git class. pylint: disable=unused-argument
 
-    executable_name = 'mock-git'
-
-    def __init__(self, cwd=None, filesystem=None, executive=None):
+    def __init__(self, cwd=None, filesystem=None, executive=None, platform=None):
         self.checkout_root = '/mock-checkout'
         self.cwd = cwd or self.checkout_root
         self.added_paths = set()
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/host.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/host.py
index 77de72eb..d450892d 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/host.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/host.py
@@ -79,7 +79,7 @@
 
     def git(self, path=None):
         if path:
-            return Git(cwd=path, executive=self.executive, filesystem=self.filesystem)
+            return Git(cwd=path, executive=self.executive, filesystem=self.filesystem, platform=self.platform)
         if not self._git:
-            self._git = Git(filesystem=self.filesystem, executive=self.executive)
+            self._git = Git(filesystem=self.filesystem, executive=self.executive, platform=self.platform)
         return self._git
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/host_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/host_mock.py
index cb994a7..52e82e0 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/host_mock.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/host_mock.py
@@ -69,9 +69,9 @@
 
     def git(self, path=None):
         if path:
-            return MockGit(cwd=path, filesystem=self.filesystem, executive=self.executive)
+            return MockGit(cwd=path, filesystem=self.filesystem, executive=self.executive, platform=self.platform)
         if not self._git:
-            self._git = MockGit(filesystem=self.filesystem, executive=self.executive)
+            self._git = MockGit(filesystem=self.filesystem, executive=self.executive, platform=self.platform)
         # Various pieces of code (wrongly) call filesystem.chdir(checkout_root).
         # Making the checkout_root exist in the mock filesystem makes that chdir not raise.
         self.filesystem.maybe_make_directory(self._git.checkout_root)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl.py
index 5c03c13..a291236 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl.py
@@ -13,6 +13,7 @@
 import re
 
 from webkitpy.common.net.buildbot import Build, filter_latest_builds
+from webkitpy.common.checkout.git import Git
 
 _log = logging.getLogger(__name__)
 
@@ -27,10 +28,11 @@
         self._host = host
         self._auth_refresh_token_json = auth_refresh_token_json
         self._cwd = cwd
+        self._git_executable_name = Git.find_executable_name(host.executive, host.platform)
 
     def run(self, args):
         """Runs git-cl with the given arguments and returns the output."""
-        command = ['git', 'cl'] + args
+        command = [self._git_executable_name, 'cl'] + args
         if self._auth_refresh_token_json and args[0] in _COMMANDS_THAT_TAKE_REFRESH_TOKEN:
             command += ['--auth-refresh-token-json', self._auth_refresh_token_json]
         return self._host.executive.run_command(command, cwd=self._cwd)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_mock.py
index 670b728..2b910bc 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_mock.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_mock.py
@@ -56,6 +56,9 @@
     def communicate(self, *_):
         return (self.stdout.getvalue(), self.stderr.getvalue())
 
+    def kill(self):
+        return
+
 
 class MockExecutive(object):
     PIPE = 'MOCK PIPE'
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
index 6a792fc..3f3aabf 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
@@ -332,13 +332,6 @@
                 _log.error("Build check failed")
                 return exit_code
 
-        # Check that the system dependencies (themes, fonts, ...) are correct.
-        if not self._options.nocheck_sys_deps:
-            self._printer.write_update("Checking system dependencies ...")
-            exit_code = self._port.check_sys_deps(self._needs_servers(test_names))
-            if exit_code:
-                return exit_code
-
         if self._options.clobber_old_results:
             self._clobber_old_results()
         elif self._filesystem.exists(self._results_directory):
@@ -350,6 +343,14 @@
         self._port.host.filesystem.maybe_make_directory(self._results_directory)
 
         self._port.setup_test_run()
+
+        # Check that the system dependencies (themes, fonts, ...) are correct.
+        if not self._options.nocheck_sys_deps:
+            self._printer.write_update("Checking system dependencies ...")
+            exit_code = self._port.check_sys_deps(self._needs_servers(test_names))
+            if exit_code:
+                return exit_code
+
         return exit_codes.OK_EXIT_STATUS
 
     def _run_tests(self, tests_to_run, tests_to_skip, repeat_each, iterations,
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux.py
index 28c22b4..da1121b 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux.py
@@ -65,6 +65,7 @@
         if not self.get_option('disable_breakpad'):
             self._dump_reader = DumpReaderLinux(host, self._build_path())
         self._original_home = None
+        self._xvfb_process = None
 
     def additional_driver_flag(self):
         flags = super(LinuxPort, self).additional_driver_flag()
@@ -104,10 +105,12 @@
 
     def setup_test_run(self):
         super(LinuxPort, self).setup_test_run()
+        self._start_xvfb()
         self._setup_dummy_home_dir()
 
     def clean_up_test_run(self):
         super(LinuxPort, self).clean_up_test_run()
+        self._stop_xvfb()
         self._clean_up_dummy_home_dir()
 
     #
@@ -142,6 +145,45 @@
         self._filesystem.rmtree(dummy_home)
         self.host.environ['HOME'] = self._original_home
 
+    def _start_xvfb(self):
+        display = self._find_display()
+        if not display:
+            _log.warn('Failed to find a free display to start Xvfb.')
+            return
+
+        _log.info('Starting Xvfb with display "%s".', display)
+        self._xvfb_process = self.host.executive.popen(
+            ['Xvfb', display, '-screen', '0', '1280x800x24', '-ac', '-dpi', '96'],
+            stderr=self.host.executive.DEVNULL)
+
+        # By setting DISPLAY here, the individual worker processes will
+        # get the right DISPLAY. Note, if this environment could be passed
+        # when creating workers, then we wouldn't need to modify DISPLAY here.
+        self.host.environ['DISPLAY'] = display
+
+        # The poll() method will return None if the process has not terminated:
+        # https://docs.python.org/2/library/subprocess.html#subprocess.Popen.poll
+        if self._xvfb_process.poll() is not None:
+            _log.warn('Failed to start Xvfb on display "%s."', display)
+
+    def _find_display(self):
+        """Tries to find a free X display, looping if necessary."""
+        # The "xvfb-run" command uses :99 by default.
+        for display_number in range(99, 120):
+            display = ':%d' % display_number
+            exit_code = self.host.executive.run_command(
+                ['xdpyinfo', '-display', display], return_exit_code=True)
+            if exit_code == 1:
+                return display
+        return None
+
+    def _stop_xvfb(self):
+        if not self._xvfb_process:
+            return
+        _log.debug('Killing Xvfb process pid %d.', self._xvfb_process.pid)
+        self._xvfb_process.kill()
+        self._xvfb_process.wait()
+
     def _path_to_driver(self, target=None):
         binary_name = self.driver_name()
         return self._build_path_with_target(target, binary_name)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux_unittest.py
index fe363f7..9b6a25e5 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux_unittest.py
@@ -114,3 +114,33 @@
         port.clean_up_test_run()
         self.assertEqual(port.host.environ['HOME'], '/home/user')
         self.assertFalse(port.host.filesystem.exists(temp_home_dir))
+
+    def test_setup_test_run_starts_xvfb(self):
+        port = self.make_port()
+        port.host.executive = MockExecutive(exit_code=1)
+        port.setup_test_run()
+        self.assertEqual(
+            port.host.executive.calls,
+            [
+                ['xdpyinfo', '-display', ':99'],
+                ['Xvfb', ':99', '-screen', '0', '1280x800x24', '-ac', '-dpi', '96'],
+            ])
+        env = port.setup_environ_for_server()
+        self.assertEqual(env['DISPLAY'], ':99')
+
+    def test_setup_test_runs_finds_free_display(self):
+        port = self.make_port()
+        port.host.executive = MockExecutive(
+            run_command_fn=lambda args: 1 if ':102' in args else 0)
+        port.setup_test_run()
+        self.assertEqual(
+            port.host.executive.calls,
+            [
+                ['xdpyinfo', '-display', ':99'],
+                ['xdpyinfo', '-display', ':100'],
+                ['xdpyinfo', '-display', ':101'],
+                ['xdpyinfo', '-display', ':102'],
+                ['Xvfb', ':102', '-screen', '0', '1280x800x24', '-ac', '-dpi', '96'],
+            ])
+        env = port.setup_environ_for_server()
+        self.assertEqual(env['DISPLAY'], ':102')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
index 404e09e..a76c2a69 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
@@ -162,7 +162,7 @@
             '/mock-checkout/third_party/WebKit/LayoutTests/W3CImportExpectations',
             '## Owners: someone@chromium.org\n'
             '# external/wpt/foo [ Pass ]\n')
-        git = MockGit()
+        git = MockGit(filesystem=host.filesystem, executive=host.executive, platform=host.platform)
         git.changed_files = lambda: ['third_party/WebKit/LayoutTests/external/wpt/foo/x.html']
         host.git = lambda: git
         importer = TestImporter(host)
diff --git a/tools/cygprofile/profile_android_startup.py b/tools/cygprofile/profile_android_startup.py
index 914f7d19..c33b60b3 100755
--- a/tools/cygprofile/profile_android_startup.py
+++ b/tools/cygprofile/profile_android_startup.py
@@ -33,8 +33,8 @@
 from pylib import constants
 
 sys.path.append(os.path.join(sys.path[0], '..', '..', 'tools', 'perf'))
-from chrome_telemetry_build import chromium_config
-sys.path.append(chromium_config.GetTelemetryDir())
+from core import path_util
+sys.path.append(path_util.GetTelemetryDir())
 from telemetry.internal.util import wpr_server
 
 sys.path.append(os.path.join(sys.path[0], '..', '..',
diff --git a/tools/gritsettings/translation_expectations.pyl b/tools/gritsettings/translation_expectations.pyl
index 6b59db83..fb7d23b7 100644
--- a/tools/gritsettings/translation_expectations.pyl
+++ b/tools/gritsettings/translation_expectations.pyl
@@ -77,6 +77,7 @@
     "tools/grit/grit/testdata/chrome/app/generated_resources.grd": "Test data",
     "tools/grit/grit/testdata/substitute.grd": "Test data",
     "tools/grit/grit/testdata/substitute_no_ids.grd": "Test data",
+    "tools/grit/grit/testdata/substitute_tmpl.grd": "Test data",
     "tools/grit/grit/testdata/whitelist_resources.grd": "Test data",
     "tools/grit/grit/testdata/whitelist_strings.grd": "Test data",
     "ui/strings/app_locale_settings.grd": "Not UI strings; localized separately",
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index a17bd3d..8331861 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -35138,6 +35138,35 @@
   </summary>
 </histogram>
 
+<histogram
+    name="Net.JobControllerSet.CountOfJobController.NonPreconnect.PendingRequest"
+    units="job_controllers">
+  <owner>zhongyi@chromium.org</owner>
+  <summary>
+    This counts number of JobControllers that are still alive, not created for
+    preconnect, and still have a HttpStreamFactoryImpl::Request pending.
+  </summary>
+</histogram>
+
+<histogram
+    name="Net.JobControllerSet.CountOfJobController.NonPreconnect.RequestGone"
+    units="job_controllers">
+  <owner>zhongyi@chromium.org</owner>
+  <summary>
+    This counts number of job controllers that are still alive, not created for
+    preconnect but HttpStreamFactoryImpl::Request has completed.
+  </summary>
+</histogram>
+
+<histogram name="Net.JobControllerSet.CountOfJobController.Preconnect"
+    units="job_controllers">
+  <owner>zhongyi@chromium.org</owner>
+  <summary>
+    This counts number of job controllers which are used for preconnect and are
+    still alive.
+  </summary>
+</histogram>
+
 <histogram name="Net.JobControllerSet.CountOfJobControllerAtShutDown"
     units="job_controllers">
   <owner>zhongyi@chromium.org</owner>
@@ -35161,6 +35190,10 @@
 </histogram>
 
 <histogram name="Net.JobControllerSet.CountOfPendingRequest" units="requests">
+  <obsolete>
+    Deprecated 04/2017, replaced by
+    Net.JobController.CountOfJobController.NonPreconnect.PendingRequest.
+  </obsolete>
   <owner>zhongyi@chromium.org</owner>
   <summary>
     This counts number of HttpStreamFactoryImpl::Request which are still alive.
@@ -35169,6 +35202,10 @@
 
 <histogram name="Net.JobControllerSet.CountOfPreconnect"
     units="job_controllers">
+  <obsolete>
+    Deprecated 04/2017, replaced by
+    Net.JobController.CountOfJobController.Preconnect.
+  </obsolete>
   <owner>zhongyi@chromium.org</owner>
   <summary>
     This counts number of job controllers which are used for preconnect and are
@@ -89371,6 +89408,23 @@
 <enum name="DialogName" type="int">
   <int value="0" label="Unknown"/>
   <int value="1" label="Translate"/>
+  <int value="2" label="Bookmark"/>
+  <int value="3" label="Bookmark Editor"/>
+  <int value="4" label="Desktop Media Picker (Screenshare)"/>
+  <int value="5" label="Outdated Upgrade"/>
+  <int value="6" label="One Click Sign In"/>
+  <int value="7" label="Profile Signin Confirmation (Link Chrome Data)"/>
+  <int value="8" label="Hung Renderer"/>
+  <int value="9" label="Session Crashed"/>
+  <int value="10" label="Confirm Bubble (Ask Google for Suggestions)"/>
+  <int value="11" label="Update Recommended"/>
+  <int value="12" label="Crypto Password"/>
+  <int value="13" label="Safe Browsing Download Feedback"/>
+  <int value="14" label="First Run"/>
+  <int value="15" label="Network Share Profile Warning"/>
+  <int value="16" label="Conflicting Module"/>
+  <int value="17" label="Critical Notification (Upgrade Installed)"/>
+  <int value="18" label="IME Warning (Activation)"/>
 </enum>
 
 <enum name="DifferentPrimaryAccounts" type="int">
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py
index b48d440..1c4d4ca 100755
--- a/tools/perf/core/perf_data_generator.py
+++ b/tools/perf/core/perf_data_generator.py
@@ -662,14 +662,6 @@
     'loading.mobile': 14400,
 }
 
-# Certain swarming bots are not sharding correctly with the new device affinity
-# algorithm.  Reverting to legacy algorithm to try and get them to complete.
-# See crbug.com/670284
-LEGACY_DEVICE_AFFIINITY_ALGORITHM = [
-  'Win Zenbook Perf',
-  'Win 10 High-DPI Perf',
-]
-
 # List of benchmarks that are to never be run with reference builds.
 BENCHMARK_REF_BUILD_BLACKLIST = [
   'power.idle_platform',
@@ -773,8 +765,6 @@
         raise Exception('Invalid assumption on number of swarming dimensions')
       # Generate benchmarks
       sharding_map = benchmark_sharding_map
-      if name in LEGACY_DEVICE_AFFIINITY_ALGORITHM:
-        sharding_map = None
       isolated_scripts = generate_telemetry_tests(
           config, benchmark_list, sharding_map, use_whitelist,
           BENCHMARK_REF_BUILD_BLACKLIST)
diff --git a/ui/aura/mus/window_port_mus.cc b/ui/aura/mus/window_port_mus.cc
index 0621b0f..d5cec711 100644
--- a/ui/aura/mus/window_port_mus.cc
+++ b/ui/aura/mus/window_port_mus.cc
@@ -524,7 +524,7 @@
 void WindowPortMus::UpdatePrimarySurfaceInfo() {
   bool embeds_surface = window_mus_type() == WindowMusType::TOP_LEVEL_IN_WM ||
                         window_mus_type() == WindowMusType::EMBED_IN_OWNER;
-  if (!embeds_surface)
+  if (!embeds_surface || !window_tree_client_->enable_surface_synchronization_)
     return;
 
   if (!frame_sink_id_.is_valid() || !local_surface_id_.is_valid())
diff --git a/ui/base/clipboard/clipboard_android.cc b/ui/base/clipboard/clipboard_android.cc
index 1761d6c..b33b78f 100644
--- a/ui/base/clipboard/clipboard_android.cc
+++ b/ui/base/clipboard/clipboard_android.cc
@@ -498,11 +498,8 @@
   gfx::Size size(bitmap.width(), bitmap.height());
 
   std::string packed(reinterpret_cast<const char*>(&size), sizeof(size));
-  {
-    SkAutoLockPixels bitmap_lock(bitmap);
-    packed += std::string(static_cast<const char*>(bitmap.getPixels()),
-                          bitmap.getSize());
-  }
+  packed += std::string(static_cast<const char*>(bitmap.getPixels()),
+                        bitmap.getSize());
   g_map.Get().Set(kBitmapFormat, packed);
 }
 
diff --git a/ui/base/clipboard/clipboard_test_template.h b/ui/base/clipboard/clipboard_test_template.h
index cf033779..0082870b 100644
--- a/ui/base/clipboard/clipboard_test_template.h
+++ b/ui/base/clipboard/clipboard_test_template.h
@@ -394,7 +394,6 @@
                                            CLIPBOARD_TYPE_COPY_PASTE));
   const SkBitmap& image = clipboard->ReadImage(CLIPBOARD_TYPE_COPY_PASTE);
   EXPECT_EQ(size, gfx::Size(image.width(), image.height()));
-  SkAutoLockPixels image_lock(image);
   for (int j = 0; j < image.height(); ++j) {
     const uint32_t* row_address = image.getAddr32(0, j);
     for (int i = 0; i < image.width(); ++i) {
diff --git a/ui/base/clipboard/clipboard_win.cc b/ui/base/clipboard/clipboard_win.cc
index ae892c9..c135e35 100644
--- a/ui/base/clipboard/clipboard_win.cc
+++ b/ui/base/clipboard/clipboard_win.cc
@@ -808,11 +808,8 @@
       ::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, &bits, NULL, 0);
 
   if (bits && source_hbitmap) {
-    {
-      SkAutoLockPixels bitmap_lock(bitmap);
-      // Copy the bitmap out of shared memory and into GDI
-      memcpy(bits, bitmap.getPixels(), bitmap.getSize());
-    }
+    // Copy the bitmap out of shared memory and into GDI
+    memcpy(bits, bitmap.getPixels(), bitmap.getSize());
 
     // Now we have an HBITMAP, we can write it to the clipboard
     WriteBitmapFromHandle(source_hbitmap,
diff --git a/ui/base/dragdrop/os_exchange_data_provider_win.cc b/ui/base/dragdrop/os_exchange_data_provider_win.cc
index 7657d3a..3fa651b 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_win.cc
+++ b/ui/base/dragdrop/os_exchange_data_provider_win.cc
@@ -579,10 +579,7 @@
   if (!hbitmap)
     return;
 
-  {
-    SkAutoLockPixels lock(unpremul_bitmap);
-    memcpy(bits, unpremul_bitmap.getPixels(), height * rowbytes);
-  }
+  memcpy(bits, unpremul_bitmap.getPixels(), height * rowbytes);
 
   base::win::ScopedComPtr<IDragSourceHelper> helper;
   HRESULT rv = CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER,
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc
index dbb489fa..037c236 100644
--- a/ui/base/x/x11_util.cc
+++ b/ui/base/x/x11_util.cc
@@ -319,12 +319,10 @@
   image->yhot = std::min(bitmap->height() - 1, hotspot_point.y());
 
   if (bitmap->width() && bitmap->height()) {
-    bitmap->lockPixels();
     // The |bitmap| contains ARGB image, so just copy it.
     memcpy(image->pixels,
            bitmap->getPixels(),
            bitmap->width() * bitmap->height() * 4);
-    bitmap->unlockPixels();
   }
 
   return image;
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index b0c5983..3e24319 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -253,6 +253,10 @@
   }
 }
 
+bool Compositor::IsForSubframe() {
+  return false;
+}
+
 void Compositor::AddFrameSink(const cc::FrameSinkId& frame_sink_id) {
   if (!context_factory_private_)
     return;
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index fe85a4e2..2e95a3f 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -343,6 +343,8 @@
   void DidReceiveCompositorFrameAck() override;
   void DidCompletePageScaleAnimation() override {}
 
+  bool IsForSubframe() override;
+
   // cc::LayerTreeHostSingleThreadClient implementation.
   void DidSubmitCompositorFrame() override;
   void DidLoseCompositorFrameSink() override {}
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc
index d06bf13..911788fe 100644
--- a/ui/compositor/layer_unittest.cc
+++ b/ui/compositor/layer_unittest.cc
@@ -1183,7 +1183,6 @@
   ReadPixels(&bitmap, gfx::Rect(viewport_size));
   ASSERT_FALSE(bitmap.empty());
 
-  SkAutoLockPixels lock(bitmap);
   for (int x = 0; x < viewport_size.width(); x++) {
     for (int y = 0; y < viewport_size.height(); y++) {
       SkColor actual_color = bitmap.getColor(x, y);
@@ -1221,7 +1220,6 @@
   ReadPixels(&bitmap, gfx::Rect(viewport_size));
   ASSERT_FALSE(bitmap.empty());
 
-  SkAutoLockPixels lock(bitmap);
   for (int x = 0; x < test_size; x++) {
     for (int y = 0; y < test_size; y++) {
       SkColor actual_color = bitmap.getColor(x, y);
@@ -1262,7 +1260,6 @@
   ReadPixels(&bitmap, gfx::Rect(viewport_size));
   ASSERT_FALSE(bitmap.empty());
 
-  SkAutoLockPixels lock(bitmap);
   for (int x = 0; x < test_size; x++) {
     for (int y = 0; y < test_size; y++) {
       SkColor actual_color = bitmap.getColor(x, y);
diff --git a/ui/display/fake_display_snapshot.cc b/ui/display/fake_display_snapshot.cc
index ea2b52e..c7294a5 100644
--- a/ui/display/fake_display_snapshot.cc
+++ b/ui/display/fake_display_snapshot.cc
@@ -60,8 +60,6 @@
       return "dp";
     case DISPLAY_CONNECTION_TYPE_NETWORK:
       return "network";
-    case DISPLAY_CONNECTION_TYPE_VIRTUAL:
-      return "virtual";
   }
   NOTREACHED();
   return "";
diff --git a/ui/display/manager/BUILD.gn b/ui/display/manager/BUILD.gn
index 8021aef..af4d1ee08 100644
--- a/ui/display/manager/BUILD.gn
+++ b/ui/display/manager/BUILD.gn
@@ -15,8 +15,6 @@
     "chromeos/display_configurator.cc",
     "chromeos/display_configurator.h",
     "chromeos/display_layout_manager.h",
-    "chromeos/display_snapshot_virtual.cc",
-    "chromeos/display_snapshot_virtual.h",
     "chromeos/display_util.cc",
     "chromeos/display_util.h",
     "chromeos/query_content_protection_task.cc",
diff --git a/ui/display/manager/chromeos/apply_content_protection_task.cc b/ui/display/manager/chromeos/apply_content_protection_task.cc
index c7a4fcd8..612a563 100644
--- a/ui/display/manager/chromeos/apply_content_protection_task.cc
+++ b/ui/display/manager/chromeos/apply_content_protection_task.cc
@@ -28,7 +28,6 @@
       case DISPLAY_CONNECTION_TYPE_INTERNAL:
       case DISPLAY_CONNECTION_TYPE_VGA:
       case DISPLAY_CONNECTION_TYPE_NETWORK:
-      case DISPLAY_CONNECTION_TYPE_VIRTUAL:
         // No protections for these types. Do nothing.
         break;
       case DISPLAY_CONNECTION_TYPE_NONE:
diff --git a/ui/display/manager/chromeos/display_change_observer.cc b/ui/display/manager/chromeos/display_change_observer.cc
index 0cadbc1..8934783 100644
--- a/ui/display/manager/chromeos/display_change_observer.cc
+++ b/ui/display/manager/chromeos/display_change_observer.cc
@@ -221,17 +221,9 @@
     }
     gfx::Rect display_bounds(state->origin(), mode_info->size());
 
-    std::string name;
-    switch (state->type()) {
-      case DISPLAY_CONNECTION_TYPE_INTERNAL:
-        name = l10n_util::GetStringUTF8(IDS_DISPLAY_NAME_INTERNAL);
-        break;
-      case DISPLAY_CONNECTION_TYPE_VIRTUAL:
-        name = l10n_util::GetStringUTF8(IDS_DISPLAY_NAME_VIRTUAL);
-        break;
-      default:
-        name = state->display_name();
-    }
+    std::string name = (state->type() == DISPLAY_CONNECTION_TYPE_INTERNAL)
+                           ? l10n_util::GetStringUTF8(IDS_DISPLAY_NAME_INTERNAL)
+                           : state->display_name();
 
     if (name.empty())
       name = l10n_util::GetStringUTF8(IDS_DISPLAY_NAME_UNKNOWN);
diff --git a/ui/display/manager/chromeos/display_configurator.cc b/ui/display/manager/chromeos/display_configurator.cc
index bc6f9fd..64201c0 100644
--- a/ui/display/manager/chromeos/display_configurator.cc
+++ b/ui/display/manager/chromeos/display_configurator.cc
@@ -18,7 +18,6 @@
 #include "ui/display/display_switches.h"
 #include "ui/display/manager/chromeos/apply_content_protection_task.h"
 #include "ui/display/manager/chromeos/display_layout_manager.h"
-#include "ui/display/manager/chromeos/display_snapshot_virtual.h"
 #include "ui/display/manager/chromeos/display_util.h"
 #include "ui/display/manager/chromeos/update_display_configuration_task.h"
 #include "ui/display/types/display_mode.h"
@@ -32,9 +31,6 @@
 
 typedef std::vector<const DisplayMode*> DisplayModeList;
 
-// The EDID specification marks the top bit of the manufacturer id as reserved.
-const int16_t kReservedManufacturerID = static_cast<int16_t>(1 << 15);
-
 struct DisplayState {
   DisplaySnapshot* display = nullptr;  // Not owned.
 
@@ -1037,7 +1033,6 @@
       requested_display_state_, pending_power_state_, pending_power_flags_, 0,
       force_configure_, base::Bind(&DisplayConfigurator::OnConfigured,
                                    weak_ptr_factory_.GetWeakPtr())));
-  configuration_task_->SetVirtualDisplaySnapshots(virtual_display_snapshots_);
 
   // Reset the flags before running the task; otherwise it may end up scheduling
   // another configuration.
@@ -1154,44 +1149,6 @@
     observer.OnPowerStateChanged(current_power_state_);
 }
 
-int64_t DisplayConfigurator::AddVirtualDisplay(const gfx::Size& display_size) {
-  if (last_virtual_display_id_ == 0xff) {
-    LOG(WARNING) << "Exceeded virtual display id limit";
-    return kInvalidDisplayId;
-  }
-
-  int64_t display_id = GenerateDisplayID(kReservedManufacturerID, 0x0,
-                                         ++last_virtual_display_id_);
-  virtual_display_snapshots_.push_back(
-      base::MakeUnique<DisplaySnapshotVirtual>(display_id, display_size));
-  ConfigureDisplays();
-
-  return display_id;
-}
-
-bool DisplayConfigurator::RemoveVirtualDisplay(int64_t display_id) {
-  bool display_found = false;
-  for (auto it = virtual_display_snapshots_.begin();
-       it != virtual_display_snapshots_.end(); ++it) {
-    if ((*it)->display_id() == display_id) {
-      virtual_display_snapshots_.erase(it);
-      ConfigureDisplays();
-      display_found = true;
-      break;
-    }
-  }
-
-  if (!display_found)
-    return false;
-
-  int64_t max_display_id = 0;
-  for (const auto& display : virtual_display_snapshots_)
-    max_display_id = std::max(max_display_id, display->display_id());
-  last_virtual_display_id_ = max_display_id & 0xff;
-
-  return true;
-}
-
 bool DisplayConfigurator::IsDisplayOn() const {
   return current_power_state_ != chromeos::DISPLAY_POWER_ALL_OFF;
 }
diff --git a/ui/display/manager/chromeos/display_configurator.h b/ui/display/manager/chromeos/display_configurator.h
index 8519bd11..adf467e0 100644
--- a/ui/display/manager/chromeos/display_configurator.h
+++ b/ui/display/manager/chromeos/display_configurator.h
@@ -19,7 +19,6 @@
 #include "base/observer_list.h"
 #include "base/timer/timer.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
-#include "ui/display/manager/chromeos/display_snapshot_virtual.h"
 #include "ui/display/manager/chromeos/query_content_protection_task.h"
 #include "ui/display/manager/display_manager_export.h"
 #include "ui/display/types/display_constants.h"
@@ -284,10 +283,6 @@
   bool SetColorCalibrationProfile(int64_t display_id,
                                   ColorCalibrationProfile new_profile);
 
-  // Enables/disables virtual display.
-  int64_t AddVirtualDisplay(const gfx::Size& display_size);
-  bool RemoveVirtualDisplay(int64_t display_id);
-
   // Returns true if there is at least one display on.
   bool IsDisplayOn() const;
 
@@ -463,12 +458,6 @@
   // Whether the displays are currently suspended.
   bool displays_suspended_;
 
-  // Virtual display control.
-  std::vector<std::unique_ptr<DisplaySnapshot>> virtual_display_snapshots_;
-
-  // Last used virtual display id.
-  uint8_t last_virtual_display_id_ = 0;
-
   std::unique_ptr<DisplayLayoutManager> layout_manager_;
 
   std::unique_ptr<UpdateDisplayConfigurationTask> configuration_task_;
diff --git a/ui/display/manager/chromeos/display_configurator_unittest.cc b/ui/display/manager/chromeos/display_configurator_unittest.cc
index 4bca2fd..a366630a 100644
--- a/ui/display/manager/chromeos/display_configurator_unittest.cc
+++ b/ui/display/manager/chromeos/display_configurator_unittest.cc
@@ -412,162 +412,6 @@
                          *output, gfx::Size(1440, 900)));
 }
 
-TEST_F(DisplayConfiguratorTest, EnableVirtualDisplay) {
-  InitWithSingleOutput();
-
-  observer_.Reset();
-  const DisplayConfigurator::DisplayStateList& cached =
-      configurator_.cached_displays();
-  ASSERT_EQ(static_cast<size_t>(1u), cached.size());
-  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
-
-  // Add virtual display.
-  int64_t virtual_display_id =
-      configurator_.AddVirtualDisplay(big_mode_.size());
-  EXPECT_EQ(GenerateDisplayID(0x8000, 0x0, 1), virtual_display_id);
-  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
-  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
-            configurator_.display_state());
-
-  // Virtual should not trigger addition of added crtc but does change FB
-  // height.
-  const int kVirtualHeight = small_mode_.size().height() +
-                             DisplayConfigurator::kVerticalGap +
-                             big_mode_.size().height();
-  EXPECT_EQ(
-      JoinActions(
-          kGrab, GetFramebufferAction(
-                     gfx::Size(big_mode_.size().width(), kVirtualHeight),
-                     outputs_[0].get(), nullptr)
-                     .c_str(),
-          GetCrtcAction(*outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
-          kUngrab, nullptr),
-      log_->GetActionsAndClear());
-  EXPECT_EQ(1, observer_.num_changes());
-  ASSERT_EQ(static_cast<size_t>(2u), cached.size());
-  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
-  EXPECT_EQ(big_mode_.size(), cached[1]->current_mode()->size());
-  EXPECT_EQ(virtual_display_id, cached[1]->display_id());
-
-  // Remove virtual display.
-  observer_.Reset();
-  EXPECT_TRUE(configurator_.RemoveVirtualDisplay(virtual_display_id));
-  EXPECT_EQ(
-      JoinActions(
-          kGrab,
-          GetFramebufferAction(small_mode_.size(), outputs_[0].get(), nullptr)
-              .c_str(),
-          GetCrtcAction(*outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
-          kUngrab, nullptr),
-      log_->GetActionsAndClear());
-  EXPECT_EQ(1, observer_.num_changes());
-  ASSERT_EQ(static_cast<size_t>(1u), cached.size());
-  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
-  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state());
-}
-
-TEST_F(DisplayConfiguratorTest, EnableTwoVirtualDisplays) {
-  InitWithSingleOutput();
-
-  observer_.Reset();
-  const DisplayConfigurator::DisplayStateList& cached =
-      configurator_.cached_displays();
-  ASSERT_EQ(static_cast<size_t>(1u), cached.size());
-  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
-
-  // Add 1st virtual display.
-  int64_t virtual_display_id_1 =
-      configurator_.AddVirtualDisplay(big_mode_.size());
-  EXPECT_EQ(GenerateDisplayID(0x8000, 0x0, 1), virtual_display_id_1);
-  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
-  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
-            configurator_.display_state());
-
-  // Virtual should not trigger addition of added crtc but does change FB
-  // height.
-  const int kSingleVirtualHeight = small_mode_.size().height() +
-                                   DisplayConfigurator::kVerticalGap +
-                                   big_mode_.size().height();
-  EXPECT_EQ(
-      JoinActions(
-          kGrab, GetFramebufferAction(
-                     gfx::Size(big_mode_.size().width(), kSingleVirtualHeight),
-                     outputs_[0].get(), nullptr)
-                     .c_str(),
-          GetCrtcAction(*outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
-          kUngrab, nullptr),
-      log_->GetActionsAndClear());
-  EXPECT_EQ(1, observer_.num_changes());
-  ASSERT_EQ(static_cast<size_t>(2), cached.size());
-  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
-  EXPECT_EQ(big_mode_.size(), cached[1]->current_mode()->size());
-  EXPECT_EQ(virtual_display_id_1, cached[1]->display_id());
-
-  // Add 2nd virtual display
-  int64_t virtual_display_id_2 =
-      configurator_.AddVirtualDisplay(big_mode_.size());
-  EXPECT_EQ(GenerateDisplayID(0x8000, 0x0, 2), virtual_display_id_2);
-  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
-  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED,
-            configurator_.display_state());
-
-  const int kDualVirtualHeight =
-      small_mode_.size().height() +
-      (DisplayConfigurator::kVerticalGap + big_mode_.size().height()) * 2;
-  EXPECT_EQ(
-      JoinActions(
-          kGrab, GetFramebufferAction(
-                     gfx::Size(big_mode_.size().width(), kDualVirtualHeight),
-                     outputs_[0].get(), nullptr)
-                     .c_str(),
-          GetCrtcAction(*outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
-          kUngrab, nullptr),
-      log_->GetActionsAndClear());
-  EXPECT_EQ(2, observer_.num_changes());
-  ASSERT_EQ(static_cast<size_t>(3u), cached.size());
-  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
-  EXPECT_EQ(big_mode_.size(), cached[1]->current_mode()->size());
-  EXPECT_EQ(big_mode_.size(), cached[2]->current_mode()->size());
-  EXPECT_EQ(virtual_display_id_1, cached[1]->display_id());
-  EXPECT_EQ(virtual_display_id_2, cached[2]->display_id());
-
-  // Remove 1st virtual display.
-  observer_.Reset();
-  EXPECT_TRUE(configurator_.RemoveVirtualDisplay(virtual_display_id_1));
-  EXPECT_EQ(
-      JoinActions(
-          kGrab, GetFramebufferAction(
-                     gfx::Size(big_mode_.size().width(), kSingleVirtualHeight),
-                     outputs_[0].get(), nullptr)
-                     .c_str(),
-          GetCrtcAction(*outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
-          kUngrab, nullptr),
-      log_->GetActionsAndClear());
-  EXPECT_EQ(1, observer_.num_changes());
-  ASSERT_EQ(static_cast<size_t>(2u), cached.size());
-  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
-  EXPECT_EQ(big_mode_.size(), cached[1]->current_mode()->size());
-  EXPECT_EQ(virtual_display_id_2, cached[1]->display_id());
-  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
-            configurator_.display_state());
-
-  // Remove 2nd virtual display.
-  observer_.Reset();
-  EXPECT_TRUE(configurator_.RemoveVirtualDisplay(virtual_display_id_2));
-  EXPECT_EQ(
-      JoinActions(
-          kGrab,
-          GetFramebufferAction(small_mode_.size(), outputs_[0].get(), nullptr)
-              .c_str(),
-          GetCrtcAction(*outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
-          kUngrab, nullptr),
-      log_->GetActionsAndClear());
-  EXPECT_EQ(1, observer_.num_changes());
-  ASSERT_EQ(static_cast<size_t>(1), cached.size());
-  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
-  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state());
-}
-
 TEST_F(DisplayConfiguratorTest, ConnectSecondOutput) {
   InitWithSingleOutput();
 
diff --git a/ui/display/manager/chromeos/display_snapshot_virtual.cc b/ui/display/manager/chromeos/display_snapshot_virtual.cc
deleted file mode 100644
index b3c32c9..0000000
--- a/ui/display/manager/chromeos/display_snapshot_virtual.cc
+++ /dev/null
@@ -1,53 +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 "ui/display/manager/chromeos/display_snapshot_virtual.h"
-
-#include <inttypes.h>
-
-#include "base/strings/stringprintf.h"
-#include "ui/display/types/display_mode.h"
-
-namespace display {
-
-namespace {
-
-// For a non hi-DPI display (96 dpi) use a pitch of 265µm.
-static const float kVirtualDisplayPitchMM = 0.265;
-
-}  // namespace
-
-DisplaySnapshotVirtual::DisplaySnapshotVirtual(int64_t display_id,
-                                               const gfx::Size& display_size)
-    : DisplaySnapshot(display_id,
-                      gfx::Point(0, 0),
-                      // Calculate physical size assuming 96dpi display.
-                      gfx::Size(display_size.width() * kVirtualDisplayPitchMM,
-                                display_size.height() * kVirtualDisplayPitchMM),
-                      DISPLAY_CONNECTION_TYPE_VIRTUAL,
-                      false,
-                      false,
-                      false,
-                      "Virtual display",
-                      base::FilePath(),
-                      std::vector<std::unique_ptr<const DisplayMode>>(),
-                      std::vector<uint8_t>(),  // Virtual displays have no EDID.
-                      nullptr,
-                      nullptr) {
-  mode_.reset(new DisplayMode(display_size, false, 30));
-  modes_.push_back(mode_->Clone());
-
-  native_mode_ = modes_.front().get();
-}
-
-DisplaySnapshotVirtual::~DisplaySnapshotVirtual() {}
-
-std::string DisplaySnapshotVirtual::ToString() const {
-  return base::StringPrintf(
-      "Virtual id=%" PRId64 " current_mode=%s physical_size=%s", display_id_,
-      current_mode_ ? current_mode_->ToString().c_str() : "nullptr",
-      physical_size_.ToString().c_str());
-}
-
-}  // namespace display
diff --git a/ui/display/manager/chromeos/display_snapshot_virtual.h b/ui/display/manager/chromeos/display_snapshot_virtual.h
deleted file mode 100644
index 2a542fd..0000000
--- a/ui/display/manager/chromeos/display_snapshot_virtual.h
+++ /dev/null
@@ -1,38 +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 UI_DISPLAY_MANAGER_CHROMEOS_DISPLAY_SNAPSHOT_VIRTUAL_H_
-#define UI_DISPLAY_MANAGER_CHROMEOS_DISPLAY_SNAPSHOT_VIRTUAL_H_
-
-#include <stdint.h>
-
-#include <memory>
-
-#include "base/macros.h"
-#include "ui/display/manager/display_manager_export.h"
-#include "ui/display/types/display_mode.h"
-#include "ui/display/types/display_snapshot.h"
-
-namespace display {
-
-// This class represents a virtual display to be enabled on demand. The display
-// is constructed for the desired pixel resolution.
-class DISPLAY_MANAGER_EXPORT DisplaySnapshotVirtual : public DisplaySnapshot {
- public:
-  // |display_id| is the numerical identifier for the virtual display,
-  // |display_size| is the pixel dimensions for the display.
-  DisplaySnapshotVirtual(int64_t display_id, const gfx::Size& display_size);
-  ~DisplaySnapshotVirtual() override;
-
-  // DisplaySnapshot overrides.
-  std::string ToString() const override;
-
- private:
-  std::unique_ptr<DisplayMode> mode_;
-  DISALLOW_COPY_AND_ASSIGN(DisplaySnapshotVirtual);
-};
-
-}  // namespace display
-
-#endif  // UI_DISPLAY_MANAGER_CHROMEOS_DISPLAY_SNAPSHOT_VIRTUAL_H_
diff --git a/ui/display/manager/chromeos/display_util.cc b/ui/display/manager/chromeos/display_util.cc
index 645cd8e..c9f78e7 100644
--- a/ui/display/manager/chromeos/display_util.cc
+++ b/ui/display/manager/chromeos/display_util.cc
@@ -57,7 +57,6 @@
   for (size_t i = 0; i < displays.size(); ++i) {
     bool internal = displays[i]->type() == DISPLAY_CONNECTION_TYPE_INTERNAL;
     bool on =
-        displays[i]->type() == DISPLAY_CONNECTION_TYPE_VIRTUAL ||
         state == chromeos::DISPLAY_POWER_ALL_ON ||
         (state == chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON &&
          !internal) ||
@@ -71,8 +70,7 @@
 }
 
 bool IsPhysicalDisplayType(DisplayConnectionType type) {
-  return !(type &
-           (DISPLAY_CONNECTION_TYPE_NETWORK | DISPLAY_CONNECTION_TYPE_VIRTUAL));
+  return !(type & DISPLAY_CONNECTION_TYPE_NETWORK);
 }
 
 }  // namespace display
diff --git a/ui/display/manager/chromeos/display_util.h b/ui/display/manager/chromeos/display_util.h
index 1e3043da..3da69e1 100644
--- a/ui/display/manager/chromeos/display_util.h
+++ b/ui/display/manager/chromeos/display_util.h
@@ -31,8 +31,8 @@
                 std::vector<bool>* display_power);
 
 // Returns whether the DisplayConnectionType |type| is a physically connected
-// display. Currently DISPLAY_CONNECTION_TYPE_VIRTUAL and
-// DISPLAY_CONNECTION_TYPE_NETWORK return false. All other types return true.
+// display. Currently only DISPLAY_CONNECTION_TYPE_NETWORK return false.
+// All other types return true.
 bool IsPhysicalDisplayType(DisplayConnectionType type);
 
 }  // namespace display
diff --git a/ui/display/manager/chromeos/query_content_protection_task.cc b/ui/display/manager/chromeos/query_content_protection_task.cc
index 812f835..d454970 100644
--- a/ui/display/manager/chromeos/query_content_protection_task.cc
+++ b/ui/display/manager/chromeos/query_content_protection_task.cc
@@ -45,7 +45,6 @@
       case DISPLAY_CONNECTION_TYPE_INTERNAL:
       case DISPLAY_CONNECTION_TYPE_VGA:
       case DISPLAY_CONNECTION_TYPE_NETWORK:
-      case DISPLAY_CONNECTION_TYPE_VIRTUAL:
         // No protections for these types. Do nothing.
         break;
       case DISPLAY_CONNECTION_TYPE_NONE:
diff --git a/ui/display/manager/chromeos/update_display_configuration_task.cc b/ui/display/manager/chromeos/update_display_configuration_task.cc
index 7ba78c2..506bcd7 100644
--- a/ui/display/manager/chromeos/update_display_configuration_task.cc
+++ b/ui/display/manager/chromeos/update_display_configuration_task.cc
@@ -4,8 +4,6 @@
 
 #include "ui/display/manager/chromeos/update_display_configuration_task.h"
 
-#include <algorithm>
-
 #include "ui/display/manager/chromeos/configure_displays_task.h"
 #include "ui/display/manager/chromeos/display_layout_manager.h"
 #include "ui/display/manager/chromeos/display_util.h"
@@ -46,23 +44,10 @@
                  weak_ptr_factory_.GetWeakPtr()));
 }
 
-void UpdateDisplayConfigurationTask::SetVirtualDisplaySnapshots(
-    const std::vector<std::unique_ptr<DisplaySnapshot>>& snapshots) {
-  virtual_display_snapshots_.resize(snapshots.size());
-  std::transform(
-      snapshots.cbegin(), snapshots.cend(), virtual_display_snapshots_.begin(),
-      [](const std::unique_ptr<DisplaySnapshot>& item) { return item.get(); });
-}
-
 void UpdateDisplayConfigurationTask::OnDisplaysUpdated(
     const std::vector<DisplaySnapshot*>& displays) {
   cached_displays_ = displays;
 
-  // Add virtual displays after retrieving the physical displays from the NDD.
-  cached_displays_.insert(cached_displays_.end(),
-                          virtual_display_snapshots_.begin(),
-                          virtual_display_snapshots_.end());
-
   if (cached_displays_.size() > 1 && background_color_argb_)
     delegate_->SetBackgroundColor(background_color_argb_);
 
diff --git a/ui/display/manager/chromeos/update_display_configuration_task.h b/ui/display/manager/chromeos/update_display_configuration_task.h
index 270dc8f..75fa1c0 100644
--- a/ui/display/manager/chromeos/update_display_configuration_task.h
+++ b/ui/display/manager/chromeos/update_display_configuration_task.h
@@ -40,11 +40,6 @@
                                  const ResponseCallback& callback);
   ~UpdateDisplayConfigurationTask();
 
-  // The pointers to the DisplaySnapshots in this vector are owned by
-  // DisplayConfigurator.
-  void SetVirtualDisplaySnapshots(
-      const std::vector<std::unique_ptr<DisplaySnapshot>>& snapshots);
-
   void Run();
 
  private:
@@ -102,9 +97,6 @@
   // List of updated displays.
   std::vector<DisplaySnapshot*> cached_displays_;
 
-  // Vector of unowned VirtualDisplaySnapshots to be added when doing the task.
-  std::vector<DisplaySnapshot*> virtual_display_snapshots_;
-
   gfx::Size framebuffer_size_;
 
   std::unique_ptr<ConfigureDisplaysTask> configure_task_;
diff --git a/ui/display/mojo/display_constants.mojom b/ui/display/mojo/display_constants.mojom
index eefc4f6..a10d8d3 100644
--- a/ui/display/mojo/display_constants.mojom
+++ b/ui/display/mojo/display_constants.mojom
@@ -14,7 +14,6 @@
   DISPLAY_CONNECTION_TYPE_DVI = 16,
   DISPLAY_CONNECTION_TYPE_DISPLAYPORT = 32,
   DISPLAY_CONNECTION_TYPE_NETWORK = 64,
-  DISPLAY_CONNECTION_TYPE_VIRTUAL = 128,
 };
 
 // Corresponding to display::HDCPState.
diff --git a/ui/display/mojo/display_constants_struct_traits.cc b/ui/display/mojo/display_constants_struct_traits.cc
index 80eaedd..c5cc013 100644
--- a/ui/display/mojo/display_constants_struct_traits.cc
+++ b/ui/display/mojo/display_constants_struct_traits.cc
@@ -33,9 +33,6 @@
     case display::DisplayConnectionType::DISPLAY_CONNECTION_TYPE_NETWORK:
       return display::mojom::DisplayConnectionType::
           DISPLAY_CONNECTION_TYPE_NETWORK;
-    case display::DisplayConnectionType::DISPLAY_CONNECTION_TYPE_VIRTUAL:
-      return display::mojom::DisplayConnectionType::
-          DISPLAY_CONNECTION_TYPE_VIRTUAL;
   }
   NOTREACHED();
   return display::mojom::DisplayConnectionType::DISPLAY_CONNECTION_TYPE_NONE;
@@ -73,9 +70,6 @@
     case display::mojom::DisplayConnectionType::DISPLAY_CONNECTION_TYPE_NETWORK:
       *out = display::DisplayConnectionType::DISPLAY_CONNECTION_TYPE_NETWORK;
       return true;
-    case display::mojom::DisplayConnectionType::DISPLAY_CONNECTION_TYPE_VIRTUAL:
-      *out = display::DisplayConnectionType::DISPLAY_CONNECTION_TYPE_VIRTUAL;
-      return true;
   }
   return false;
 }
diff --git a/ui/display/types/display_constants.h b/ui/display/types/display_constants.h
index c5f6850..ff524dd3 100644
--- a/ui/display/types/display_constants.h
+++ b/ui/display/types/display_constants.h
@@ -34,10 +34,9 @@
   DISPLAY_CONNECTION_TYPE_DVI = 1 << 4,
   DISPLAY_CONNECTION_TYPE_DISPLAYPORT = 1 << 5,
   DISPLAY_CONNECTION_TYPE_NETWORK = 1 << 6,
-  DISPLAY_CONNECTION_TYPE_VIRTUAL = 1 << 7,
 
   // Update this when adding a new type.
-  DISPLAY_CONNECTION_TYPE_LAST = DISPLAY_CONNECTION_TYPE_VIRTUAL
+  DISPLAY_CONNECTION_TYPE_LAST = DISPLAY_CONNECTION_TYPE_NETWORK
 };
 
 // Content protection methods applied on video output.
diff --git a/ui/display/types/display_mode.cc b/ui/display/types/display_mode.cc
index 6d43caa..62eb49c8 100644
--- a/ui/display/types/display_mode.cc
+++ b/ui/display/types/display_mode.cc
@@ -12,9 +12,7 @@
 DisplayMode::DisplayMode(const gfx::Size& size,
                          bool interlaced,
                          float refresh_rate)
-    : size_(size),
-      is_interlaced_(interlaced),
-      refresh_rate_(refresh_rate) {}
+    : size_(size), refresh_rate_(refresh_rate), is_interlaced_(interlaced) {}
 
 DisplayMode::~DisplayMode() {}
 
diff --git a/ui/display/types/display_mode.h b/ui/display/types/display_mode.h
index 0b972d5..e729ae4 100644
--- a/ui/display/types/display_mode.h
+++ b/ui/display/types/display_mode.h
@@ -31,8 +31,8 @@
 
  private:
   gfx::Size size_;
-  bool is_interlaced_;
   float refresh_rate_;
+  bool is_interlaced_;
 
   DISALLOW_COPY_AND_ASSIGN(DisplayMode);
 };
diff --git a/ui/gfx/android/java_bitmap.cc b/ui/gfx/android/java_bitmap.cc
index 82f1bca..df98913 100644
--- a/ui/gfx/android/java_bitmap.cc
+++ b/ui/gfx/android/java_bitmap.cc
@@ -74,7 +74,6 @@
          (color_type == kN32_SkColorType));
   ScopedJavaLocalRef<jobject> jbitmap = CreateJavaBitmap(
       skbitmap->width(), skbitmap->height(), color_type);
-  SkAutoLockPixels src_lock(*skbitmap);
   JavaBitmap dst_lock(jbitmap);
   void* src_pixels = skbitmap->getPixels();
   void* dst_pixels = dst_lock.pixels();
diff --git a/ui/gfx/blit_unittest.cc b/ui/gfx/blit_unittest.cc
index 8fc45607..98a80a3 100644
--- a/ui/gfx/blit_unittest.cc
+++ b/ui/gfx/blit_unittest.cc
@@ -46,7 +46,6 @@
 template <int w, int h>
 void VerifyCanvasValues(SkCanvas* canvas, uint8_t values[h][w]) {
   SkBitmap bitmap = skia::ReadPixels(canvas);
-  SkAutoLockPixels lock(bitmap);
   ASSERT_EQ(w, bitmap.width());
   ASSERT_EQ(h, bitmap.height());
 
diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc
index d9f66426..31ef57f 100644
--- a/ui/gfx/canvas.cc
+++ b/ui/gfx/canvas.cc
@@ -514,15 +514,7 @@
 
 SkBitmap Canvas::GetBitmap() const {
   DCHECK(bitmap_);
-  SkBitmap bitmap = bitmap_.value();
-  // When the bitmap is copied, it shares the underlying pixelref, but doesn't
-  // initialize pixels unless they are locked. Hence, ensure that the returned
-  // bitmap keeps the pixelref alive by locking it. Note that the dtor of
-  // SkBitmap will unlock the pixelrefs, so this won't leak. Also note that
-  // moving SkBitmap retains the same lock as the source, so the caller
-  // will receive a locked-pixels bitmap.
-  bitmap.lockPixels();
-  return bitmap;
+  return bitmap_.value();
 }
 
 bool Canvas::IntersectsClipRect(const SkRect& rect) {
diff --git a/ui/gfx/codec/png_codec.cc b/ui/gfx/codec/png_codec.cc
index 7f0a569..69a00c1 100644
--- a/ui/gfx/codec/png_codec.cc
+++ b/ui/gfx/codec/png_codec.cc
@@ -731,7 +731,6 @@
   int bpp = input.bytesPerPixel();
   DCHECK(bpp == 1 || bpp == 4);  // We support kA8_Config and kARGB_8888_Config.
 
-  SkAutoLockPixels lock_input(input);
   unsigned char* inputAddr = bpp == 1 ?
       reinterpret_cast<unsigned char*>(input.getAddr8(0, 0)) :
       reinterpret_cast<unsigned char*>(input.getAddr32(0, 0));    // bpp = 4
diff --git a/ui/gfx/codec/png_codec.h b/ui/gfx/codec/png_codec.h
index bcc30e75..0ae9a81d 100644
--- a/ui/gfx/codec/png_codec.h
+++ b/ui/gfx/codec/png_codec.h
@@ -83,8 +83,7 @@
   // Call PNGCodec::Encode on the supplied SkBitmap |input|, which is assumed
   // to be kARGB_8888_Config, 32 bits per pixel. The params
   // |discard_transparency| and |output| are passed directly to Encode; refer to
-  // Encode for more information. During the call, an SkAutoLockPixels lock
-  // is held on |input|.
+  // Encode for more information.
   static bool EncodeBGRASkBitmap(const SkBitmap& input,
                                  bool discard_transparency,
                                  std::vector<unsigned char>* output);
@@ -99,8 +98,7 @@
   // Call PNGCodec::Encode on the supplied SkBitmap |input|, which is assumed
   // to be kA8_Config, 8 bits per pixel. The bitmap is encoded as a grayscale
   // PNG with alpha used for color intensity. The |output| param is passed
-  // directly to Encode; refer to Encode for more information. During the call,
-  // an SkAutoLockPixels lock is held on |input|.
+  // directly to Encode; refer to Encode for more information.
   static bool EncodeA8SkBitmap(const SkBitmap& input,
                                std::vector<unsigned char>* output);
 
diff --git a/ui/gfx/color_analysis.cc b/ui/gfx/color_analysis.cc
index d3e8998..6a2e878 100644
--- a/ui/gfx/color_analysis.cc
+++ b/ui/gfx/color_analysis.cc
@@ -140,7 +140,6 @@
 // Un-premultiplies each pixel in |bitmap| into an output |buffer|. Requires
 // approximately 10 microseconds for a 16x16 icon on an Intel Core i5.
 void UnPreMultiply(const SkBitmap& bitmap, uint32_t* buffer, int buffer_size) {
-  SkAutoLockPixels auto_lock(bitmap);
   uint32_t* in = static_cast<uint32_t*>(bitmap.getPixels());
   uint32_t* out = buffer;
   int pixel_count = std::min(bitmap.width() * bitmap.height(), buffer_size);
@@ -364,7 +363,6 @@
   DCHECK(!bitmap.empty());
   DCHECK(!bitmap.isNull());
 
-  SkAutoLockPixels auto_lock(bitmap);
   const uint32_t* pixels = static_cast<uint32_t*>(bitmap.getPixels());
   const int pixel_count = bitmap.width() * bitmap.height();
 
@@ -778,7 +776,6 @@
 
 gfx::Matrix3F ComputeColorCovariance(const SkBitmap& bitmap) {
   // First need basic stats to normalize each channel separately.
-  SkAutoLockPixels bitmap_lock(bitmap);
   gfx::Matrix3F covariance = gfx::Matrix3F::Zeros();
   if (!bitmap.getPixels())
     return covariance;
@@ -857,9 +854,6 @@
                          bool fit_to_range,
                          SkBitmap* target_bitmap) {
   DCHECK(target_bitmap);
-  SkAutoLockPixels source_lock(source_bitmap);
-  SkAutoLockPixels target_lock(*target_bitmap);
-
   DCHECK(source_bitmap.getPixels());
   DCHECK(target_bitmap->getPixels());
   DCHECK_EQ(kN32_SkColorType, source_bitmap.colorType());
diff --git a/ui/gfx/color_analysis_unittest.cc b/ui/gfx/color_analysis_unittest.cc
index 32444db..93fc2db6 100644
--- a/ui/gfx/color_analysis_unittest.cc
+++ b/ui/gfx/color_analysis_unittest.cc
@@ -99,7 +99,6 @@
   SkBitmap bitmap;
   bitmap.allocN32Pixels(colors.size(), 1);
 
-  SkAutoLockPixels lock(bitmap);
   for (size_t i = 0; i < colors.size(); ++i) {
     bitmap.eraseArea(SkIRect::MakeXYWH(i, 0, 1, 1), colors[i]);
   }
@@ -149,7 +148,6 @@
 void Calculate8bitBitmapMinMax(const SkBitmap& bitmap,
                                uint8_t* min_gl,
                                uint8_t* max_gl) {
-  SkAutoLockPixels bitmap_lock(bitmap);
   DCHECK(bitmap.getPixels());
   DCHECK_EQ(bitmap.colorType(), kAlpha_8_SkColorType);
   DCHECK(min_gl);
diff --git a/ui/gfx/color_utils.cc b/ui/gfx/color_utils.cc
index 95dea09..257990d9 100644
--- a/ui/gfx/color_utils.cc
+++ b/ui/gfx/color_utils.cc
@@ -236,8 +236,6 @@
 void BuildLumaHistogram(const SkBitmap& bitmap, int histogram[256]) {
   DCHECK_EQ(kN32_SkColorType, bitmap.colorType());
 
-  SkAutoLockPixels bitmap_lock(bitmap);
-
   int pixel_width = bitmap.width();
   int pixel_height = bitmap.height();
   for (int y = 0; y < pixel_height; ++y) {
diff --git a/ui/gfx/icon_util.cc b/ui/gfx/icon_util.cc
index f5b9b179..eb0bcdb2 100644
--- a/ui/gfx/icon_util.cc
+++ b/ui/gfx/icon_util.cc
@@ -119,7 +119,6 @@
 
     // Only 32 bit ARGB bitmaps are supported. We also make sure the bitmap has
     // been properly initialized.
-    SkAutoLockPixels bitmap_lock(bitmap);
     if ((bitmap.colorType() != kN32_SkColorType) ||
         (bitmap.getPixels() == NULL)) {
       return false;
@@ -167,7 +166,6 @@
     const SkBitmap& bitmap) {
   // Only 32 bit ARGB bitmaps are supported. We also try to perform as many
   // validations as we can on the bitmap.
-  SkAutoLockPixels bitmap_lock(bitmap);
   if ((bitmap.colorType() != kN32_SkColorType) ||
       (bitmap.width() <= 0) || (bitmap.height() <= 0) ||
       (bitmap.getPixels() == NULL))
@@ -387,7 +385,6 @@
   SkBitmap bitmap;
   bitmap.allocN32Pixels(s.width(), s.height());
   bitmap.eraseARGB(0, 0, 0, 0);
-  SkAutoLockPixels bitmap_lock(bitmap);
 
   // Now we should create a DIB so that we can use ::DrawIconEx in order to
   // obtain the icon's image.
@@ -640,7 +637,6 @@
 void IconUtil::CopySkBitmapBitsIntoIconBuffer(const SkBitmap& bitmap,
                                               unsigned char* buffer,
                                               size_t buffer_size) {
-  SkAutoLockPixels bitmap_lock(bitmap);
   unsigned char* bitmap_ptr = static_cast<unsigned char*>(bitmap.getPixels());
   size_t bitmap_size = bitmap.height() * bitmap.width() * 4;
   DCHECK_EQ(buffer_size, bitmap_size);
diff --git a/ui/gfx/image/image_unittest.cc b/ui/gfx/image/image_unittest.cc
index 641ccfa8..317e598 100644
--- a/ui/gfx/image/image_unittest.cc
+++ b/ui/gfx/image/image_unittest.cc
@@ -506,7 +506,6 @@
   gfx::Image image(gt::CreatePlatformImage());
 
   const SkBitmap* bitmap = image.ToSkBitmap();
-  SkAutoLockPixels auto_lock(*bitmap);
   gt::CheckColors(bitmap->getColor(10, 10), SK_ColorGREEN);
 }
 
@@ -544,7 +543,6 @@
   // Force a conversion back to SkBitmap and check that the upper half is red.
   gfx::Image from_platform(gt::CopyPlatformType(from_skbitmap));
   const SkBitmap* bitmap2 = from_platform.ToSkBitmap();
-  SkAutoLockPixels auto_lock(*bitmap2);
   {
     SCOPED_TRACE("Checking color after conversion back to SkBitmap");
     gt::CheckColors(bitmap2->getColor(10, 10), SK_ColorRED);
@@ -585,7 +583,6 @@
   // Force a conversion back to SkBitmap and check that the upper half is red.
   gfx::Image from_platform(gt::CopyPlatformType(from_skbitmap));
   const SkBitmap* bitmap2 = from_platform.ToSkBitmap();
-  SkAutoLockPixels auto_lock(*bitmap2);
   {
     SCOPED_TRACE("Checking color after conversion back to SkBitmap");
     gt::CheckColors(bitmap2->getColor(10, 10), SK_ColorRED);
diff --git a/ui/gfx/image/image_unittest_util.cc b/ui/gfx/image/image_unittest_util.cc
index f589f46..32a8ed08 100644
--- a/ui/gfx/image/image_unittest_util.cc
+++ b/ui/gfx/image/image_unittest_util.cc
@@ -137,8 +137,6 @@
     return false;
   }
 
-  SkAutoLockPixels lock1(bmp1);
-  SkAutoLockPixels lock2(bmp2);
   if (!bmp1.getPixels() || !bmp2.getPixels())
     return false;
 
@@ -174,7 +172,6 @@
   EXPECT_FALSE(bitmap.isNull());
   EXPECT_LE(16, bitmap.width());
   EXPECT_LE(16, bitmap.height());
-  SkAutoLockPixels auto_lock(bitmap);
   CheckColors(bitmap.getColor(10, 10), SK_ColorRED);
 }
 
@@ -271,9 +268,7 @@
 // Defined in image_unittest_util_mac.mm.
 #else
 SkColor GetPlatformImageColor(PlatformImage image, int x, int y) {
-  SkBitmap bitmap = *image.bitmap();
-  SkAutoLockPixels auto_lock(bitmap);
-  return bitmap.getColor(x, y);
+  return image.bitmap()->getColor(x, y);
 }
 #endif
 
diff --git a/ui/gfx/image/image_util.cc b/ui/gfx/image/image_util.cc
index 3fca705a..16387149 100644
--- a/ui/gfx/image/image_util.cc
+++ b/ui/gfx/image/image_util.cc
@@ -62,8 +62,6 @@
     return false;
 
   const SkBitmap& bitmap = image_skia_rep.sk_bitmap();
-  SkAutoLockPixels bitmap_lock(bitmap);
-
   if (!bitmap.readyToDraw())
     return false;
 
@@ -85,7 +83,6 @@
   if (bitmap.drawsNothing() || bitmap.isOpaque())
     return;
 
-  SkAutoLockPixels lock(bitmap);
   int x = 0;
   for (; x < bitmap.width(); ++x) {
     if (ColumnHasVisiblePixels(bitmap, x)) {
diff --git a/ui/gfx/ipc/skia/OWNERS b/ui/gfx/ipc/skia/OWNERS
new file mode 100644
index 0000000..146c3c3c
--- /dev/null
+++ b/ui/gfx/ipc/skia/OWNERS
@@ -0,0 +1,2 @@
+per-file *_param_traits*.*=set noparent
+per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/ui/gfx/ipc/skia/gfx_skia_param_traits.cc b/ui/gfx/ipc/skia/gfx_skia_param_traits.cc
index 5b09529..4a36137 100644
--- a/ui/gfx/ipc/skia/gfx_skia_param_traits.cc
+++ b/ui/gfx/ipc/skia/gfx_skia_param_traits.cc
@@ -64,7 +64,6 @@
   m->WriteData(reinterpret_cast<const char*>(&bmp_data),
                static_cast<int>(fixed_size));
   size_t pixel_size = p.getSize();
-  SkAutoLockPixels p_lock(p);
   m->WriteData(reinterpret_cast<const char*>(p.getPixels()),
                static_cast<int>(pixel_size));
 }
diff --git a/ui/gfx/skbitmap_operations.cc b/ui/gfx/skbitmap_operations.cc
index ff6b8bd..25bd1816 100644
--- a/ui/gfx/skbitmap_operations.cc
+++ b/ui/gfx/skbitmap_operations.cc
@@ -24,8 +24,6 @@
 SkBitmap SkBitmapOperations::CreateInvertedBitmap(const SkBitmap& image) {
   DCHECK(image.colorType() == kN32_SkColorType);
 
-  SkAutoLockPixels lock_image(image);
-
   SkBitmap inverted;
   inverted.allocN32Pixels(image.width(), image.height());
 
@@ -61,9 +59,6 @@
   else if (alpha > alpha_max)
     return second;
 
-  SkAutoLockPixels lock_first(first);
-  SkAutoLockPixels lock_second(second);
-
   SkBitmap blended;
   blended.allocN32Pixels(first.width(), first.height());
 
@@ -106,10 +101,6 @@
   SkBitmap masked;
   masked.allocN32Pixels(rgb.width(), rgb.height());
 
-  SkAutoLockPixels lock_rgb(rgb);
-  SkAutoLockPixels lock_alpha(alpha);
-  SkAutoLockPixels lock_masked(masked);
-
   for (int y = 0; y < masked.height(); ++y) {
     uint32_t* rgb_row = rgb.getAddr32(0, y);
     uint32_t* alpha_row = alpha.getAddr32(0, y);
@@ -143,10 +134,6 @@
   double bg_g = SkColorGetG(color) * (bg_a / 255.0);
   double bg_b = SkColorGetB(color) * (bg_a / 255.0);
 
-  SkAutoLockPixels lock_mask(mask);
-  SkAutoLockPixels lock_image(image);
-  SkAutoLockPixels lock_background(background);
-
   for (int y = 0; y < mask.height(); ++y) {
     uint32_t* dst_row = background.getAddr32(0, y);
     uint32_t* image_row = image.getAddr32(0, y % image.height());
@@ -518,9 +505,6 @@
   SkBitmap shifted;
   shifted.allocN32Pixels(bitmap.width(), bitmap.height());
 
-  SkAutoLockPixels lock_bitmap(bitmap);
-  SkAutoLockPixels lock_shifted(shifted);
-
   // Loop through the pixels of the original bitmap.
   for (int y = 0; y < bitmap.height(); ++y) {
     SkPMColor* pixels = bitmap.getAddr32(0, y);
@@ -541,9 +525,6 @@
   SkBitmap cropped;
   cropped.allocN32Pixels(dst_w, dst_h);
 
-  SkAutoLockPixels lock_source(source);
-  SkAutoLockPixels lock_cropped(cropped);
-
   // Loop through the pixels of the original bitmap.
   for (int y = 0; y < dst_h; ++y) {
     int y_pix = (src_y + y) % source.height();
@@ -589,8 +570,6 @@
   SkBitmap result;
   result.allocN32Pixels((bitmap.width() + 1) / 2, (bitmap.height() + 1) / 2);
 
-  SkAutoLockPixels lock(bitmap);
-
   const int resultLastX = result.width() - 1;
   const int srcLastX = bitmap.width() - 1;
 
@@ -657,16 +636,12 @@
   SkBitmap opaque_bitmap;
   opaque_bitmap.allocPixels(opaque_info);
 
-  {
-    SkAutoLockPixels bitmap_lock(bitmap);
-    SkAutoLockPixels opaque_bitmap_lock(opaque_bitmap);
-    for (int y = 0; y < opaque_bitmap.height(); y++) {
-      for (int x = 0; x < opaque_bitmap.width(); x++) {
-        uint32_t src_pixel = *bitmap.getAddr32(x, y);
-        uint32_t* dst_pixel = opaque_bitmap.getAddr32(x, y);
-        SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(src_pixel);
-        *dst_pixel = unmultiplied;
-      }
+  for (int y = 0; y < opaque_bitmap.height(); y++) {
+    for (int x = 0; x < opaque_bitmap.width(); x++) {
+      uint32_t src_pixel = *bitmap.getAddr32(x, y);
+      uint32_t* dst_pixel = opaque_bitmap.getAddr32(x, y);
+      SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(src_pixel);
+      *dst_pixel = unmultiplied;
     }
   }
 
@@ -680,9 +655,6 @@
   SkBitmap transposed;
   transposed.allocN32Pixels(image.height(), image.width());
 
-  SkAutoLockPixels lock_image(image);
-  SkAutoLockPixels lock_transposed(transposed);
-
   for (int y = 0; y < image.height(); ++y) {
     uint32_t* image_row = image.getAddr32(0, y);
     for (int x = 0; x < image.width(); ++x) {
diff --git a/ui/gfx/skbitmap_operations_unittest.cc b/ui/gfx/skbitmap_operations_unittest.cc
index ce0851a..65f6843 100644
--- a/ui/gfx/skbitmap_operations_unittest.cc
+++ b/ui/gfx/skbitmap_operations_unittest.cc
@@ -31,9 +31,6 @@
 }
 
 bool BitmapsClose(const SkBitmap& a, const SkBitmap& b) {
-  SkAutoLockPixels a_lock(a);
-  SkAutoLockPixels b_lock(b);
-
   for (int y = 0; y < a.height(); y++) {
     for (int x = 0; x < a.width(); x++) {
       SkColor a_pixel = *a.getAddr32(x, y);
@@ -67,9 +64,6 @@
   shifted.allocN32Pixels(bitmap.width(), bitmap.height());
   shifted.eraseARGB(0, 0, 0, 0);
 
-  SkAutoLockPixels lock_bitmap(bitmap);
-  SkAutoLockPixels lock_shifted(shifted);
-
   // Loop through the pixels of the original bitmap.
   for (int y = 0; y < bitmap.height(); ++y) {
     SkPMColor* pixels = bitmap.getAddr32(0, y);
@@ -102,8 +96,6 @@
   }
 
   SkBitmap inverted = SkBitmapOperations::CreateInvertedBitmap(src);
-  SkAutoLockPixels src_lock(src);
-  SkAutoLockPixels inverted_lock(inverted);
 
   for (int y = 0; y < src_h; y++) {
     for (int x = 0; x < src_w; x++) {
@@ -142,9 +134,6 @@
   // Shift to red.
   SkBitmap blended = SkBitmapOperations::CreateBlendedBitmap(
     src_a, src_b, 0.5);
-  SkAutoLockPixels srca_lock(src_a);
-  SkAutoLockPixels srcb_lock(src_b);
-  SkAutoLockPixels blended_lock(blended);
 
   for (int y = 0; y < src_h; y++) {
     for (int x = 0; x < src_w; x++) {
@@ -179,10 +168,6 @@
 
   SkBitmap masked = SkBitmapOperations::CreateMaskedBitmap(src, alpha);
 
-  SkAutoLockPixels src_lock(src);
-  SkAutoLockPixels alpha_lock(alpha);
-  SkAutoLockPixels masked_lock(masked);
-
   for (int y = 0; y < src_h; y++) {
     for (int x = 0; x < src_w; x++) {
       int alpha_pixel = *alpha.getAddr32(x, y);
@@ -228,9 +213,6 @@
   color_utils::HSL hsl = { -1, -1, -1 };
   SkBitmap shifted = ReferenceCreateHSLShiftedBitmap(src, hsl);
 
-  SkAutoLockPixels src_lock(src);
-  SkAutoLockPixels shifted_lock(shifted);
-
   for (int y = 0; y < src_h; y++) {
     for (int x = 0; x < src_w; x++) {
       SkColor src_pixel = *src.getAddr32(x, y);
@@ -266,9 +248,6 @@
 
   SkBitmap shifted = SkBitmapOperations::CreateHSLShiftedBitmap(src, hsl);
 
-  SkAutoLockPixels src_lock(src);
-  SkAutoLockPixels shifted_lock(shifted);
-
   for (int y = 0, i = 0; y < src_h; y++) {
     for (int x = 0; x < src_w; x++) {
       EXPECT_TRUE(ColorsClose(shifted.getColor(x, y),
@@ -323,8 +302,6 @@
   ASSERT_EQ(8, cropped.width());
   ASSERT_EQ(8, cropped.height());
 
-  SkAutoLockPixels src_lock(src);
-  SkAutoLockPixels cropped_lock(cropped);
   for (int y = 4; y < 12; y++) {
     for (int x = 4; x < 12; x++) {
       EXPECT_EQ(*src.getAddr32(x, y),
@@ -344,8 +321,6 @@
   ASSERT_EQ(src_w, cropped.width());
   ASSERT_EQ(src_h, cropped.height());
 
-  SkAutoLockPixels src_lock(src);
-  SkAutoLockPixels cropped_lock(cropped);
   for (int y = 0; y < src_h; y++) {
     for (int x = 0; x < src_w; x++) {
       EXPECT_EQ(*src.getAddr32(x, y),
@@ -392,7 +367,6 @@
   EXPECT_EQ(2, result.height());
 
   // Some of the values are off-by-one due to rounding.
-  SkAutoLockPixels lock(result);
   EXPECT_EQ(0x9f404040, *result.getAddr32(0, 0));
   EXPECT_EQ(0xFF7f7f7f, *result.getAddr32(1, 0));
   EXPECT_EQ(0xFF7f7f7f, *result.getAddr32(0, 1));
@@ -408,7 +382,6 @@
   one_by_one.allocN32Pixels(1, 1);
   *one_by_one.getAddr32(0, 0) = reference;
   SkBitmap result = SkBitmapOperations::DownsampleByTwo(one_by_one);
-  SkAutoLockPixels lock1(result);
   EXPECT_EQ(1, result.width());
   EXPECT_EQ(1, result.height());
   EXPECT_EQ(reference, *result.getAddr32(0, 0));
@@ -417,7 +390,6 @@
   SkBitmap one_by_n;
   one_by_n.allocN32Pixels(300, 1);
   result = SkBitmapOperations::DownsampleByTwo(one_by_n);
-  SkAutoLockPixels lock2(result);
   EXPECT_EQ(300, result.width());
   EXPECT_EQ(1, result.height());
 
@@ -425,7 +397,6 @@
   SkBitmap n_by_one;
   n_by_one.allocN32Pixels(1, 300);
   result = SkBitmapOperations::DownsampleByTwo(n_by_one);
-  SkAutoLockPixels lock3(result);
   EXPECT_EQ(1, result.width());
   EXPECT_EQ(300, result.height());
 
@@ -477,7 +448,6 @@
   EXPECT_EQ(2, result.width());
   EXPECT_EQ(2, result.height());
 
-  SkAutoLockPixels lock(result);
   EXPECT_EQ(0x80000000, *result.getAddr32(0, 0));
   EXPECT_EQ(0x80FFFFFF, *result.getAddr32(1, 0));
   EXPECT_EQ(0xFF00CC88, *result.getAddr32(0, 1));
@@ -498,7 +468,6 @@
   EXPECT_EQ(3, result.width());
   EXPECT_EQ(2, result.height());
 
-  SkAutoLockPixels lock(result);
   for (int x = 0; x < input.width(); ++x) {
     for (int y = 0; y < input.height(); ++y) {
       EXPECT_EQ(*input.getAddr32(x, y), *result.getAddr32(y, x));
@@ -557,11 +526,6 @@
   ASSERT_EQ(rotate270.width(), src.height());
   ASSERT_EQ(rotate270.height(), src.width());
 
-  SkAutoLockPixels lock_src(src);
-  SkAutoLockPixels lock_90(rotate90);
-  SkAutoLockPixels lock_180(rotate180);
-  SkAutoLockPixels lock_270(rotate270);
-
   for (int x=0; x < src_w; ++x) {
     for (int y=0; y < src_h; ++y) {
       ASSERT_EQ(*src.getAddr32(x,y), *rotate90.getAddr32(src_h - (y+1),x));
diff --git a/ui/gfx/skia_util.cc b/ui/gfx/skia_util.cc
index c23eab2b..c0c4a54 100644
--- a/ui/gfx/skia_util.cc
+++ b/ui/gfx/skia_util.cc
@@ -97,15 +97,11 @@
   size_t size1 = 0;
   size_t size2 = 0;
 
-  bitmap1.lockPixels();
   addr1 = bitmap1.getAddr32(0, 0);
   size1 = bitmap1.getSize();
-  bitmap1.unlockPixels();
 
-  bitmap2.lockPixels();
   addr2 = bitmap2.getAddr32(0, 0);
   size2 = bitmap2.getSize();
-  bitmap2.unlockPixels();
 
   return (size1 == size2) && (0 == memcmp(addr1, addr2, bitmap1.getSize()));
 }
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd
index 0a4d71f..e0e348f 100644
--- a/ui/strings/ui_strings.grd
+++ b/ui/strings/ui_strings.grd
@@ -691,9 +691,6 @@
       <message name="IDS_DISPLAY_NAME_INTERNAL" desc="The name used for internal displays, which is shown in the display settings.">
         Internal Display
       </message>
-      <message name="IDS_DISPLAY_NAME_VIRTUAL" desc="The name used for virtual displays, which is shown in the display settings. Virtual displays are not associated with a physical monitor.">
-        Virtual Display
-      </message>
     </messages>
   </release>
 </grit>
diff --git a/ui/views/controls/image_view.cc b/ui/views/controls/image_view.cc
index 024155d..c6a7145 100644
--- a/ui/views/controls/image_view.cc
+++ b/ui/views/controls/image_view.cc
@@ -20,9 +20,7 @@
 // Returns the pixels for the bitmap in |image| at scale |image_scale|.
 void* GetBitmapPixels(const gfx::ImageSkia& img, float image_scale) {
   DCHECK_NE(0.0f, image_scale);
-  const SkBitmap& bitmap = img.GetRepresentation(image_scale).sk_bitmap();
-  SkAutoLockPixels pixel_lock(bitmap);
-  return bitmap.getPixels();
+  return img.GetRepresentation(image_scale).sk_bitmap().getPixels();
 }
 
 }  // namespace
diff --git a/ui/views/controls/menu/menu_delegate.h b/ui/views/controls/menu/menu_delegate.h
index db99e54..b1eca37 100644
--- a/ui/views/controls/menu/menu_delegate.h
+++ b/ui/views/controls/menu/menu_delegate.h
@@ -120,7 +120,7 @@
   virtual void ExecuteCommand(int id, int mouse_event_flags);
 
   // Returns true if ExecuteCommand() should be invoked while leaving the
-  // menu open. Default implementation returns true.
+  // menu open. Default implementation returns false.
   virtual bool ShouldExecuteCommandWithoutClosingMenu(int id,
                                                       const ui::Event& e);
 
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc
index 71d3ad8..7e35ae7 100644
--- a/ui/views/controls/textfield/textfield_unittest.cc
+++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -2797,13 +2797,15 @@
   EXPECT_EQ(gfx::Range(4, 4), textfield_->GetSelectedRange());
   EXPECT_TRUE(GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION).empty());
 
-  // Middle clicking in the selection should clear the clipboard and selection.
+  // Middle clicking in the selection should insert the selection clipboard
+  // contents into the middle of the selection, and move the cursor to the end
+  // of the pasted content.
   SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE, "foo");
   textfield_->SelectRange(gfx::Range(2, 6));
   textfield_->OnMousePressed(middle);
-  EXPECT_STR_EQ("012301230123", textfield_->text());
-  EXPECT_EQ(gfx::Range(6, 6), textfield_->GetSelectedRange());
-  EXPECT_TRUE(GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION).empty());
+  EXPECT_STR_EQ("0123foo01230123", textfield_->text());
+  EXPECT_EQ(gfx::Range(7, 7), textfield_->GetSelectedRange());
+  EXPECT_STR_EQ("foo", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
 
   // Double and triple clicking should update the clipboard contents.
   textfield_->SetText(ASCIIToUTF16("ab cd ef"));
diff --git a/ui/views/selection_controller.cc b/ui/views/selection_controller.cc
index fdf9924..6d7d7a9 100644
--- a/ui/views/selection_controller.cc
+++ b/ui/views/selection_controller.cc
@@ -80,20 +80,14 @@
     }
   }
 
-  if (handles_selection_clipboard_ && event.IsOnlyMiddleMouseButton()) {
-    if (render_text->IsPointInSelection(event.location())) {
-      delegate_->OnBeforePointerAction();
-      render_text->ClearSelection();
-      delegate_->UpdateSelectionClipboard();
-      delegate_->OnAfterPointerAction(false, true);
-    } else if (!delegate_->IsReadOnly()) {
-      delegate_->OnBeforePointerAction();
-      const bool selection_changed =
-          render_text->MoveCursorTo(event.location(), false);
-      const bool text_changed = delegate_->PasteSelectionClipboard();
-      delegate_->OnAfterPointerAction(text_changed,
-                                      selection_changed | text_changed);
-    }
+  if (handles_selection_clipboard_ && event.IsOnlyMiddleMouseButton() &&
+      !delegate_->IsReadOnly()) {
+    delegate_->OnBeforePointerAction();
+    const bool selection_changed =
+        render_text->MoveCursorTo(event.location(), false);
+    const bool text_changed = delegate_->PasteSelectionClipboard();
+    delegate_->OnAfterPointerAction(text_changed,
+                                    selection_changed | text_changed);
   }
 
   return true;
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
index a1118cf..0c829ba 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
@@ -1352,7 +1352,6 @@
   // don't make another context if the window would just be displaying a mostly
   // transparent image.
   const SkBitmap* in_bitmap = image.bitmap();
-  SkAutoLockPixels in_lock(*in_bitmap);
   for (int y = 0; y < in_bitmap->height(); ++y) {
     uint32_t* in_row = in_bitmap->getAddr32(0, y);
 
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 4215122..cd987802 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
@@ -1887,7 +1887,6 @@
   data->push_back(height);
 
   const SkBitmap& bitmap = rep.sk_bitmap();
-  SkAutoLockPixels locker(bitmap);
 
   for (int y = 0; y < height; ++y)
     for (int x = 0; x < width; ++x)
diff --git a/ui/webui/resources/html/md_select_css.html b/ui/webui/resources/html/md_select_css.html
index f9a8062..2eb49a7 100644
--- a/ui/webui/resources/html/md_select_css.html
+++ b/ui/webui/resources/html/md_select_css.html
@@ -11,15 +11,20 @@
 
       .md-select {
         --md-arrow-width: 0.9em;
+
+        /* The offset of the arrow from the end of the underline. */
+        --md-arrow-offset: 3%;
+
         -webkit-appearance: none;
         -webkit-margin-end: calc(-1 * var(--md-side-padding));
-        /* Ensure that the text does not overlap with the down arrow. */
+        /* Ensure that there is a 3px space between the text and the arrow. */
         -webkit-padding-end: calc(var(--md-side-padding) +
-            var(--md-arrow-width) * 1.8);
+            var(--md-arrow-offset) + var(--md-arrow-width) + 3px);
         -webkit-padding-start: var(--md-side-padding);
         background: url(
             chrome://resources/images/arrow_down.svg)
-            calc(97% - var(--md-side-padding)) center no-repeat;
+            calc(100% - var(--md-arrow-offset) - var(--md-side-padding))
+            center no-repeat;
         background-size: var(--md-arrow-width);
         border: none;
         color: var(--primary-text-color);
@@ -44,7 +49,8 @@
       }
 
       :host-context([dir=rtl]) .md-select {
-        background-position-x: calc(var(--md-side-padding) + 3%);
+        background-position-x: calc(var(--md-side-padding) +
+            var(--md-arrow-offset));
       }
 
       /* Persistent underline */