diff --git a/.gn b/.gn
index d243f0cd..50a8a2f 100644
--- a/.gn
+++ b/.gn
@@ -3,6 +3,7 @@
 # file, run "gn help dotfile" at the command line.
 
 import("//build/dotfile_settings.gni")
+import("//third_party/angle/dotfile_settings.gni")
 
 # The location of the build configuration file.
 buildconfig = "//build/config/BUILDCONFIG.gn"
@@ -231,7 +232,9 @@
 #      files and passes them to a script, it will always be correct.
 
 exec_script_whitelist =
-    build_dotfile_settings.exec_script_whitelist + [
+    build_dotfile_settings.exec_script_whitelist +
+    angle_dotfile_settings.exec_script_whitelist +
+    [
       # Whitelist entries for //build should go into
       # //build/dotfile_settings.gni instead, so that they can be shared
       # with other repos. The entries in this list should be only for files
@@ -248,9 +251,6 @@
       "//remoting/host/installer/win/generate_clsids.gni",
 
       # TODO(dpranke): Get these from the appropriate repos instead.
-      "//third_party/angle/BUILD.gn",
-      "//third_party/angle/src/tests/BUILD.gn",
-      "//third_party/angle/src/vulkan_support/BUILD.gn",
       "//third_party/catapult/tracing/BUILD.gn",
       "//third_party/google_input_tools/inputview.gni",
 
diff --git a/DEPS b/DEPS
index 97d05ebe..a857efa 100644
--- a/DEPS
+++ b/DEPS
@@ -79,11 +79,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': 'b915b978e3c34e7ded50e1433cbc9e342bb71404',
+  'skia_revision': '2fb7c8aef57e4b94d5215e618d8c3b4cccd35edf',
   # 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': 'ebe77c45b6ffbb591aa897f25942ba3867cedac7',
+  'v8_revision': 'a24f69106db7115d65e35b1d834743e3c3550458',
   # 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.
@@ -135,7 +135,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'a1303e46889b22580cbf6129a01fd1c1c094b4f3',
+  'catapult_revision': 'e6e84629dbe593096a7771373de2f33bfb9d2902',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -649,10 +649,10 @@
     Var('chromium_git') + '/external/selenium/py.git' + '@' + '5fd78261a75fe08d27ca4835fb6c5ce4b42275bd',
 
   'src/third_party/webgl/src':
-    Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '98a3d3b4355644bb1187a858fdd2aff6b2bc84ec',
+    Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a182a9ad3078aca566d8355eabf2d9f56f70ee82',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '7092368982d3f9c5a503cde2c6ee08c05eedfe25', # commit position 21742
+    Var('webrtc_git') + '/src.git' + '@' + '29f14322d13e126c1c9cab0d3bf874bd2a652fdb', # commit position 21742
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/android_webview/browser/aw_field_trial_creator.cc b/android_webview/browser/aw_field_trial_creator.cc
index 09c3d27..ff8e4b2 100644
--- a/android_webview/browser/aw_field_trial_creator.cc
+++ b/android_webview/browser/aw_field_trial_creator.cc
@@ -31,7 +31,7 @@
   return std::unique_ptr<const base::FieldTrial::EntropyProvider>(
       // Since variations are only enabled for users opted in to UMA, it is
       // acceptable to use the SHA1EntropyProvider for randomization.
-      new metrics::SHA1EntropyProvider(
+      new variations::SHA1EntropyProvider(
           // Synchronous read of the client id is permitted as it is fast
           // enough to have minimal impact on startup time, and is behind the
           // webview-enable-finch flag.
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 45c3e47..9ea7f3a 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -300,6 +300,8 @@
     "login/ui/user_switch_flip_animation.cc",
     "login/ui/user_switch_flip_animation.h",
     "login_status.h",
+    "magnifier/docked_magnifier_controller.cc",
+    "magnifier/docked_magnifier_controller.h",
     "magnifier/magnification_controller.cc",
     "magnifier/magnification_controller.h",
     "magnifier/partial_magnification_controller.cc",
@@ -1025,6 +1027,7 @@
 
   public_deps = [
     "//ash/public/cpp",
+    "//ash/public/cpp/vector_icons",
     "//ash/resources",
     "//ash/resources/vector_icons",
     "//ash/strings",
@@ -1401,6 +1404,7 @@
     "login/ui/login_test_utils.h",
     "login/ui/login_user_view_unittest.cc",
     "login/ui/note_action_launch_button_unittest.cc",
+    "magnifier/docked_magnifier_controller_unittest.cc",
     "magnifier/magnification_controller_unittest.cc",
     "magnifier/partial_magnification_controller_unittest.cc",
     "message_center/message_center_view_unittest.cc",
@@ -1570,6 +1574,7 @@
     "//ash/autoclick/common:autoclick",
     "//ash/public/cpp",
     "//ash/public/cpp:unit_tests",
+    "//ash/public/cpp/vector_icons",
     "//ash/resources",
     "//ash/resources/vector_icons",
     "//ash/strings",
diff --git a/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc b/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
index 0d9c594..4d99a9bf 100644
--- a/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
+++ b/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
@@ -6,7 +6,7 @@
 
 #include "ash/ash_layout_constants.h"
 #include "ash/frame/caption_buttons/frame_caption_button.h"
-#include "ash/resources/vector_icons/vector_icons.h"
+#include "ash/public/cpp/vector_icons/vector_icons.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
diff --git a/ash/frame/caption_buttons/frame_size_button_unittest.cc b/ash/frame/caption_buttons/frame_size_button_unittest.cc
index e8e1cf3..37412c1 100644
--- a/ash/frame/caption_buttons/frame_size_button_unittest.cc
+++ b/ash/frame/caption_buttons/frame_size_button_unittest.cc
@@ -7,7 +7,7 @@
 #include "ash/ash_layout_constants.h"
 #include "ash/frame/caption_buttons/frame_caption_button.h"
 #include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
-#include "ash/resources/vector_icons/vector_icons.h"
+#include "ash/public/cpp/vector_icons/vector_icons.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/wm/window_state.h"
diff --git a/ash/frame/default_frame_header.cc b/ash/frame/default_frame_header.cc
index a8d615a..451bd93 100644
--- a/ash/frame/default_frame_header.cc
+++ b/ash/frame/default_frame_header.cc
@@ -8,8 +8,8 @@
 #include "ash/frame/caption_buttons/frame_caption_button.h"
 #include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
 #include "ash/frame/frame_header_util.h"
+#include "ash/public/cpp/vector_icons/vector_icons.h"
 #include "ash/resources/grit/ash_resources.h"
-#include "ash/resources/vector_icons/vector_icons.h"
 #include "base/debug/leak_annotations.h"
 #include "base/logging.h"  // DCHECK
 #include "third_party/skia/include/core/SkPath.h"
diff --git a/ash/magnifier/docked_magnifier_controller.cc b/ash/magnifier/docked_magnifier_controller.cc
new file mode 100644
index 0000000..d3b24cdf
--- /dev/null
+++ b/ash/magnifier/docked_magnifier_controller.cc
@@ -0,0 +1,131 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/magnifier/docked_magnifier_controller.h"
+
+#include "ash/public/cpp/ash_pref_names.h"
+#include "ash/session/session_controller.h"
+#include "ash/shell.h"
+#include "base/numerics/ranges.h"
+#include "components/prefs/pref_change_registrar.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+
+namespace ash {
+
+namespace {
+
+constexpr float kDefaultMagnifierScale = 2.0f;
+constexpr float kMinMagnifierScale = 1.0f;
+constexpr float kMaxMagnifierScale = 10.0f;
+
+}  // namespace
+
+DockedMagnifierController::DockedMagnifierController() : binding_(this) {
+  Shell::Get()->session_controller()->AddObserver(this);
+}
+
+DockedMagnifierController::~DockedMagnifierController() {
+  Shell::Get()->session_controller()->RemoveObserver(this);
+}
+
+// static
+void DockedMagnifierController::RegisterProfilePrefs(
+    PrefRegistrySimple* registry) {
+  registry->RegisterBooleanPref(prefs::kDockedMagnifierEnabled, false,
+                                PrefRegistry::PUBLIC);
+  registry->RegisterDoublePref(prefs::kDockedMagnifierScale,
+                               kDefaultMagnifierScale, PrefRegistry::PUBLIC);
+}
+
+void DockedMagnifierController::BindRequest(
+    mojom::DockedMagnifierControllerRequest request) {
+  binding_.Bind(std::move(request));
+}
+
+bool DockedMagnifierController::GetEnabled() const {
+  return active_user_pref_service_ &&
+         active_user_pref_service_->GetBoolean(prefs::kDockedMagnifierEnabled);
+}
+
+float DockedMagnifierController::GetScale() const {
+  if (active_user_pref_service_)
+    return active_user_pref_service_->GetDouble(prefs::kDockedMagnifierScale);
+
+  return kDefaultMagnifierScale;
+}
+
+void DockedMagnifierController::SetEnabled(bool enabled) {
+  if (active_user_pref_service_) {
+    active_user_pref_service_->SetBoolean(prefs::kDockedMagnifierEnabled,
+                                          enabled);
+  }
+}
+
+void DockedMagnifierController::SetScale(float scale) {
+  if (active_user_pref_service_) {
+    active_user_pref_service_->SetDouble(
+        prefs::kDockedMagnifierScale,
+        base::ClampToRange(scale, kMinMagnifierScale, kMaxMagnifierScale));
+  }
+}
+
+void DockedMagnifierController::SetClient(
+    mojom::DockedMagnifierClientPtr client) {
+  client_ = std::move(client);
+  NotifyClientWithStatusChanged();
+}
+
+void DockedMagnifierController::CenterOnPoint(
+    const gfx::Point& point_in_screen) {
+  // TODO(afakhry): Implement logic here.
+}
+
+void DockedMagnifierController::OnActiveUserPrefServiceChanged(
+    PrefService* pref_service) {
+  active_user_pref_service_ = pref_service;
+  InitFromUserPrefs();
+}
+
+void DockedMagnifierController::FlushClientPtrForTesting() {
+  client_.FlushForTesting();
+}
+
+void DockedMagnifierController::InitFromUserPrefs() {
+  DCHECK(active_user_pref_service_);
+
+  pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
+  pref_change_registrar_->Init(active_user_pref_service_);
+  pref_change_registrar_->Add(
+      prefs::kDockedMagnifierEnabled,
+      base::BindRepeating(&DockedMagnifierController::OnEnabledPrefChanged,
+                          base::Unretained(this)));
+  pref_change_registrar_->Add(
+      prefs::kDockedMagnifierScale,
+      base::BindRepeating(&DockedMagnifierController::OnScalePrefChanged,
+                          base::Unretained(this)));
+
+  Refresh();
+  NotifyClientWithStatusChanged();
+}
+
+void DockedMagnifierController::OnEnabledPrefChanged() {
+  Refresh();
+  NotifyClientWithStatusChanged();
+}
+
+void DockedMagnifierController::OnScalePrefChanged() {
+  Refresh();
+}
+
+void DockedMagnifierController::Refresh() {
+  // TODO(afakhry): Implement logic here.
+}
+
+void DockedMagnifierController::NotifyClientWithStatusChanged() {
+  if (client_)
+    client_->OnEnabledStatusChanged(GetEnabled());
+}
+
+}  // namespace ash
diff --git a/ash/magnifier/docked_magnifier_controller.h b/ash/magnifier/docked_magnifier_controller.h
new file mode 100644
index 0000000..198dea2
--- /dev/null
+++ b/ash/magnifier/docked_magnifier_controller.h
@@ -0,0 +1,80 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_MAGNIFIER_DOCKED_MAGNIFIER_CONTROLLER_H_
+#define ASH_MAGNIFIER_DOCKED_MAGNIFIER_CONTROLLER_H_
+
+#include <memory>
+
+#include "ash/ash_export.h"
+#include "ash/public/interfaces/docked_magnifier_controller.mojom.h"
+#include "ash/session/session_observer.h"
+#include "mojo/public/cpp/bindings/binding.h"
+
+class PrefRegistrySimple;
+class PrefService;
+class PrefChangeRegistrar;
+
+namespace ash {
+
+// Controls the Docked Magnifier (a.k.a. picture-in-picture magnifier) feature,
+// which allocates the top portion of the currently active display as a
+// magnified viewport of an area around the point of interest in the screen
+// (which follows the cursor location, text input caret location, or focus
+// changes).
+class ASH_EXPORT DockedMagnifierController
+    : public mojom::DockedMagnifierController,
+      public SessionObserver {
+ public:
+  DockedMagnifierController();
+  ~DockedMagnifierController() override;
+
+  static void RegisterProfilePrefs(PrefRegistrySimple* registry);
+
+  void BindRequest(mojom::DockedMagnifierControllerRequest request);
+
+  // Get the Docked Magnifier settings for the current active user prefs.
+  bool GetEnabled() const;
+  float GetScale() const;
+
+  // Set the Docked Magnifier settings in the current active user prefs.
+  void SetEnabled(bool enabled);
+  void SetScale(float scale);
+
+  // ash::mojom::DockedMagnifierController:
+  void SetClient(mojom::DockedMagnifierClientPtr client) override;
+  void CenterOnPoint(const gfx::Point& point_in_screen) override;
+
+  // SessionObserver:
+  void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;
+
+  void FlushClientPtrForTesting();
+
+ private:
+  void InitFromUserPrefs();
+
+  // Handlers of prefs changes.
+  void OnEnabledPrefChanged();
+  void OnScalePrefChanged();
+
+  void Refresh();
+
+  void NotifyClientWithStatusChanged();
+
+  // The pref service of the currently active user. Can be null in
+  // ash_unittests.
+  PrefService* active_user_pref_service_ = nullptr;
+
+  std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
+
+  mojo::Binding<mojom::DockedMagnifierController> binding_;
+
+  mojom::DockedMagnifierClientPtr client_;
+
+  DISALLOW_COPY_AND_ASSIGN(DockedMagnifierController);
+};
+
+}  // namespace ash
+
+#endif  // ASH_MAGNIFIER_DOCKED_MAGNIFIER_CONTROLLER_H_
diff --git a/ash/magnifier/docked_magnifier_controller_unittest.cc b/ash/magnifier/docked_magnifier_controller_unittest.cc
new file mode 100644
index 0000000..fe5b66c
--- /dev/null
+++ b/ash/magnifier/docked_magnifier_controller_unittest.cc
@@ -0,0 +1,189 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/magnifier/docked_magnifier_controller.h"
+
+#include <memory>
+
+#include "ash/public/cpp/ash_pref_names.h"
+#include "ash/public/cpp/ash_switches.h"
+#include "ash/public/interfaces/docked_magnifier_controller.mojom.h"
+#include "ash/session/session_controller.h"
+#include "ash/session/test_session_controller_client.h"
+#include "ash/shell.h"
+#include "ash/test/ash_test_base.h"
+#include "ash/test/ash_test_helper.h"
+#include "components/prefs/pref_service.h"
+#include "mojo/public/cpp/bindings/binding.h"
+
+namespace ash {
+
+namespace {
+
+constexpr char kUser1Email[] = "user1@dockedmagnifier";
+constexpr char kUser2Email[] = "user2@dockedmagnifier";
+
+// Mock mojo client of the Docked Magnifier.
+class DockedMagnifierTestClient : public mojom::DockedMagnifierClient {
+ public:
+  DockedMagnifierTestClient() : binding_(this) {}
+  ~DockedMagnifierTestClient() override = default;
+
+  bool docked_magnifier_enabled() const { return docked_magnifier_enabled_; }
+
+  // Connects to the DockedMagnifierController.
+  void Start() {
+    ash::mojom::DockedMagnifierClientPtr client;
+    binding_.Bind(mojo::MakeRequest(&client));
+    Shell::Get()->docked_magnifier_controller()->SetClient(std::move(client));
+  }
+
+  // ash::mojom::DockedMagnifierClient:
+  void OnEnabledStatusChanged(bool enabled) override {
+    docked_magnifier_enabled_ = enabled;
+  }
+
+ private:
+  mojo::Binding<ash::mojom::DockedMagnifierClient> binding_;
+
+  bool docked_magnifier_enabled_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(DockedMagnifierTestClient);
+};
+
+class DockedMagnifierTest : public NoSessionAshTestBase {
+ public:
+  DockedMagnifierTest() = default;
+  ~DockedMagnifierTest() override = default;
+
+  DockedMagnifierController* controller() const {
+    return Shell::Get()->docked_magnifier_controller();
+  }
+
+  DockedMagnifierTestClient* test_client() { return &test_client_; }
+
+  PrefService* user1_pref_service() {
+    return Shell::Get()->session_controller()->GetUserPrefServiceForUser(
+        AccountId::FromUserEmail(kUser1Email));
+  }
+
+  PrefService* user2_pref_service() {
+    return Shell::Get()->session_controller()->GetUserPrefServiceForUser(
+        AccountId::FromUserEmail(kUser2Email));
+  }
+
+  // AshTestBase:
+  void SetUp() override {
+    // Explicitly enable the Docked Magnifier feature for the tests.
+    base::CommandLine::ForCurrentProcess()->AppendSwitch(
+        ash::switches::kAshEnableDockedMagnifier);
+
+    NoSessionAshTestBase::SetUp();
+    CreateTestUserSessions();
+
+    // Simulate user 1 login.
+    SwitchActiveUser(kUser1Email);
+
+    test_client_.Start();
+  }
+
+  void CreateTestUserSessions() {
+    GetSessionControllerClient()->Reset();
+    GetSessionControllerClient()->AddUserSession(kUser1Email);
+    GetSessionControllerClient()->AddUserSession(kUser2Email);
+  }
+
+  void SwitchActiveUser(const std::string& email) {
+    GetSessionControllerClient()->SwitchActiveUser(
+        AccountId::FromUserEmail(email));
+  }
+
+ private:
+  DockedMagnifierTestClient test_client_;
+
+  DISALLOW_COPY_AND_ASSIGN(DockedMagnifierTest);
+};
+
+// Tests the changes in the magnifier's status, user switches and the
+// interaction with the client.
+TEST_F(DockedMagnifierTest, TestEnableAndDisable) {
+  // Client should receive status updates.
+  EXPECT_FALSE(controller()->GetEnabled());
+  EXPECT_FALSE(test_client()->docked_magnifier_enabled());
+  controller()->SetEnabled(true);
+  controller()->FlushClientPtrForTesting();
+  EXPECT_TRUE(controller()->GetEnabled());
+  EXPECT_TRUE(test_client()->docked_magnifier_enabled());
+  controller()->SetEnabled(false);
+  controller()->FlushClientPtrForTesting();
+  EXPECT_FALSE(controller()->GetEnabled());
+  EXPECT_FALSE(test_client()->docked_magnifier_enabled());
+
+  // Enable again for user 1, and switch to user 2. User 2 should have it
+  // disabled, the client should be updated accordingly.
+  controller()->SetEnabled(true);
+  controller()->FlushClientPtrForTesting();
+  EXPECT_TRUE(controller()->GetEnabled());
+  EXPECT_TRUE(test_client()->docked_magnifier_enabled());
+  SwitchActiveUser(kUser2Email);
+  controller()->FlushClientPtrForTesting();
+  EXPECT_FALSE(controller()->GetEnabled());
+  EXPECT_FALSE(test_client()->docked_magnifier_enabled());
+
+  // Switch back to user 1, expect it to be enabled.
+  SwitchActiveUser(kUser1Email);
+  controller()->FlushClientPtrForTesting();
+  EXPECT_TRUE(controller()->GetEnabled());
+  EXPECT_TRUE(test_client()->docked_magnifier_enabled());
+}
+
+// Tests the magnifier's scale changes.
+TEST_F(DockedMagnifierTest, TestScale) {
+  // Scale changes are persisted even when the Docked Magnifier is disabled.
+  EXPECT_FALSE(controller()->GetEnabled());
+  controller()->SetScale(5.0f);
+  EXPECT_FLOAT_EQ(5.0f, controller()->GetScale());
+
+  // Scale values are clamped to a minimum of 1.0f (which means no scale).
+  controller()->SetScale(0.0f);
+  EXPECT_FLOAT_EQ(1.0f, controller()->GetScale());
+
+  // Switch to user 2, change the scale, then switch back to user 1. User 1's
+  // scale should not change.
+  SwitchActiveUser(kUser2Email);
+  controller()->SetScale(6.5f);
+  EXPECT_FLOAT_EQ(6.5f, controller()->GetScale());
+  SwitchActiveUser(kUser1Email);
+  EXPECT_FLOAT_EQ(1.0f, controller()->GetScale());
+}
+
+// Tests that updates of the Docked Magnifier user prefs from outside the
+// DockedMagnifierController (such as Settings UI) are observed and applied.
+TEST_F(DockedMagnifierTest, TestOutsidePrefsUpdates) {
+  EXPECT_FALSE(controller()->GetEnabled());
+  EXPECT_FALSE(test_client()->docked_magnifier_enabled());
+  user1_pref_service()->SetBoolean(prefs::kDockedMagnifierEnabled, true);
+  controller()->FlushClientPtrForTesting();
+  EXPECT_TRUE(controller()->GetEnabled());
+  EXPECT_TRUE(test_client()->docked_magnifier_enabled());
+  user1_pref_service()->SetDouble(prefs::kDockedMagnifierScale, 7.3f);
+  EXPECT_FLOAT_EQ(7.3f, controller()->GetScale());
+  user1_pref_service()->SetBoolean(prefs::kDockedMagnifierEnabled, false);
+  controller()->FlushClientPtrForTesting();
+  EXPECT_FALSE(controller()->GetEnabled());
+  EXPECT_FALSE(test_client()->docked_magnifier_enabled());
+}
+
+// TODO(afakhry): Expand tests:
+// - Test magnifier viewport's layer transforms.
+// - Test display workarea changes.
+// - Test with screen rotation, multi display, and unified mode.
+// - Test point of interest changes.
+// - Test following text input caret.
+// - Test adjust scale using shortcut.
+// - Test add/remove displays.
+
+}  // namespace
+
+}  // namespace ash
diff --git a/ash/manifest.json b/ash/manifest.json
index fbee95d7..e12a5bd 100644
--- a/ash/manifest.json
+++ b/ash/manifest.json
@@ -13,6 +13,7 @@
           "ash::mojom::AccessibilityController",
           "ash::mojom::AshMessageCenterController",
           "ash::mojom::CastConfig",
+          "ash::mojom::DockedMagnifierController",
           "ash::mojom::HighlighterController",
           "ash::mojom::ImeController",
           "ash::mojom::LocaleNotificationController",
diff --git a/ash/mojo_interface_factory.cc b/ash/mojo_interface_factory.cc
index 399d5356..f63a1aa 100644
--- a/ash/mojo_interface_factory.cc
+++ b/ash/mojo_interface_factory.cc
@@ -13,6 +13,7 @@
 #include "ash/highlighter/highlighter_controller.h"
 #include "ash/ime/ime_controller.h"
 #include "ash/login/login_screen_controller.h"
+#include "ash/magnifier/docked_magnifier_controller.h"
 #include "ash/media_controller.h"
 #include "ash/message_center/message_center_controller.h"
 #include "ash/metrics/time_to_first_present_recorder.h"
@@ -73,6 +74,11 @@
   Shell::Get()->cast_config()->BindRequest(std::move(request));
 }
 
+void BindDockedMagnifierControllerRequestOnMainThread(
+    mojom::DockedMagnifierControllerRequest request) {
+  Shell::Get()->docked_magnifier_controller()->BindRequest(std::move(request));
+}
+
 void BindHighlighterControllerRequestOnMainThread(
     mojom::HighlighterControllerRequest request) {
   Shell::Get()->highlighter_controller()->BindRequest(std::move(request));
@@ -179,6 +185,11 @@
       main_thread_task_runner);
   registry->AddInterface(base::Bind(&BindCastConfigOnMainThread),
                          main_thread_task_runner);
+  if (switches::IsDockedMagnifierEnabled()) {
+    registry->AddInterface(
+        base::BindRepeating(&BindDockedMagnifierControllerRequestOnMainThread),
+        main_thread_task_runner);
+  }
   registry->AddInterface(
       base::Bind(&BindHighlighterControllerRequestOnMainThread),
       main_thread_task_runner);
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn
index 49e343a..8c8e045 100644
--- a/ash/public/cpp/BUILD.gn
+++ b/ash/public/cpp/BUILD.gn
@@ -38,6 +38,8 @@
     "immersive/immersive_revealed_lock.cc",
     "immersive/immersive_revealed_lock.h",
     "login_constants.h",
+    "menu_utils.cc",
+    "menu_utils.h",
     "mus_property_mirror_ash.cc",
     "mus_property_mirror_ash.h",
     "remote_shelf_item_delegate.cc",
@@ -112,8 +114,9 @@
 source_set("unit_tests") {
   testonly = true
   sources = [
+    "menu_utils_unittest.cc",
     "shelf_model_unittest.cc",
-    "shelf_struct_traits_unittest.cc",
+    "shelf_struct_mojom_traits_unittest.cc",
   ]
 
   deps = [
diff --git a/ash/public/cpp/OWNERS b/ash/public/cpp/OWNERS
index 16f082a..8da0832 100644
--- a/ash/public/cpp/OWNERS
+++ b/ash/public/cpp/OWNERS
@@ -2,4 +2,6 @@
 per-file *.mojom=file://ipc/SECURITY_OWNERS
 
 per-file *_struct_traits*.*=set noparent
-per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
\ No newline at end of file
+per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *_mojom_traits*.*=set noparent
+per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/ash/public/cpp/ash_pref_names.cc b/ash/public/cpp/ash_pref_names.cc
index f5e57e5..642116c 100644
--- a/ash/public/cpp/ash_pref_names.cc
+++ b/ash/public/cpp/ash_pref_names.cc
@@ -67,6 +67,12 @@
 // regardless of the state of a11y features.
 const char kShouldAlwaysShowAccessibilityMenu[] = "settings.a11y.enable_menu";
 
+// A boolean pref storing the enabled status of the Docked Magnifier feature.
+const char kDockedMagnifierEnabled[] = "ash.docked_magnifier.enabled";
+// A double pref storing the scale value of the Docked Magnifier feature by
+// which the screen is magnified.
+const char kDockedMagnifierScale[] = "ash.docked_magnifier.scale";
+
 // A boolean pref which stores whether a stylus has been seen before.
 const char kHasSeenStylus[] = "ash.has_seen_stylus";
 // A boolean pref which stores whether a the palette warm welcome bubble
diff --git a/ash/public/cpp/ash_pref_names.h b/ash/public/cpp/ash_pref_names.h
index 72106378..d239579 100644
--- a/ash/public/cpp/ash_pref_names.h
+++ b/ash/public/cpp/ash_pref_names.h
@@ -30,6 +30,9 @@
 ASH_PUBLIC_EXPORT extern const char kAccessibilitySwitchAccessEnabled[];
 ASH_PUBLIC_EXPORT extern const char kShouldAlwaysShowAccessibilityMenu[];
 
+ASH_PUBLIC_EXPORT extern const char kDockedMagnifierEnabled[];
+ASH_PUBLIC_EXPORT extern const char kDockedMagnifierScale[];
+
 ASH_PUBLIC_EXPORT extern const char kHasSeenStylus[];
 ASH_PUBLIC_EXPORT extern const char kShownPaletteWelcomeBubble[];
 ASH_PUBLIC_EXPORT extern const char kEnableStylusTools[];
diff --git a/ash/public/cpp/ash_switches.cc b/ash/public/cpp/ash_switches.cc
index 268b8ee..98c1810 100644
--- a/ash/public/cpp/ash_switches.cc
+++ b/ash/public/cpp/ash_switches.cc
@@ -196,6 +196,11 @@
       kAshEnableDisplayMoveWindowAccels);
 }
 
+bool IsDockedMagnifierEnabled() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+      kAshEnableDockedMagnifier);
+}
+
 bool IsNightLightEnabled() {
   return base::CommandLine::ForCurrentProcess()->HasSwitch(
       kAshEnableNightLight);
diff --git a/ash/public/cpp/ash_switches.h b/ash/public/cpp/ash_switches.h
index 6a5d76e..f6958e8 100644
--- a/ash/public/cpp/ash_switches.h
+++ b/ash/public/cpp/ash_switches.h
@@ -71,6 +71,7 @@
 ASH_PUBLIC_EXPORT extern const char kUseIMEService[];
 
 ASH_PUBLIC_EXPORT bool IsDisplayMoveWindowAccelsEnabled();
+ASH_PUBLIC_EXPORT bool IsDockedMagnifierEnabled();
 ASH_PUBLIC_EXPORT bool IsNightLightEnabled();
 ASH_PUBLIC_EXPORT bool IsSidebarEnabled();
 ASH_PUBLIC_EXPORT bool IsUsingViewsLogin();
diff --git a/ash/public/cpp/menu_struct_mojom_traits.h b/ash/public/cpp/menu_struct_mojom_traits.h
new file mode 100644
index 0000000..a799efd
--- /dev/null
+++ b/ash/public/cpp/menu_struct_mojom_traits.h
@@ -0,0 +1,62 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_PUBLIC_CPP_MENU_STRUCT_MOJOM_TRAITS_H_
+#define ASH_PUBLIC_CPP_MENU_STRUCT_MOJOM_TRAITS_H_
+
+#include "ash/public/cpp/ash_public_export.h"
+#include "ash/public/interfaces/menu.mojom-shared.h"
+#include "ui/base/models/menu_model.h"
+
+namespace mojo {
+
+template <>
+struct EnumTraits<ash::mojom::MenuItemType, ui::MenuModel::ItemType> {
+  static ash::mojom::MenuItemType ToMojom(ui::MenuModel::ItemType input) {
+    switch (input) {
+      case ui::MenuModel::TYPE_COMMAND:
+        return ash::mojom::MenuItemType::COMMAND;
+      case ui::MenuModel::TYPE_CHECK:
+        return ash::mojom::MenuItemType::CHECK;
+      case ui::MenuModel::TYPE_RADIO:
+        return ash::mojom::MenuItemType::RADIO;
+      case ui::MenuModel::TYPE_SEPARATOR:
+        return ash::mojom::MenuItemType::SEPARATOR;
+      case ui::MenuModel::TYPE_BUTTON_ITEM:
+        NOTREACHED() << "TYPE_BUTTON_ITEM is not yet supported.";
+        return ash::mojom::MenuItemType::COMMAND;
+      case ui::MenuModel::TYPE_SUBMENU:
+        return ash::mojom::MenuItemType::SUBMENU;
+    }
+    NOTREACHED();
+    return ash::mojom::MenuItemType::COMMAND;
+  }
+
+  static bool FromMojom(ash::mojom::MenuItemType input,
+                        ui::MenuModel::ItemType* out) {
+    switch (input) {
+      case ash::mojom::MenuItemType::COMMAND:
+        *out = ui::MenuModel::TYPE_COMMAND;
+        return true;
+      case ash::mojom::MenuItemType::CHECK:
+        *out = ui::MenuModel::TYPE_CHECK;
+        return true;
+      case ash::mojom::MenuItemType::RADIO:
+        *out = ui::MenuModel::TYPE_RADIO;
+        return true;
+      case ash::mojom::MenuItemType::SEPARATOR:
+        *out = ui::MenuModel::TYPE_SEPARATOR;
+        return true;
+      case ash::mojom::MenuItemType::SUBMENU:
+        *out = ui::MenuModel::TYPE_SUBMENU;
+        return true;
+    }
+    NOTREACHED();
+    return false;
+  }
+};
+
+}  // namespace mojo
+
+#endif  // ASH_PUBLIC_CPP_MENU_STRUCT_MOJOM_TRAITS_H_
diff --git a/ash/public/cpp/menu_utils.cc b/ash/public/cpp/menu_utils.cc
new file mode 100644
index 0000000..ac723348
--- /dev/null
+++ b/ash/public/cpp/menu_utils.cc
@@ -0,0 +1,95 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/public/cpp/menu_utils.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/no_destructor.h"
+#include "ui/gfx/image/image.h"
+
+namespace ash {
+namespace menu_utils {
+
+MenuItemList GetMojoMenuItemsFromModel(const ui::MenuModel* model) {
+  MenuItemList items;
+  if (!model)
+    return items;
+  for (int i = 0; i < model->GetItemCount(); ++i) {
+    mojom::MenuItemPtr item(mojom::MenuItem::New());
+    DCHECK_NE(ui::MenuModel::TYPE_BUTTON_ITEM, model->GetTypeAt(i));
+    item->type = model->GetTypeAt(i);
+    item->command_id = model->GetCommandIdAt(i);
+    item->label = model->GetLabelAt(i);
+    item->checked = model->IsItemCheckedAt(i);
+    item->enabled = model->IsEnabledAt(i);
+    item->radio_group_id = model->GetGroupIdAt(i);
+    if (item->type == ui::MenuModel::TYPE_SUBMENU)
+      item->submenu = GetMojoMenuItemsFromModel(model->GetSubmenuModelAt(i));
+    items.push_back(std::move(item));
+  }
+  return items;
+}
+
+void PopulateMenuFromMojoMenuItems(ui::SimpleMenuModel* model,
+                                   ui::SimpleMenuModel::Delegate* delegate,
+                                   const MenuItemList& items,
+                                   SubmenuList* submenus) {
+  for (const mojom::MenuItemPtr& item : items) {
+    switch (item->type) {
+      case ui::MenuModel::TYPE_COMMAND:
+        model->AddItem(item->command_id, item->label);
+        break;
+      case ui::MenuModel::TYPE_CHECK:
+        model->AddCheckItem(item->command_id, item->label);
+        break;
+      case ui::MenuModel::TYPE_RADIO:
+        model->AddRadioItem(item->command_id, item->label,
+                            item->radio_group_id);
+        break;
+      case ui::MenuModel::TYPE_SEPARATOR:
+        model->AddSeparator(ui::NORMAL_SEPARATOR);
+        break;
+      case ui::MenuModel::TYPE_BUTTON_ITEM:
+        NOTREACHED() << "TYPE_BUTTON_ITEM is not yet supported.";
+        break;
+      case ui::MenuModel::TYPE_SUBMENU:
+        if (item->submenu.has_value()) {
+          std::unique_ptr<ui::SimpleMenuModel> submenu =
+              std::make_unique<ui::SimpleMenuModel>(delegate);
+          PopulateMenuFromMojoMenuItems(submenu.get(), delegate,
+                                        item->submenu.value(), submenus);
+          model->AddSubMenu(item->command_id, item->label, submenu.get());
+          submenus->push_back(std::move(submenu));
+        }
+        break;
+    }
+    if (!item->image.isNull()) {
+      model->SetIcon(model->GetIndexOfCommandId(item->command_id),
+                     gfx::Image(item->image));
+    }
+  }
+}
+
+const mojom::MenuItemPtr& GetMenuItemByCommandId(const MenuItemList& items,
+                                                 int command_id) {
+  static const base::NoDestructor<mojom::MenuItemPtr> item_not_found(
+      mojom::MenuItem::New());
+  for (const mojom::MenuItemPtr& item : items) {
+    if (item->command_id == command_id)
+      return item;
+    if (item->type == ui::MenuModel::TYPE_SUBMENU &&
+        item->submenu.has_value()) {
+      const mojom::MenuItemPtr& submenu_item =
+          GetMenuItemByCommandId(item->submenu.value(), command_id);
+      if (submenu_item->command_id == command_id)
+        return submenu_item;
+    }
+  }
+  return *item_not_found;
+}
+
+}  // namespace menu_utils
+}  // namespace ash
diff --git a/ash/public/cpp/menu_utils.h b/ash/public/cpp/menu_utils.h
new file mode 100644
index 0000000..b56927b6
--- /dev/null
+++ b/ash/public/cpp/menu_utils.h
@@ -0,0 +1,43 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_PUBLIC_CPP_MENU_UTILS_H_
+#define ASH_PUBLIC_CPP_MENU_UTILS_H_
+
+#include <memory>
+#include <vector>
+
+#include "ash/public/cpp/ash_public_export.h"
+#include "ash/public/interfaces/menu.mojom.h"
+#include "ui/base/models/simple_menu_model.h"
+
+namespace ash {
+namespace menu_utils {
+
+using MenuItemList = std::vector<mojom::MenuItemPtr>;
+using SubmenuList = std::vector<std::unique_ptr<ui::MenuModel>>;
+
+// Gets a serialized list of mojo MenuItemPtr objects to transport a menu model.
+// NOTE: This does not support button items, some separator types, sublabels,
+// minor text, dynamic items, label fonts, accelerators, visibility, etc.
+ASH_PUBLIC_EXPORT MenuItemList
+GetMojoMenuItemsFromModel(const ui::MenuModel* model);
+
+// Populates a simple menu model with a list of mojo menu items. This can be
+// considered as an inverse operation of |GetMojoMenuItemsFromModel|.
+ASH_PUBLIC_EXPORT void PopulateMenuFromMojoMenuItems(
+    ui::SimpleMenuModel* model,
+    ui::SimpleMenuModel::Delegate* delegate,
+    const MenuItemList& items,
+    SubmenuList* submenus);
+
+// Finds a menu item by command id; returns a stub item if no match was found.
+ASH_PUBLIC_EXPORT const mojom::MenuItemPtr& GetMenuItemByCommandId(
+    const MenuItemList& items,
+    int command_id);
+
+}  // namespace menu_utils
+}  // namespace ash
+
+#endif  // ASH_PUBLIC_CPP_MENU_UTILS_H_
diff --git a/ash/public/cpp/menu_utils_unittest.cc b/ash/public/cpp/menu_utils_unittest.cc
new file mode 100644
index 0000000..c818536
--- /dev/null
+++ b/ash/public/cpp/menu_utils_unittest.cc
@@ -0,0 +1,159 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/public/cpp/menu_utils.h"
+
+#include <utility>
+
+#include "base/logging.h"
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/models/menu_model.h"
+#include "ui/base/models/menu_separator_types.h"
+#include "ui/base/models/simple_menu_model.h"
+
+using base::ASCIIToUTF16;
+
+namespace ash {
+namespace menu_utils {
+
+using MenuModelList = std::vector<std::unique_ptr<ui::SimpleMenuModel>>;
+
+class MenuUtilsTest : public testing::Test,
+                      public ui::SimpleMenuModel::Delegate {
+ public:
+  MenuUtilsTest() {}
+  ~MenuUtilsTest() override {}
+
+  // testing::Test overrides:
+  void SetUp() override {
+    menu_model_ = std::make_unique<ui::SimpleMenuModel>(this);
+  }
+
+ protected:
+  ui::SimpleMenuModel* root_menu() { return menu_model_.get(); }
+  MenuModelList* submenus() { return &submenu_models_; }
+
+  ui::SimpleMenuModel* CreateSubmenu() {
+    std::unique_ptr<ui::SimpleMenuModel> submenu =
+        std::make_unique<ui::SimpleMenuModel>(this);
+    ui::SimpleMenuModel* submenu_ptr = submenu.get();
+    submenu_models_.push_back(std::move(submenu));
+    return submenu_ptr;
+  }
+
+  bool IsCommandIdChecked(int command_id) const override {
+    // Assume that we have a checked item in every 3 items.
+    return command_id % 3 == 0;
+  }
+
+  bool IsCommandIdEnabled(int command_id) const override {
+    // Assume that we have a enabled item in every 4 items.
+    return command_id % 4 == 0;
+  }
+
+  void ExecuteCommand(int command_id, int event_flags) override {}
+
+  void CheckMenuItemsMatched(const MenuItemList& mojo_menu,
+                             const ui::MenuModel* menu) {
+    EXPECT_EQ(mojo_menu.size(), static_cast<size_t>(menu->GetItemCount()));
+    for (size_t i = 0; i < mojo_menu.size(); i++) {
+      VLOG(1) << "Checking item at " << i;
+      mojom::MenuItem* mojo_item = mojo_menu[i].get();
+      EXPECT_EQ(mojo_item->type, menu->GetTypeAt(i));
+      EXPECT_EQ(mojo_item->command_id, menu->GetCommandIdAt(i));
+      EXPECT_EQ(mojo_item->label, menu->GetLabelAt(i));
+      if (mojo_item->type == ui::MenuModel::TYPE_SUBMENU) {
+        VLOG(1) << "It's a submenu, let's do a recursion.";
+        CheckMenuItemsMatched(mojo_item->submenu.value(),
+                              menu->GetSubmenuModelAt(i));
+        continue;
+      }
+      EXPECT_EQ(mojo_item->enabled, menu->IsEnabledAt(i));
+      EXPECT_EQ(mojo_item->checked, menu->IsItemCheckedAt(i));
+      EXPECT_EQ(mojo_item->radio_group_id, menu->GetGroupIdAt(i));
+    }
+  }
+
+ private:
+  std::unique_ptr<ui::SimpleMenuModel> menu_model_;
+  MenuModelList submenu_models_;
+
+  DISALLOW_COPY_AND_ASSIGN(MenuUtilsTest);
+};
+
+TEST_F(MenuUtilsTest, Basic) {
+  ui::SimpleMenuModel* menu = root_menu();
+
+  // Populates items into |menu| for testing.
+  int command_id = 0;
+  menu->AddItem(command_id++, ASCIIToUTF16("Item0"));
+  menu->AddItem(command_id++, ASCIIToUTF16("Item1"));
+  menu->AddSeparator(ui::NORMAL_SEPARATOR);
+  menu->AddCheckItem(command_id++, ASCIIToUTF16("CheckItem0"));
+  menu->AddCheckItem(command_id++, ASCIIToUTF16("CheckItem1"));
+  menu->AddRadioItem(command_id++, ASCIIToUTF16("RadioItem0"),
+                     0 /* group_id */);
+  menu->AddRadioItem(command_id++, ASCIIToUTF16("RadioItem1"),
+                     0 /* group_id */);
+  // Creates a submenu.
+  ui::SimpleMenuModel* submenu = CreateSubmenu();
+  submenu->AddItem(command_id++, ASCIIToUTF16("SubMenu-Item0"));
+  submenu->AddItem(command_id++, ASCIIToUTF16("SubMenu-Item1"));
+  submenu->AddSeparator(ui::NORMAL_SEPARATOR);
+  submenu->AddCheckItem(command_id++, ASCIIToUTF16("SubMenu-CheckItem0"));
+  submenu->AddCheckItem(command_id++, ASCIIToUTF16("SubMenu-CheckItem1"));
+  submenu->AddRadioItem(command_id++, ASCIIToUTF16("SubMenu-RadioItem0"),
+                        1 /* group_id */);
+  submenu->AddRadioItem(command_id++, ASCIIToUTF16("SubMenu-RadioItem1"),
+                        1 /* group_id */);
+  menu->AddSubMenu(command_id++, ASCIIToUTF16("SubMenu"), submenu);
+
+  // Converts the menu into mojo format.
+  MenuItemList mojo_menu_items = GetMojoMenuItemsFromModel(menu);
+  CheckMenuItemsMatched(mojo_menu_items, menu);
+
+  // Converts backwards.
+  ui::SimpleMenuModel new_menu(this);
+  SubmenuList new_submenus;
+  PopulateMenuFromMojoMenuItems(&new_menu, this, mojo_menu_items,
+                                &new_submenus);
+  CheckMenuItemsMatched(mojo_menu_items, &new_menu);
+
+  // Tests |GetMenuItemByCommandId|.
+  for (int command_to_find = 0; command_to_find < command_id;
+       command_to_find++) {
+    // Gets the mojo item.
+    const mojom::MenuItemPtr& mojo_item =
+        GetMenuItemByCommandId(mojo_menu_items, command_to_find);
+
+    // Gets the item index with this command from the original root menu.
+    int index = menu->GetIndexOfCommandId(command_to_find);
+    ui::MenuModel* menu_to_find = menu;
+    if (index < 0) {
+      // We cannot find it from the original root menu. Then it should be in the
+      // submenu.
+      index = submenu->GetIndexOfCommandId(command_to_find);
+      EXPECT_LE(0, index);
+      menu_to_find = submenu;
+    }
+    // Checks whether they match.
+    EXPECT_EQ(mojo_item->type, menu_to_find->GetTypeAt(index));
+    EXPECT_EQ(mojo_item->command_id, menu_to_find->GetCommandIdAt(index));
+    EXPECT_EQ(mojo_item->label, menu_to_find->GetLabelAt(index));
+    EXPECT_EQ(mojo_item->enabled, menu_to_find->IsEnabledAt(index));
+    EXPECT_EQ(mojo_item->checked, menu_to_find->IsItemCheckedAt(index));
+    EXPECT_EQ(mojo_item->radio_group_id, menu_to_find->GetGroupIdAt(index));
+  }
+
+  // For unknown command ids, we'll get a singleton stub item.
+  const mojom::MenuItemPtr& item_not_found_1 =
+      GetMenuItemByCommandId(mojo_menu_items, command_id + 1);
+  const mojom::MenuItemPtr& item_not_found_2 =
+      GetMenuItemByCommandId(mojo_menu_items, command_id + 2);
+  EXPECT_EQ(item_not_found_1.get(), item_not_found_2.get());
+}
+
+}  // namespace menu_utils
+}  // namespace ash
diff --git a/ash/public/cpp/shelf_item_delegate.cc b/ash/public/cpp/shelf_item_delegate.cc
index 9a4e2da..02338ce 100644
--- a/ash/public/cpp/shelf_item_delegate.cc
+++ b/ash/public/cpp/shelf_item_delegate.cc
@@ -4,37 +4,14 @@
 
 #include "ash/public/cpp/shelf_item_delegate.h"
 
+#include <memory>
+#include <utility>
+
+#include "ash/public/cpp/menu_utils.h"
 #include "ui/base/models/menu_model.h"
 
 namespace ash {
 
-namespace {
-
-// Get a serialized list of mojo MenuItemPtr objects to transport a menu model.
-// NOTE: This does not support button items, some separator types, sublabels,
-// minor text, dynamic items, label fonts, accelerators, visibility, etc.
-MenuItemList GetMenuItemsForMojo(ui::MenuModel* model) {
-  MenuItemList items;
-  if (!model)
-    return items;
-  for (int i = 0; i < model->GetItemCount(); ++i) {
-    mojom::MenuItemPtr item(mojom::MenuItem::New());
-    DCHECK_NE(ui::MenuModel::TYPE_BUTTON_ITEM, model->GetTypeAt(i));
-    item->type = model->GetTypeAt(i);
-    item->command_id = model->GetCommandIdAt(i);
-    item->label = model->GetLabelAt(i);
-    item->checked = model->IsItemCheckedAt(i);
-    item->enabled = model->IsEnabledAt(i);
-    item->radio_group_id = model->GetGroupIdAt(i);
-    if (item->type == ui::MenuModel::TYPE_SUBMENU)
-      item->submenu = GetMenuItemsForMojo(model->GetSubmenuModelAt(i));
-    items.push_back(std::move(item));
-  }
-  return items;
-}
-
-}  // namespace
-
 ShelfItemDelegate::ShelfItemDelegate(const ShelfID& shelf_id)
     : shelf_id_(shelf_id), binding_(this), image_set_by_controller_(false) {}
 
@@ -78,7 +55,8 @@
     int64_t display_id,
     GetContextMenuItemsCallback callback) {
   context_menu_ = GetContextMenu(display_id);
-  std::move(callback).Run(GetMenuItemsForMojo(context_menu_.get()));
+  std::move(callback).Run(
+      menu_utils::GetMojoMenuItemsFromModel(context_menu_.get()));
 }
 
 }  // namespace ash
diff --git a/ash/public/cpp/shelf_struct_traits.cc b/ash/public/cpp/shelf_struct_mojom_traits.cc
similarity index 89%
rename from ash/public/cpp/shelf_struct_traits.cc
rename to ash/public/cpp/shelf_struct_mojom_traits.cc
index a7b9e29..c7a7be1 100644
--- a/ash/public/cpp/shelf_struct_traits.cc
+++ b/ash/public/cpp/shelf_struct_mojom_traits.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/public/cpp/shelf_struct_traits.h"
+#include "ash/public/cpp/shelf_struct_mojom_traits.h"
 
 #include "mojo/public/cpp/base/string16_mojom_traits.h"
 #include "ui/gfx/image/mojo/image_skia_struct_traits.h"
@@ -16,7 +16,7 @@
 bool StructTraits<ash::mojom::ShelfIDDataView, ash::ShelfID>::Read(
     ash::mojom::ShelfIDDataView data,
     ash::ShelfID* out) {
-  if (!data.ReadAppId(&out->app_id) ||!data.ReadLaunchId(&out->launch_id))
+  if (!data.ReadAppId(&out->app_id) || !data.ReadLaunchId(&out->launch_id))
     return false;
   // A non-empty launch id requires a non-empty app id.
   return out->launch_id.empty() || !out->app_id.empty();
diff --git a/ash/public/cpp/shelf_struct_traits.h b/ash/public/cpp/shelf_struct_mojom_traits.h
similarity index 79%
rename from ash/public/cpp/shelf_struct_traits.h
rename to ash/public/cpp/shelf_struct_mojom_traits.h
index e4d42f9..c19d19e4 100644
--- a/ash/public/cpp/shelf_struct_traits.h
+++ b/ash/public/cpp/shelf_struct_mojom_traits.h
@@ -2,66 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_PUBLIC_CPP_SHELF_STRUCT_TRAITS_H_
-#define ASH_PUBLIC_CPP_SHELF_STRUCT_TRAITS_H_
+#ifndef ASH_PUBLIC_CPP_SHELF_STRUCT_MOJOM_TRAITS_H_
+#define ASH_PUBLIC_CPP_SHELF_STRUCT_MOJOM_TRAITS_H_
+
+#include <string>
 
 #include "ash/public/cpp/ash_public_export.h"
 #include "ash/public/cpp/shelf_item.h"
 #include "ash/public/cpp/shelf_types.h"
 #include "ash/public/interfaces/shelf.mojom-shared.h"
-#include "ui/base/models/menu_model.h"
 
 using ash::ShelfItem;
 
 namespace mojo {
 
 template <>
-struct EnumTraits<ash::mojom::MenuItemType, ui::MenuModel::ItemType> {
-  static ash::mojom::MenuItemType ToMojom(ui::MenuModel::ItemType input) {
-    switch (input) {
-      case ui::MenuModel::TYPE_COMMAND:
-        return ash::mojom::MenuItemType::COMMAND;
-      case ui::MenuModel::TYPE_CHECK:
-        return ash::mojom::MenuItemType::CHECK;
-      case ui::MenuModel::TYPE_RADIO:
-        return ash::mojom::MenuItemType::RADIO;
-      case ui::MenuModel::TYPE_SEPARATOR:
-        return ash::mojom::MenuItemType::SEPARATOR;
-      case ui::MenuModel::TYPE_BUTTON_ITEM:
-        NOTREACHED() << "TYPE_BUTTON_ITEM is not yet supported.";
-        return ash::mojom::MenuItemType::COMMAND;
-      case ui::MenuModel::TYPE_SUBMENU:
-        return ash::mojom::MenuItemType::SUBMENU;
-    }
-    NOTREACHED();
-    return ash::mojom::MenuItemType::COMMAND;
-  }
-
-  static bool FromMojom(ash::mojom::MenuItemType input,
-                        ui::MenuModel::ItemType* out) {
-    switch (input) {
-      case ash::mojom::MenuItemType::COMMAND:
-        *out = ui::MenuModel::TYPE_COMMAND;
-        return true;
-      case ash::mojom::MenuItemType::CHECK:
-        *out = ui::MenuModel::TYPE_CHECK;
-        return true;
-      case ash::mojom::MenuItemType::RADIO:
-        *out = ui::MenuModel::TYPE_RADIO;
-        return true;
-      case ash::mojom::MenuItemType::SEPARATOR:
-        *out = ui::MenuModel::TYPE_SEPARATOR;
-        return true;
-      case ash::mojom::MenuItemType::SUBMENU:
-        *out = ui::MenuModel::TYPE_SUBMENU;
-        return true;
-    }
-    NOTREACHED();
-    return false;
-  }
-};
-
-template <>
 struct EnumTraits<ash::mojom::ShelfAction, ash::ShelfAction> {
   static ash::mojom::ShelfAction ToMojom(ash::ShelfAction input) {
     switch (input) {
@@ -255,4 +210,4 @@
 
 }  // namespace mojo
 
-#endif  // ASH_PUBLIC_CPP_SHELF_STRUCT_TRAITS_H_
+#endif  // ASH_PUBLIC_CPP_SHELF_STRUCT_MOJOM_TRAITS_H_
diff --git a/ash/public/cpp/shelf_struct_traits_unittest.cc b/ash/public/cpp/shelf_struct_mojom_traits_unittest.cc
similarity index 97%
rename from ash/public/cpp/shelf_struct_traits_unittest.cc
rename to ash/public/cpp/shelf_struct_mojom_traits_unittest.cc
index 375b5a5e..e9eae2fc 100644
--- a/ash/public/cpp/shelf_struct_traits_unittest.cc
+++ b/ash/public/cpp/shelf_struct_mojom_traits_unittest.cc
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/public/cpp/shelf_struct_traits.h"
+#include "ash/public/cpp/shelf_struct_mojom_traits.h"
+
+#include <utility>
 
 #include "ash/public/cpp/shelf_item.h"
 #include "ash/public/cpp/shelf_struct_traits_test_service.mojom.h"
diff --git a/ash/public/cpp/vector_icons/BUILD.gn b/ash/public/cpp/vector_icons/BUILD.gn
new file mode 100644
index 0000000..f90c009
--- /dev/null
+++ b/ash/public/cpp/vector_icons/BUILD.gn
@@ -0,0 +1,36 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//components/vector_icons/vector_icons.gni")
+
+# The icons in this target, unlike those in //ash/resources/vector_icons, are ok to use from outside of ash/.
+aggregate_vector_icons("ash_public_vector_icons") {
+  icon_directory = "."
+
+  icons = [
+    "window_control_left_snapped.1x.icon",
+    "window_control_left_snapped.icon",
+    "window_control_right_snapped.1x.icon",
+    "window_control_right_snapped.icon",
+    "window_control_close.1x.icon",
+    "window_control_close.icon",
+    "window_control_maximize.1x.icon",
+    "window_control_maximize.icon",
+    "window_control_minimize.1x.icon",
+    "window_control_minimize.icon",
+    "window_control_restore.1x.icon",
+    "window_control_restore.icon",
+  ]
+}
+
+source_set("vector_icons") {
+  sources = get_target_outputs(":ash_public_vector_icons")
+
+  deps = [
+    ":ash_public_vector_icons",
+    "//base",
+    "//skia",
+    "//ui/gfx",
+  ]
+}
diff --git a/ash/public/cpp/vector_icons/vector_icons.cc.template b/ash/public/cpp/vector_icons/vector_icons.cc.template
new file mode 100644
index 0000000..49936d3
--- /dev/null
+++ b/ash/public/cpp/vector_icons/vector_icons.cc.template
@@ -0,0 +1,25 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// vector_icons.cc.template is used to generate vector_icons.cc. Edit the former
+// rather than the latter.
+
+#include "ash/public/cpp/vector_icons/vector_icons.h"
+
+#include "base/logging.h"
+#include "ui/gfx/vector_icon_types.h"
+
+#define PATH_ELEMENT_TEMPLATE(path_name, ...) \
+static constexpr gfx::PathElement path_name[] = {__VA_ARGS__};
+
+#define VECTOR_ICON_TEMPLATE(icon_name, path_name, path_name_1x) \
+const gfx::VectorIcon icon_name = { path_name , path_name_1x };
+
+namespace ash {
+
+using namespace gfx;
+
+TEMPLATE_PLACEHOLDER
+
+}  // namespace ash
diff --git a/ash/public/cpp/vector_icons/vector_icons.h.template b/ash/public/cpp/vector_icons/vector_icons.h.template
new file mode 100644
index 0000000..7e4c2c96
--- /dev/null
+++ b/ash/public/cpp/vector_icons/vector_icons.h.template
@@ -0,0 +1,26 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// vector_icons.h.template is used to generate vector_icons.h. Edit the former
+// rather than the latter.
+
+#ifndef ASH_PUBLIC_CPP_VECTOR_ICONS_VECTOR_ICONS_H_
+#define ASH_PUBLIC_CPP_VECTOR_ICONS_VECTOR_ICONS_H_
+
+namespace gfx {
+struct VectorIcon;
+}
+
+#define VECTOR_ICON_TEMPLATE_H(icon_name) \
+extern const gfx::VectorIcon icon_name;
+
+namespace ash {
+
+TEMPLATE_PLACEHOLDER
+
+}  // namespace ash
+
+#undef VECTOR_ICON_TEMPLATE_H
+
+#endif  // ASH_PUBLIC_CPP_VECTOR_ICONS_VECTOR_ICONS_H_
diff --git a/ash/resources/vector_icons/window_control_close.1x.icon b/ash/public/cpp/vector_icons/window_control_close.1x.icon
similarity index 100%
rename from ash/resources/vector_icons/window_control_close.1x.icon
rename to ash/public/cpp/vector_icons/window_control_close.1x.icon
diff --git a/ash/resources/vector_icons/window_control_close.icon b/ash/public/cpp/vector_icons/window_control_close.icon
similarity index 100%
rename from ash/resources/vector_icons/window_control_close.icon
rename to ash/public/cpp/vector_icons/window_control_close.icon
diff --git a/ash/resources/vector_icons/window_control_left_snapped.1x.icon b/ash/public/cpp/vector_icons/window_control_left_snapped.1x.icon
similarity index 100%
rename from ash/resources/vector_icons/window_control_left_snapped.1x.icon
rename to ash/public/cpp/vector_icons/window_control_left_snapped.1x.icon
diff --git a/ash/resources/vector_icons/window_control_left_snapped.icon b/ash/public/cpp/vector_icons/window_control_left_snapped.icon
similarity index 100%
rename from ash/resources/vector_icons/window_control_left_snapped.icon
rename to ash/public/cpp/vector_icons/window_control_left_snapped.icon
diff --git a/ash/resources/vector_icons/window_control_maximize.1x.icon b/ash/public/cpp/vector_icons/window_control_maximize.1x.icon
similarity index 100%
rename from ash/resources/vector_icons/window_control_maximize.1x.icon
rename to ash/public/cpp/vector_icons/window_control_maximize.1x.icon
diff --git a/ash/resources/vector_icons/window_control_maximize.icon b/ash/public/cpp/vector_icons/window_control_maximize.icon
similarity index 100%
rename from ash/resources/vector_icons/window_control_maximize.icon
rename to ash/public/cpp/vector_icons/window_control_maximize.icon
diff --git a/ash/resources/vector_icons/window_control_minimize.1x.icon b/ash/public/cpp/vector_icons/window_control_minimize.1x.icon
similarity index 100%
rename from ash/resources/vector_icons/window_control_minimize.1x.icon
rename to ash/public/cpp/vector_icons/window_control_minimize.1x.icon
diff --git a/ash/resources/vector_icons/window_control_minimize.icon b/ash/public/cpp/vector_icons/window_control_minimize.icon
similarity index 100%
rename from ash/resources/vector_icons/window_control_minimize.icon
rename to ash/public/cpp/vector_icons/window_control_minimize.icon
diff --git a/ash/resources/vector_icons/window_control_restore.1x.icon b/ash/public/cpp/vector_icons/window_control_restore.1x.icon
similarity index 100%
rename from ash/resources/vector_icons/window_control_restore.1x.icon
rename to ash/public/cpp/vector_icons/window_control_restore.1x.icon
diff --git a/ash/resources/vector_icons/window_control_restore.icon b/ash/public/cpp/vector_icons/window_control_restore.icon
similarity index 100%
rename from ash/resources/vector_icons/window_control_restore.icon
rename to ash/public/cpp/vector_icons/window_control_restore.icon
diff --git a/ash/resources/vector_icons/window_control_right_snapped.1x.icon b/ash/public/cpp/vector_icons/window_control_right_snapped.1x.icon
similarity index 100%
rename from ash/resources/vector_icons/window_control_right_snapped.1x.icon
rename to ash/public/cpp/vector_icons/window_control_right_snapped.1x.icon
diff --git a/ash/resources/vector_icons/window_control_right_snapped.icon b/ash/public/cpp/vector_icons/window_control_right_snapped.icon
similarity index 100%
rename from ash/resources/vector_icons/window_control_right_snapped.icon
rename to ash/public/cpp/vector_icons/window_control_right_snapped.icon
diff --git a/ash/public/interfaces/BUILD.gn b/ash/public/interfaces/BUILD.gn
index c53489f..473ee8a 100644
--- a/ash/public/interfaces/BUILD.gn
+++ b/ash/public/interfaces/BUILD.gn
@@ -19,6 +19,7 @@
     "ash_message_center_controller.mojom",
     "cast_config.mojom",
     "constants.mojom",
+    "docked_magnifier_controller.mojom",
     "event_properties.mojom",
     "highlighter_controller.mojom",
     "ime_controller.mojom",
@@ -27,6 +28,7 @@
     "login_screen.mojom",
     "login_user_info.mojom",
     "media.mojom",
+    "menu.mojom",
     "new_window.mojom",
     "night_light_controller.mojom",
     "note_taking_controller.mojom",
diff --git a/ash/public/interfaces/docked_magnifier_controller.mojom b/ash/public/interfaces/docked_magnifier_controller.mojom
new file mode 100644
index 0000000..c347ce6ca
--- /dev/null
+++ b/ash/public/interfaces/docked_magnifier_controller.mojom
@@ -0,0 +1,29 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module ash.mojom;
+
+import "ui/gfx/geometry/mojo/geometry.mojom";
+
+// Used by a client (e.g. Chrome) to notify ash of focus change events of nodes
+// in webpages.
+interface DockedMagnifierController {
+  // Sets the client that will be notified with status changes of the Docked
+  // Magnifier.
+  SetClient(DockedMagnifierClient client);
+
+  // Requests that the Docked Magnifier centers its viewport around this given
+  // screen point. This can be used by a client (e.g. Chrome) to notify ash of
+  // focus change events in e.g. webpages. Note that ash observes the focus
+  // change events of the text input carets in editable nodes by itself.
+  CenterOnPoint(gfx.mojom.Point point_in_screen);
+};
+
+// Used by ash to notify a client (e.g. Chrome) of changes in the Docked
+// Magnifier enabled status. This relieves clients from observing changes in the
+// active user profile and the associated prefs.
+interface DockedMagnifierClient {
+  // Notifies the client with the new enabled status of the Docked Magnifier.
+  OnEnabledStatusChanged(bool enabled);
+};
\ No newline at end of file
diff --git a/ash/public/interfaces/menu.mojom b/ash/public/interfaces/menu.mojom
new file mode 100644
index 0000000..2986328f
--- /dev/null
+++ b/ash/public/interfaces/menu.mojom
@@ -0,0 +1,31 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module ash.mojom;
+
+import "mojo/public/mojom/base/string16.mojom";
+import "ui/gfx/image/mojo/image.mojom";
+
+// The types of menu items shown in shelf context and application list menus.
+// These values roughly match ui::MenuModel::ItemType (sans TYPE_BUTTON_ITEM).
+enum MenuItemType {
+  COMMAND,    // An item that performs an action when selected.
+  CHECK,      // An item that can be selected/checked to toggle a boolean state.
+  RADIO,      // An item that can be selected/checked among a group of choices.
+  SEPARATOR,  // An item that shows a horizontal line separator.
+  SUBMENU,    // An item that presents a submenu within another menu.
+};
+
+// MenuItems are used to populate application menus for shelf items.
+// Note: Some menus only support a subset of these item features (eg. no icons).
+struct MenuItem {
+  MenuItemType type;               // The type of the menu item.
+  int32 command_id;                // The client's arbitrary item command id.
+  mojo_base.mojom.String16 label;  // The string label, may be empty.
+  gfx.mojom.ImageSkia? image;      // The image icon, may be null.
+  array<MenuItem>? submenu;        // The optional nested submenu item list.
+  bool enabled;                    // The enabled state.
+  bool checked;                    // The checked state.
+  int64 radio_group_id;            // The radio group id.
+};
diff --git a/ash/public/interfaces/menu.typemap b/ash/public/interfaces/menu.typemap
new file mode 100644
index 0000000..bcb14015
--- /dev/null
+++ b/ash/public/interfaces/menu.typemap
@@ -0,0 +1,13 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+mojom = "//ash/public/interfaces/menu.mojom"
+public_headers = [ "//ui/base/models/menu_model.h" ]
+traits_headers = [ "//ash/public/cpp/menu_struct_mojom_traits.h" ]
+public_deps = [
+  "//mojo/common:common_custom_types",
+  "//ui/base",
+  "//ui/gfx/image/mojo:struct_traits",
+]
+type_mappings = [ "ash.mojom.MenuItemType=ui::MenuModel::ItemType" ]
diff --git a/ash/public/interfaces/shelf.mojom b/ash/public/interfaces/shelf.mojom
index a897dbf6..a8b4f05 100644
--- a/ash/public/interfaces/shelf.mojom
+++ b/ash/public/interfaces/shelf.mojom
@@ -4,20 +4,11 @@
 
 module ash.mojom;
 
+import "ash/public/interfaces/menu.mojom";
 import "mojo/public/mojom/base/string16.mojom";
 import "ui/events/mojo/event.mojom";
 import "ui/gfx/image/mojo/image.mojom";
 
-// The types of menu items shown in shelf context and application list menus.
-// These values roughly match ui::MenuModel::ItemType (sans TYPE_BUTTON_ITEM).
-enum MenuItemType {
-  COMMAND,    // An item that performs an action when selected.
-  CHECK,      // An item that can be selected/checked to toggle a boolean state.
-  RADIO,      // An item that can be selected/checked among a group of choices.
-  SEPARATOR,  // An item that shows a horizontal line separator.
-  SUBMENU,    // An item that presents a submenu within another menu.
-};
-
 // The actions that may be performed when a shelf item is selected.
 // These values match ash::ShelfAction.
 enum ShelfAction {
@@ -132,19 +123,6 @@
   Close();
 };
 
-// MenuItems are used to populate application menus for shelf items.
-// Note: Some menus only support a subset of these item features (eg. no icons).
-struct MenuItem {
-  MenuItemType type;                 // The type of the menu item.
-  int64 command_id;                  // The client's arbitrary item command id.
-  mojo_base.mojom.String16 label;    // The string label, may be empty.
-  gfx.mojom.ImageSkia? image;        // The image icon, may be null.
-  array<MenuItem>? submenu;          // The optional nested submenu item list.
-  bool enabled;                      // The enabled state.
-  bool checked;                      // The checked state.
-  int64 radio_group_id;              // The radio group id.
-};
-
 // Identifier for shelf items and their windows.
 // This structure matches ash::ShelfID.
 struct ShelfID {
diff --git a/ash/public/interfaces/shelf.typemap b/ash/public/interfaces/shelf.typemap
index 94e8611d..4354fec 100644
--- a/ash/public/interfaces/shelf.typemap
+++ b/ash/public/interfaces/shelf.typemap
@@ -8,17 +8,15 @@
   "//ash/public/cpp/shelf_types.h",
   "//ui/base/models/menu_model.h",
 ]
-traits_headers = [ "//ash/public/cpp/shelf_struct_traits.h" ]
+traits_headers = [ "//ash/public/cpp/shelf_struct_mojom_traits.h" ]
 sources = [
-  "//ash/public/cpp/shelf_struct_traits.cc",
+  "//ash/public/cpp/shelf_struct_mojom_traits.cc",
 ]
 public_deps = [
   "//mojo/common:common_custom_types",
-  "//ui/base",
   "//ui/gfx/image/mojo:struct_traits",
 ]
 type_mappings = [
-  "ash.mojom.MenuItemType=ui::MenuModel::ItemType",
   "ash.mojom.ShelfAction=ash::ShelfAction",
   "ash.mojom.ShelfAlignment=ash::ShelfAlignment",
   "ash.mojom.ShelfAutoHideBehavior=ash::ShelfAutoHideBehavior",
diff --git a/ash/public/interfaces/typemaps.gni b/ash/public/interfaces/typemaps.gni
index 41476e5..b02bb8a 100644
--- a/ash/public/interfaces/typemaps.gni
+++ b/ash/public/interfaces/typemaps.gni
@@ -4,6 +4,7 @@
 
 typemaps = [
   "//ash/public/interfaces/app_list.typemap",
+  "//ash/public/interfaces/menu.typemap",
   "//ash/public/interfaces/session_controller.typemap",
   "//ash/public/interfaces/shelf.typemap",
   "//ash/public/interfaces/user_info.typemap",
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn
index cba89a4..4ce83fe 100644
--- a/ash/resources/vector_icons/BUILD.gn
+++ b/ash/resources/vector_icons/BUILD.gn
@@ -96,6 +96,7 @@
     "notification_stylus_battery_warning.icon",
     "notification_supervised.icon",
     "notification_timer.icon",
+    "overview_text_filter_search.icon",
     "overview_window_close.icon",
     "palette_action_capture_region.1x.icon",
     "palette_action_capture_region.icon",
@@ -292,18 +293,6 @@
     "tray_action_new_lock_screen_note.icon",
     "window_control_back.1x.icon",
     "window_control_back.icon",
-    "window_control_close.1x.icon",
-    "window_control_close.icon",
-    "window_control_left_snapped.1x.icon",
-    "window_control_left_snapped.icon",
-    "window_control_maximize.1x.icon",
-    "window_control_maximize.icon",
-    "window_control_minimize.1x.icon",
-    "window_control_minimize.icon",
-    "window_control_restore.1x.icon",
-    "window_control_restore.icon",
-    "window_control_right_snapped.1x.icon",
-    "window_control_right_snapped.icon",
   ]
 
   if (is_chrome_branded) {
diff --git a/ash/resources/vector_icons/overview_text_filter_search.icon b/ash/resources/vector_icons/overview_text_filter_search.icon
new file mode 100644
index 0000000..60f612d
--- /dev/null
+++ b/ash/resources/vector_icons/overview_text_filter_search.icon
@@ -0,0 +1,24 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+CANVAS_DIMENSIONS, 20,
+MOVE_TO, 13.01f, 11.81f,
+R_H_LINE_TO, -0.63f,
+R_LINE_TO, -0.22f, -0.22f,
+R_ARC_TO, 5.18f, 5.18f, 0, 0, 0, 1.26f, -3.39f,
+R_ARC_TO, 5.2f, 5.2f, 0, 1, 0, -5.2f, 5.2f,
+R_ARC_TO, 5.18f, 5.18f, 0, 0, 0, 3.39f, -1.26f,
+R_LINE_TO, 0.22f, 0.22f,
+R_V_LINE_TO, 0.63f,
+LINE_TO, 15.81f, 17,
+LINE_TO, 17, 15.81f,
+R_LINE_TO, -3.99f, -4,
+CLOSE,
+R_MOVE_TO, -4.8f, 0,
+R_ARC_TO, 3.6f, 3.6f, 0, 0, 1, -3.6f, -3.6f,
+R_ARC_TO, 3.6f, 3.6f, 0, 0, 1, 3.6f, -3.6f,
+R_ARC_TO, 3.6f, 3.6f, 0, 0, 1, 3.6f, 3.6f,
+R_ARC_TO, 3.6f, 3.6f, 0, 0, 1, -3.6f, 3.6f,
+CLOSE,
+END
diff --git a/ash/shelf/shelf_context_menu_model.cc b/ash/shelf/shelf_context_menu_model.cc
index f5f2bee..f24f777 100644
--- a/ash/shelf/shelf_context_menu_model.cc
+++ b/ash/shelf/shelf_context_menu_model.cc
@@ -6,8 +6,10 @@
 
 #include <memory>
 #include <string>
+#include <utility>
 
 #include "ash/public/cpp/ash_pref_names.h"
+#include "ash/public/cpp/menu_utils.h"
 #include "ash/public/cpp/shelf_item_delegate.h"
 #include "ash/public/cpp/shelf_prefs.h"
 #include "ash/public/cpp/shelf_types.h"
@@ -30,39 +32,6 @@
 
 namespace {
 
-// Find a menu item by command id; returns a stub item if no match was found.
-const mojom::MenuItemPtr& GetItem(const MenuItemList& items, int command_id) {
-  const uint32_t id = base::checked_cast<uint32_t>(command_id);
-  static const mojom::MenuItemPtr item_not_found(mojom::MenuItem::New());
-  for (const mojom::MenuItemPtr& item : items) {
-    if (item->command_id == id)
-      return item;
-    if (item->type == ui::MenuModel::TYPE_SUBMENU &&
-        item->submenu.has_value()) {
-      const mojom::MenuItemPtr& submenu_item =
-          GetItem(item->submenu.value(), command_id);
-      if (submenu_item->command_id == id)
-        return submenu_item;
-    }
-  }
-  return item_not_found;
-}
-
-// A shelf context submenu model; used for shelf alignment.
-class ShelfContextSubMenuModel : public ui::SimpleMenuModel {
- public:
-  ShelfContextSubMenuModel(Delegate* delegate,
-                           const MenuItemList& items,
-                           SubmenuList* submenus)
-      : ui::SimpleMenuModel(delegate) {
-    ShelfContextMenuModel::AddItems(this, delegate, items, submenus);
-  }
-  ~ShelfContextSubMenuModel() override = default;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ShelfContextSubMenuModel);
-};
-
 // Returns true if the user can modify the shelf's auto-hide behavior pref.
 bool CanUserModifyShelfAutoHide(PrefService* prefs) {
   return prefs && prefs->FindPreference(prefs::kShelfAutoHideBehaviorLocal)
@@ -161,57 +130,18 @@
       display_id_(display_id) {
   // Append some menu items that are handled locally by Ash.
   AddLocalMenuItems(&menu_items_, display_id);
-  AddItems(this, this, menu_items_, &submenus_);
+  menu_utils::PopulateMenuFromMojoMenuItems(this, this, menu_items_,
+                                            &submenus_);
 }
 
 ShelfContextMenuModel::~ShelfContextMenuModel() = default;
 
-// static
-void ShelfContextMenuModel::AddItems(ui::SimpleMenuModel* model,
-                                     ui::SimpleMenuModel::Delegate* delegate,
-                                     const MenuItemList& items,
-                                     SubmenuList* submenus) {
-  for (const mojom::MenuItemPtr& item : items) {
-    switch (item->type) {
-      case ui::MenuModel::TYPE_COMMAND:
-        model->AddItem(item->command_id, item->label);
-        break;
-      case ui::MenuModel::TYPE_CHECK:
-        model->AddCheckItem(item->command_id, item->label);
-        break;
-      case ui::MenuModel::TYPE_RADIO:
-        model->AddRadioItem(item->command_id, item->label,
-                            item->radio_group_id);
-        break;
-      case ui::MenuModel::TYPE_SEPARATOR:
-        model->AddSeparator(ui::NORMAL_SEPARATOR);
-        break;
-      case ui::MenuModel::TYPE_BUTTON_ITEM:
-        NOTREACHED() << "TYPE_BUTTON_ITEM is not yet supported.";
-        break;
-      case ui::MenuModel::TYPE_SUBMENU:
-        if (item->submenu.has_value()) {
-          std::unique_ptr<ui::MenuModel> submenu =
-              std::make_unique<ShelfContextSubMenuModel>(
-                  delegate, item->submenu.value(), submenus);
-          model->AddSubMenu(item->command_id, item->label, submenu.get());
-          submenus->push_back(std::move(submenu));
-        }
-        break;
-    }
-    if (!item->image.isNull()) {
-      model->SetIcon(model->GetIndexOfCommandId(item->command_id),
-                     gfx::Image(item->image));
-    }
-  }
-}
-
 bool ShelfContextMenuModel::IsCommandIdChecked(int command_id) const {
-  return GetItem(menu_items_, command_id)->checked;
+  return menu_utils::GetMenuItemByCommandId(menu_items_, command_id)->checked;
 }
 
 bool ShelfContextMenuModel::IsCommandIdEnabled(int command_id) const {
-  return GetItem(menu_items_, command_id)->enabled;
+  return menu_utils::GetMenuItemByCommandId(menu_items_, command_id)->enabled;
 }
 
 void ShelfContextMenuModel::ExecuteCommand(int command_id, int event_flags) {
diff --git a/ash/shelf/shelf_context_menu_model.h b/ash/shelf/shelf_context_menu_model.h
index daba330..64c7f3d 100644
--- a/ash/shelf/shelf_context_menu_model.h
+++ b/ash/shelf/shelf_context_menu_model.h
@@ -45,13 +45,6 @@
                         int64_t display_id);
   ~ShelfContextMenuModel() override;
 
-  // Add the given |items| to |model|, populating |submenus| as needed.
-  // This is defined as static to support use by the submodel helper class.
-  static void AddItems(ui::SimpleMenuModel* model,
-                       ui::SimpleMenuModel::Delegate* delegate,
-                       const std::vector<mojom::MenuItemPtr>& items,
-                       std::vector<std::unique_ptr<ui::MenuModel>>* submenus);
-
   // ui::SimpleMenuModel::Delegate overrides:
   bool IsCommandIdChecked(int command_id) const override;
   bool IsCommandIdEnabled(int command_id) const override;
diff --git a/ash/shell.cc b/ash/shell.cc
index 5820c5a..1dc861e 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -46,6 +46,7 @@
 #include "ash/laser/laser_pointer_controller.h"
 #include "ash/login/login_screen_controller.h"
 #include "ash/login_status.h"
+#include "ash/magnifier/docked_magnifier_controller.h"
 #include "ash/magnifier/magnification_controller.h"
 #include "ash/magnifier/partial_magnification_controller.h"
 #include "ash/media_controller.h"
@@ -379,6 +380,7 @@
 void Shell::RegisterProfilePrefs(PrefRegistrySimple* registry, bool for_test) {
   AccessibilityController::RegisterProfilePrefs(registry, for_test);
   BluetoothPowerController::RegisterProfilePrefs(registry);
+  DockedMagnifierController::RegisterProfilePrefs(registry);
   LoginScreenController::RegisterProfilePrefs(registry, for_test);
   LogoutButtonTray::RegisterProfilePrefs(registry);
   NightLightController::RegisterProfilePrefs(registry);
@@ -453,6 +455,11 @@
       resolution_notification_controller_->DoesNotificationTimeout());
 }
 
+DockedMagnifierController* Shell::docked_magnifier_controller() {
+  DCHECK(switches::IsDockedMagnifierEnabled());
+  return docked_magnifier_controller_.get();
+}
+
 NightLightController* Shell::night_light_controller() {
   DCHECK(switches::IsNightLightEnabled());
   return night_light_controller_.get();
@@ -799,6 +806,8 @@
   // NightLightController depends on the PrefService as well as the window tree
   // host manager, and must be destructed before them. crbug.com/724231.
   night_light_controller_ = nullptr;
+  // Similarly for DockedMagnifierController.
+  docked_magnifier_controller_ = nullptr;
 
   shell_port_->Shutdown();
   window_tree_host_manager_->Shutdown();
@@ -1051,6 +1060,11 @@
 
   high_contrast_controller_.reset(new HighContrastController);
 
+  if (switches::IsDockedMagnifierEnabled()) {
+    docked_magnifier_controller_ =
+        std::make_unique<DockedMagnifierController>();
+  }
+
   viz::mojom::VideoDetectorObserverPtr observer;
   video_detector_ =
       std::make_unique<VideoDetector>(mojo::MakeRequest(&observer));
diff --git a/ash/shell.h b/ash/shell.h
index 5d05712..3665424 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -95,6 +95,7 @@
 class DisplayConfigurationController;
 class DisplayErrorObserver;
 class DisplayShutdownObserver;
+class DockedMagnifierController;
 class DragDropController;
 class EventClientImpl;
 class EventTransformationHandler;
@@ -342,6 +343,7 @@
     return display_error_observer_.get();
   }
 
+  DockedMagnifierController* docked_magnifier_controller();
   ::wm::CompoundEventFilter* env_filter() { return env_filter_.get(); }
   EventClientImpl* event_client() { return event_client_.get(); }
   EventTransformationHandler* event_transformation_handler() {
@@ -770,6 +772,8 @@
       partial_magnification_controller_;
   std::unique_ptr<HighlighterController> highlighter_controller_;
 
+  std::unique_ptr<DockedMagnifierController> docked_magnifier_controller_;
+
   // The split view controller for Chrome OS in tablet mode.
   std::unique_ptr<SplitViewController> split_view_controller_;
 
diff --git a/ash/shell/app_list.cc b/ash/shell/app_list.cc
index 53a4352..75c3f58 100644
--- a/ash/shell/app_list.cc
+++ b/ash/shell/app_list.cc
@@ -276,7 +276,8 @@
     // Nothing needs to be done.
   }
 
-  void GetWallpaperProminentColors(std::vector<SkColor>* colors) override {
+  void GetWallpaperProminentColors(
+      GetWallpaperProminentColorsCallback callback) override {
     NOTIMPLEMENTED();
   }
 
@@ -288,8 +289,15 @@
     item->Activate(event_flags);
   }
 
-  ui::MenuModel* GetContextMenuModel(const std::string& id) override {
-    return nullptr;
+  void GetContextMenuModel(const std::string& id,
+                           GetContextMenuModelCallback callback) override {
+    NOTIMPLEMENTED();
+  }
+
+  void ContextMenuItemSelected(const std::string& id,
+                               int command_id,
+                               int event_flags) override {
+    NOTIMPLEMENTED();
   }
 
   void AddObserver(app_list::AppListViewDelegateObserver* observer) override {
diff --git a/ash/sidebar/sidebar_widget.cc b/ash/sidebar/sidebar_widget.cc
index 5b22f10..e1d06e9 100644
--- a/ash/sidebar/sidebar_widget.cc
+++ b/ash/sidebar/sidebar_widget.cc
@@ -22,7 +22,7 @@
 #include "ui/display/screen.h"
 #include "ui/message_center/message_center.h"
 #include "ui/message_center/message_center_style.h"
-#include "ui/message_center/views/constants.h"
+#include "ui/message_center/public/cpp/message_center_constants.h"
 #include "ui/views/background.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/layout/box_layout.h"
diff --git a/ash/wm/overview/scoped_transform_overview_window.cc b/ash/wm/overview/scoped_transform_overview_window.cc
index 42761c5..b01805c2 100644
--- a/ash/wm/overview/scoped_transform_overview_window.cc
+++ b/ash/wm/overview/scoped_transform_overview_window.cc
@@ -608,64 +608,6 @@
   original_opacity_ = 1.f;
 }
 
-void ScopedTransformOverviewWindow::OnGestureEvent(ui::GestureEvent* event) {
-  if (minimized_widget_ && SplitViewController::ShouldAllowSplitView()) {
-    gfx::Point location(event->location());
-    ::wm::ConvertPointToScreen(minimized_widget_->GetNativeWindow(), &location);
-    switch (event->type()) {
-      case ui::ET_GESTURE_TAP_DOWN:
-        selector_item_->HandlePressEvent(location);
-        break;
-      case ui::ET_GESTURE_SCROLL_UPDATE:
-        selector_item_->HandleDragEvent(location);
-        break;
-      case ui::ET_SCROLL_FLING_START:
-      case ui::ET_GESTURE_SCROLL_END:
-        selector_item_->HandleReleaseEvent(location);
-        break;
-      case ui::ET_GESTURE_TAP:
-        selector_item_->ActivateDraggedWindow();
-        break;
-      case ui::ET_GESTURE_END:
-        selector_item_->ResetDraggedWindowGesture();
-        break;
-      default:
-        break;
-    }
-    event->SetHandled();
-  } else if (event->type() == ui::ET_GESTURE_TAP) {
-    EnsureVisible();
-    window_->Show();
-    wm::ActivateWindow(window_);
-  }
-}
-
-void ScopedTransformOverviewWindow::OnMouseEvent(ui::MouseEvent* event) {
-  if (minimized_widget_ && SplitViewController::ShouldAllowSplitView()) {
-    gfx::Point location(event->location());
-    ::wm::ConvertPointToScreen(minimized_widget_->GetNativeWindow(), &location);
-    switch (event->type()) {
-      case ui::ET_MOUSE_PRESSED:
-        selector_item_->HandlePressEvent(location);
-        break;
-      case ui::ET_MOUSE_DRAGGED:
-        selector_item_->HandleDragEvent(location);
-        break;
-      case ui::ET_MOUSE_RELEASED:
-        selector_item_->HandleReleaseEvent(location);
-        break;
-      default:
-        break;
-    }
-    event->SetHandled();
-  } else if (event->type() == ui::ET_MOUSE_PRESSED &&
-             event->IsOnlyLeftMouseButton()) {
-    EnsureVisible();
-    window_->Show();
-    wm::ActivateWindow(window_);
-  }
-}
-
 void ScopedTransformOverviewWindow::OnImplicitAnimationsCompleted() {
   // Add the mask which gives the window selector items rounded corners.
   ui::Layer* layer = minimized_widget_
@@ -700,7 +642,7 @@
   params.visible_on_all_workspaces = true;
   params.name = "OverviewModeMinimized";
   params.activatable = views::Widget::InitParams::Activatable::ACTIVATABLE_NO;
-  params.accept_events = true;
+  params.accept_events = false;
   params.parent = window_->parent();
   minimized_widget_ = std::make_unique<views::Widget>();
   minimized_widget_->set_focus_on_creation(false);
@@ -711,7 +653,6 @@
   views::View* mirror_view =
       new wm::WindowMirrorView(window_, /*trilinear_filtering_on_init=*/false);
   mirror_view->SetVisible(true);
-  mirror_view->SetTargetHandler(this);
   minimized_widget_->SetContentsView(mirror_view);
   gfx::Rect bounds(window_->GetBoundsInScreen());
   gfx::Size preferred = mirror_view->GetPreferredSize();
diff --git a/ash/wm/overview/scoped_transform_overview_window.h b/ash/wm/overview/scoped_transform_overview_window.h
index 303705f2..63a76e38 100644
--- a/ash/wm/overview/scoped_transform_overview_window.h
+++ b/ash/wm/overview/scoped_transform_overview_window.h
@@ -15,7 +15,6 @@
 #include "base/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/compositor/layer_animation_observer.h"
-#include "ui/events/event_handler.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/transform.h"
@@ -50,8 +49,7 @@
 // fit in certain bounds. The window's state is restored when this object is
 // destroyed.
 class ASH_EXPORT ScopedTransformOverviewWindow
-    : public ui::EventHandler,
-      public ui::ImplicitAnimationObserver {
+    : public ui::ImplicitAnimationObserver {
  public:
   // Overview windows have certain properties if their aspect ratio exceedes a
   // threshold. This enum keeps track of which category the window falls into,
@@ -180,10 +178,6 @@
   // change. Must be called before PositionWindows in WindowGrid.
   void UpdateWindowDimensionsType();
 
-  // ui::EventHandler:
-  void OnGestureEvent(ui::GestureEvent* event) override;
-  void OnMouseEvent(ui::MouseEvent* event) override;
-
   // ui::ImplicitAnimationObserver:
   void OnImplicitAnimationsCompleted() override;
 
diff --git a/ash/wm/overview/window_grid.cc b/ash/wm/overview/window_grid.cc
index d4fb549..9562a4b8 100644
--- a/ash/wm/overview/window_grid.cc
+++ b/ash/wm/overview/window_grid.cc
@@ -685,6 +685,16 @@
     window_selector_item->UpdateCannotSnapWarningVisibility();
 }
 
+void WindowGrid::OnSelectorItemDragStarted(WindowSelectorItem* item) {
+  for (auto& window_selector_item : window_list_)
+    window_selector_item->OnSelectorItemDragStarted(item);
+}
+
+void WindowGrid::OnSelectorItemDragEnded(WindowSelectorItem* item) {
+  for (auto& window_selector_item : window_list_)
+    window_selector_item->OnSelectorItemDragEnded(item);
+}
+
 void WindowGrid::OnWindowDestroying(aura::Window* window) {
   window_observer_.Remove(window);
   window_state_observer_.Remove(wm::GetWindowState(window));
diff --git a/ash/wm/overview/window_grid.h b/ash/wm/overview/window_grid.h
index caae530..0d3a3c07 100644
--- a/ash/wm/overview/window_grid.h
+++ b/ash/wm/overview/window_grid.h
@@ -123,6 +123,11 @@
 
   void UpdateCannotSnapWarningVisibility();
 
+  // Called when any WindowSelectorItem on any WindowGrid has started/ended
+  // being dragged.
+  void OnSelectorItemDragStarted(WindowSelectorItem* item);
+  void OnSelectorItemDragEnded(WindowSelectorItem* item);
+
   // Returns true if the grid has no more windows.
   bool empty() const { return window_list_.empty(); }
 
diff --git a/ash/wm/overview/window_selector.cc b/ash/wm/overview/window_selector.cc
index df04552..f99f436 100644
--- a/ash/wm/overview/window_selector.cc
+++ b/ash/wm/overview/window_selector.cc
@@ -14,6 +14,7 @@
 #include "ash/accessibility/accessibility_controller.h"
 #include "ash/metrics/user_metrics_recorder.h"
 #include "ash/public/cpp/shell_window_ids.h"
+#include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/screen_util.h"
 #include "ash/shelf/shelf.h"
 #include "ash/shell.h"
@@ -36,14 +37,12 @@
 #include "base/metrics/user_metrics.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/vector_icons/vector_icons.h"
-#include "third_party/skia/include/core/SkPath.h"
-#include "ui/base/resource/resource_bundle.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/display/screen.h"
 #include "ui/events/event.h"
-#include "ui/gfx/canvas.h"
 #include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/gfx/skia_util.h"
 #include "ui/views/border.h"
@@ -59,39 +58,45 @@
 namespace {
 
 // The amount of padding surrounding the text in the text filtering textbox.
-const int kTextFilterHorizontalPadding = 10;
+constexpr int kTextFilterHorizontalPadding = 6;
 
 // The height of the text filtering textbox.
-const int kTextFilterHeight = 40;
+constexpr int kTextFilterHeight = 32;
 
 // The margin at the bottom to make sure the text filter layer is hidden.
 // This is needed because positioning the text filter directly touching the top
 // edge of the screen still allows the shadow to peek through.
-const int kTextFieldBottomMargin = 2;
+constexpr int kTextFieldBottomMargin = 2;
 
 // Distance from top of overview to the top of text filtering textbox as a
 // proportion of the total overview area.
-const float kTextFilterTopScreenProportion = 0.02f;
+constexpr float kTextFilterTopScreenProportion = 0.02f;
 
 // Width of the text filter area.
-const int kTextFilterWidth = 280;
+constexpr int kTextFilterWidth = 280;
 
-// The font style used for text filtering textbox.
-static const ui::ResourceBundle::FontStyle kTextFilterFontStyle =
-    ui::ResourceBundle::FontStyle::BaseFont;
+// The font delta used for text filtering textbox.
+constexpr int kTextFilterFontDelta = 1;
 
 // The color of the text and its background in the text filtering textbox.
-const SkColor kTextFilterTextColor = SkColorSetARGB(222, 0, 0, 0);
-const SkColor kTextFilterBackgroundColor = SK_ColorWHITE;
+constexpr SkColor kTextFilterTextColor = SkColorSetARGB(0xFF, 0x3C, 0x40, 0x43);
+constexpr SkColor kTextFilterBackgroundColor = SK_ColorWHITE;
 
 // The color or search icon.
-const SkColor kTextFilterIconColor = SkColorSetARGB(138, 0, 0, 0);
+constexpr SkColor kTextFilterIconColor = SkColorSetARGB(138, 0, 0, 0);
 
 // The size of search icon.
-const int kTextFilterIconSize = 20;
+constexpr int kTextFilterIconSize = 20;
 
 // The radius used for the rounded corners on the text filtering textbox.
-const int kTextFilterCornerRadius = 2;
+constexpr int kTextFilterCornerRadius = 16;
+
+// Values for the old overview ui.
+// TODO(crbug.com/782320): Delete these values when the old ui becomes obsolete.
+constexpr int kOldTextFilterHorizontalPadding = 6;
+constexpr int kOldTextFilterHeight = 40;
+constexpr SkColor kOldTextFilterTextColor = SkColorSetARGB(222, 0, 0, 0);
+constexpr int kOldTextFilterCornerRadius = 2;
 
 // A comparator for locating a selector item for a given root.
 struct WindowSelectorItemForRoot {
@@ -137,7 +142,8 @@
           0.5 * (total_bounds.width() -
                  std::min(kTextFilterWidth, total_bounds.width())),
       total_bounds.y() + total_bounds.height() * kTextFilterTopScreenProportion,
-      std::min(kTextFilterWidth, total_bounds.width()), kTextFilterHeight);
+      std::min(kTextFilterWidth, total_bounds.width()),
+      IsNewOverviewUi() ? kTextFilterHeight : kOldTextFilterHeight);
 }
 
 // Initializes the text filter on the top of the main root window and requests
@@ -161,28 +167,38 @@
 
   // Use |container| to specify the padding surrounding the text and to give
   // the textfield rounded corners.
-  views::View* container =
-      new RoundedRectView(kTextFilterCornerRadius, kTextFilterBackgroundColor);
-  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
-  const int text_height =
-      std::max(kTextFilterIconSize,
-               bundle.GetFontList(kTextFilterFontStyle).GetHeight());
+  views::View* container = new RoundedRectView(
+      IsNewOverviewUi() ? kTextFilterCornerRadius : kOldTextFilterCornerRadius,
+      kTextFilterBackgroundColor);
+  const gfx::FontList& font_list =
+      views::Textfield::GetDefaultFontList().Derive(
+          kTextFilterFontDelta, gfx::Font::FontStyle::NORMAL,
+          gfx::Font::Weight::NORMAL);
+  const int text_height = std::max(kTextFilterIconSize, font_list.GetHeight());
   DCHECK(text_height);
   const int vertical_padding = (params.bounds.height() - text_height) / 2;
   auto* layout = container->SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::kHorizontal,
-      gfx::Insets(vertical_padding, kTextFilterHorizontalPadding),
+      gfx::Insets(vertical_padding,
+                  IsNewOverviewUi() ? kTextFilterHorizontalPadding
+                                    : kOldTextFilterHorizontalPadding,
+                  vertical_padding,
+                  IsNewOverviewUi() ? kTextFilterCornerRadius
+                                    : kOldTextFilterHorizontalPadding),
       kTextFilterHorizontalPadding));
 
-  views::Textfield* textfield = new views::Textfield;
+  views::Textfield* textfield = new views::Textfield();
   textfield->set_controller(controller);
   textfield->SetBorder(views::NullBorder());
   textfield->SetBackgroundColor(kTextFilterBackgroundColor);
-  textfield->SetTextColor(kTextFilterTextColor);
-  views::ImageView* image_view = new views::ImageView;
+  textfield->SetTextColor(IsNewOverviewUi() ? kTextFilterTextColor
+                                            : kOldTextFilterTextColor);
+  textfield->SetFontList(font_list);
+
+  views::ImageView* image_view = new views::ImageView();
   image_view->SetImage(image);
+
   container->AddChildView(image_view);
-  textfield->SetFontList(bundle.GetFontList(kTextFilterFontStyle));
   container->AddChildView(textfield);
   layout->SetFlexForView(textfield, 1);
   widget->SetContentsView(container);
@@ -210,16 +226,7 @@
 WindowSelector::WindowSelector(WindowSelectorDelegate* delegate)
     : delegate_(delegate),
       restore_focus_window_(wm::GetFocusedWindow()),
-      ignore_activations_(false),
-      selected_grid_index_(0),
-      overview_start_time_(base::Time::Now()),
-      num_key_presses_(0),
-      num_items_(0),
-      showing_text_filter_(false),
-      text_filter_string_length_(0),
-      num_times_textfield_cleared_(0),
-      restoring_minimized_windows_(false),
-      text_filter_bottom_(0) {
+      overview_start_time_(base::Time::Now()) {
   DCHECK(delegate_);
 }
 
@@ -299,10 +306,14 @@
       window_grid->PositionWindows(/*animate=*/true);
     }
 
-    search_image_ = gfx::CreateVectorIcon(
-        vector_icons::kSearchIcon, kTextFilterIconSize, kTextFilterIconColor);
+    // Image used for text filter textfield.
+    gfx::ImageSkia search_image =
+        gfx::CreateVectorIcon(IsNewOverviewUi() ? kOverviewTextFilterSearchIcon
+                                                : vector_icons::kSearchIcon,
+                              kTextFilterIconSize, kTextFilterIconColor);
+
     aura::Window* root_window = Shell::GetPrimaryRootWindow();
-    text_filter_widget_.reset(CreateTextFilter(this, root_window, search_image_,
+    text_filter_widget_.reset(CreateTextFilter(this, root_window, search_image,
                                                &text_filter_bottom_));
   }
 
@@ -534,6 +545,12 @@
                                   const gfx::Point& location_in_screen) {
   window_drag_controller_.reset(new OverviewWindowDragController(this));
   window_drag_controller_->InitiateDrag(item, location_in_screen);
+
+  if (!IsNewOverviewUi())
+    return;
+
+  for (std::unique_ptr<WindowGrid>& grid : grid_list_)
+    grid->OnSelectorItemDragStarted(item);
 }
 
 void WindowSelector::Drag(WindowSelectorItem* item,
@@ -548,6 +565,12 @@
   DCHECK(window_drag_controller_.get());
   DCHECK_EQ(item, window_drag_controller_->item());
   window_drag_controller_->CompleteDrag(location_in_screen);
+
+  if (!IsNewOverviewUi())
+    return;
+
+  for (std::unique_ptr<WindowGrid>& grid : grid_list_)
+    grid->OnSelectorItemDragEnded(item);
 }
 
 void WindowSelector::ActivateDraggedWindow() {
diff --git a/ash/wm/overview/window_selector.h b/ash/wm/overview/window_selector.h
index 31dfbcbb..69c1380 100644
--- a/ash/wm/overview/window_selector.h
+++ b/ash/wm/overview/window_selector.h
@@ -19,7 +19,6 @@
 #include "base/time/time.h"
 #include "ui/aura/window_observer.h"
 #include "ui/display/display_observer.h"
-#include "ui/gfx/image/image_skia.h"
 #include "ui/views/controls/textfield/textfield_controller.h"
 #include "ui/wm/public/activation_change_observer.h"
 
@@ -31,7 +30,7 @@
 namespace views {
 class Textfield;
 class Widget;
-}
+}  // namespace views
 
 namespace ash {
 class OverviewWindowDragController;
@@ -210,7 +209,7 @@
 
   // True when performing operations that may cause window activations. This is
   // used to prevent handling the resulting expected activation.
-  bool ignore_activations_;
+  bool ignore_activations_ = false;
 
   // List of all the window overview grids, one for each root window.
   std::vector<std::unique_ptr<WindowGrid>> grid_list_;
@@ -220,7 +219,7 @@
   std::unique_ptr<SplitViewOverviewOverlay> split_view_overview_overlay_;
 
   // Tracks the index of the root window the selection widget is in.
-  size_t selected_grid_index_;
+  size_t selected_grid_index_ = 0;
 
   // The following variables are used for metric collection purposes. All of
   // them refer to this particular overview session and are not cumulative:
@@ -228,36 +227,33 @@
   base::Time overview_start_time_;
 
   // The number of arrow key presses.
-  size_t num_key_presses_;
+  size_t num_key_presses_ = 0;
 
   // The number of items in the overview.
-  size_t num_items_;
+  size_t num_items_ = 0;
 
   // Indicates if the text filter is shown on screen (rather than above it).
-  bool showing_text_filter_;
+  bool showing_text_filter_ = false;
 
   // Window text filter widget. As the user writes on it, we filter the items
   // in the overview. It is also responsible for handling overview key events,
   // such as enter key to select.
   std::unique_ptr<views::Widget> text_filter_widget_;
 
-  // Image used for text filter textfield.
-  gfx::ImageSkia search_image_;
-
   // The current length of the string entered into the text filtering textfield.
-  size_t text_filter_string_length_;
+  size_t text_filter_string_length_ = 0;
 
   // The number of times the text filtering textfield has been cleared of text
   // during this overview mode session.
-  size_t num_times_textfield_cleared_;
+  size_t num_times_textfield_cleared_ = 0;
 
   // Tracks whether minimized windows are currently being restored for overview
   // mode.
-  bool restoring_minimized_windows_;
+  bool restoring_minimized_windows_ = false;
 
   // The distance between the top edge of the screen and the bottom edge of
   // the text filtering textfield.
-  int text_filter_bottom_;
+  int text_filter_bottom_ = 0;
 
   bool is_shut_down_ = false;
 
diff --git a/ash/wm/overview/window_selector_item.cc b/ash/wm/overview/window_selector_item.cc
index 5bdc721..c513544e 100644
--- a/ash/wm/overview/window_selector_item.cc
+++ b/ash/wm/overview/window_selector_item.cc
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "ash/public/cpp/shell_window_ids.h"
+#include "ash/public/cpp/vector_icons/vector_icons.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
@@ -87,7 +88,7 @@
 constexpr int kHeaderHeightDp = 40;
 
 // Opacity for dimmed items.
-constexpr float kDimmedItemOpacity = 0.5f;
+constexpr float kDimmedItemOpacity = 0.3f;
 
 // Opacity for fading out during closing a window.
 constexpr float kClosingItemOpacity = 0.8f;
@@ -105,6 +106,10 @@
 // Duration of background opacity transition when exiting overview mode.
 constexpr int kExitFadeInMilliseconds = 30;
 
+// Duration of the header and close button fade in/out when a drag is
+// started/finished on a window selector item;
+constexpr int kDragAnimationMs = 167;
+
 // Before closing a window animate both the window and the caption to shrink by
 // this fraction of size.
 constexpr float kPreCloseScale = 0.02f;
@@ -494,6 +499,14 @@
 
   ShieldButton* listener_button() { return listener_button_; }
 
+  void SetCloseButtonVisibility(bool visible) {
+    AnimateLayerOpacity(close_button_->layer(), visible);
+  }
+
+  void SetTitleLabelVisibility(bool visible) {
+    AnimateLayerOpacity(background_->layer(), visible);
+  }
+
   void SetCannotSnapLabelVisibility(bool visible) {
     AnimateSplitviewLabelOpacity(cannot_snap_container_->layer(), visible);
   }
@@ -559,6 +572,34 @@
   const char* GetClassName() const override { return "CaptionContainerView"; }
 
  private:
+  // Animates |layer| from 0 -> 1 opacity if |visible| and 1 -> 0 opacity
+  // otherwise. The tween type differs for |visible| and if |visible| is true
+  // there is a slight delay before the animation begins. Does not animate if
+  // opacity matches |visible|.
+  void AnimateLayerOpacity(ui::Layer* layer, bool visible) {
+    float target_opacity = visible ? 1.f : 0.f;
+    if (layer->GetTargetOpacity() == target_opacity)
+      return;
+
+    layer->SetOpacity(1.f - target_opacity);
+    {
+      ui::LayerAnimator* animator = layer->GetAnimator();
+      ui::ScopedLayerAnimationSettings settings(animator);
+      settings.SetPreemptionStrategy(
+          ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
+      if (visible) {
+        animator->SchedulePauseForProperties(
+            base::TimeDelta::FromMilliseconds(kDragAnimationMs),
+            ui::LayerAnimationElement::OPACITY);
+      }
+      settings.SetTransitionDuration(
+          base::TimeDelta::FromMilliseconds(kDragAnimationMs));
+      settings.SetTweenType(visible ? gfx::Tween::LINEAR_OUT_SLOW_IN
+                                    : gfx::Tween::FAST_OUT_LINEAR_IN);
+      layer->SetOpacity(target_opacity);
+    }
+  }
+
   ShieldButton* listener_button_;
   WindowSelectorItem::RoundedContainerView* background_;
   views::ImageView* image_view_;
@@ -709,6 +750,17 @@
   caption_container_view_->SetCannotSnapLabelVisibility(visible);
 }
 
+void WindowSelectorItem::OnSelectorItemDragStarted(WindowSelectorItem* item) {
+  caption_container_view_->SetCloseButtonVisibility(false);
+  if (item == this)
+    caption_container_view_->SetTitleLabelVisibility(false);
+}
+
+void WindowSelectorItem::OnSelectorItemDragEnded(WindowSelectorItem* item) {
+  caption_container_view_->SetCloseButtonVisibility(true);
+  caption_container_view_->SetTitleLabelVisibility(true);
+}
+
 ScopedTransformOverviewWindow::GridWindowFillMode
 WindowSelectorItem::GetWindowDimensionsType() const {
   return transform_window_.type();
@@ -790,6 +842,14 @@
   window_selector_->ResetDraggedWindowGesture();
 }
 
+float WindowSelectorItem::GetCloseButtonOpacityForTesting() {
+  return close_button_->layer()->opacity();
+}
+
+float WindowSelectorItem::GetTitlebarOpacityForTesting() {
+  return background_view_->layer()->opacity();
+}
+
 gfx::Rect WindowSelectorItem::GetTargetBoundsInScreen() const {
   return transform_window_.GetTargetBoundsInScreen();
 }
diff --git a/ash/wm/overview/window_selector_item.h b/ash/wm/overview/window_selector_item.h
index 7cb34b26..d472cc7 100644
--- a/ash/wm/overview/window_selector_item.h
+++ b/ash/wm/overview/window_selector_item.h
@@ -122,6 +122,12 @@
   // window cannot be snapped.
   void UpdateCannotSnapWarningVisibility();
 
+  // Called when a WindowSelectorItem on any grid is dragged. Hides the close
+  // button when a drag is started, and reshows it when a drag is finished.
+  // Additional hides the title and window icon if |item| is this.
+  void OnSelectorItemDragStarted(WindowSelectorItem* item);
+  void OnSelectorItemDragEnded(WindowSelectorItem* item);
+
   ScopedTransformOverviewWindow::GridWindowFillMode GetWindowDimensionsType()
       const;
 
@@ -150,6 +156,9 @@
   void ActivateDraggedWindow();
   void ResetDraggedWindowGesture();
 
+  float GetCloseButtonOpacityForTesting();
+  float GetTitlebarOpacityForTesting();
+
  private:
   class CaptionContainerView;
   class RoundedContainerView;
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc
index 673ddc50..377e8c0f 100644
--- a/ash/wm/overview/window_selector_unittest.cc
+++ b/ash/wm/overview/window_selector_unittest.cc
@@ -2121,6 +2121,48 @@
             normal_item->GetWindowDimensionsType());
 }
 
+// Verify that the window selector items titlebar and close button change
+// visibility when a item is being dragged.
+TEST_F(WindowSelectorTest, WindowItemTitleCloseVisibilityOnDrag) {
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kAshEnableNewOverviewUi);
+
+  UpdateDisplay("400x400");
+  const gfx::Rect bounds(10, 10, 200, 200);
+  std::unique_ptr<aura::Window> window1(CreateWindow(bounds));
+  std::unique_ptr<aura::Window> window2(CreateWindow(bounds));
+
+  // Dragging is only allowed in tablet mode.
+  RunAllPendingInMessageLoop();
+  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
+
+  ToggleOverview();
+  WindowSelectorItem* item1 = GetWindowItemForWindow(0, window1.get());
+  WindowSelectorItem* item2 = GetWindowItemForWindow(0, window2.get());
+
+  // Start the drag on |item1|. Verify the dragged item, |item1| has both the
+  // close button and titlebar hidden. All other items, |item2| should only have
+  // the close button hidden.
+  GetEventGenerator().MoveMouseTo(item1->target_bounds().CenterPoint());
+  GetEventGenerator().PressLeftButton();
+  RunAllPendingInMessageLoop();
+  EXPECT_EQ(0.f, item1->GetTitlebarOpacityForTesting());
+  EXPECT_EQ(0.f, item1->GetCloseButtonOpacityForTesting());
+  EXPECT_EQ(1.f, item2->GetTitlebarOpacityForTesting());
+  EXPECT_EQ(0.f, item2->GetCloseButtonOpacityForTesting());
+
+  // Drag |item1| in a way so that |window1| does not get activated (drags
+  // within a certain threshold count as clicks). Verify the close button and
+  // titlebar is visible for all items.
+  GetEventGenerator().MoveMouseTo(gfx::Point(200, 200));
+  GetEventGenerator().ReleaseLeftButton();
+  RunAllPendingInMessageLoop();
+  EXPECT_EQ(1.f, item1->GetTitlebarOpacityForTesting());
+  EXPECT_EQ(1.f, item1->GetCloseButtonOpacityForTesting());
+  EXPECT_EQ(1.f, item2->GetTitlebarOpacityForTesting());
+  EXPECT_EQ(1.f, item2->GetCloseButtonOpacityForTesting());
+}
+
 class SplitViewWindowSelectorTest : public WindowSelectorTest {
  public:
   SplitViewWindowSelectorTest() = default;
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc
index d523b7b..744c0925 100644
--- a/ash/wm/splitview/split_view_controller.cc
+++ b/ash/wm/splitview/split_view_controller.cc
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "ash/display/screen_orientation_controller_chromeos.h"
+#include "ash/public/cpp/app_types.h"
 #include "ash/public/cpp/ash_switches.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/screen_util.h"
@@ -26,8 +27,10 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/user_metrics.h"
 #include "base/optional.h"
+#include "ui/aura/client/aura_constants.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_delegate.h"
+#include "ui/base/class_property.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/compositor/layer.h"
 #include "ui/views/widget/widget.h"
@@ -102,6 +105,16 @@
 }
 
 bool SplitViewController::CanSnap(aura::Window* window) {
+  // In M65, some ARC apps can be freely resized and thus are capble of
+  // displaying in splitscreen, but splitscreen is not supported for ARC apps
+  // windows yet in M65, thus we should explicity return false here for ARC apps
+  // windows. Otherwise we may see issues as in https://crbug.com/808748. It
+  // will be reverted later in M66.
+  if (window->GetProperty(aura::client::kAppType) ==
+      static_cast<int>(AppType::ARC_APP)) {
+    return false;
+  }
+
   if (!wm::CanActivateWindow(window))
     return false;
   if (!wm::GetWindowState(window)->CanSnap())
@@ -178,6 +191,12 @@
   else if (right_window_)
     state_ = RIGHT_SNAPPED;
 
+  // Update the divider position and window bounds before snapping a new window.
+  // Since the minimum size of |window| maybe larger than currently bounds in
+  // |snap_position|.
+  MoveDividerToClosestFixedPosition();
+  UpdateSnappedWindowsAndDividerBounds();
+
   StartObserving(window);
   const wm::WMEvent event((snap_position == LEFT) ? wm::WM_EVENT_SNAP_LEFT
                                                   : wm::WM_EVENT_SNAP_RIGHT);
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc
index 12e9616..fdc51b1f 100644
--- a/ash/wm/splitview/split_view_controller_unittest.cc
+++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -913,7 +913,7 @@
 
 // Tests that the left or top snapped window can be moved outside of work area
 // when its minimum size is larger than its current bounds.
-TEST_F(SplitViewControllerTest, SnapWindowBoundsWithMinimumSizeTest) {
+TEST_F(SplitViewControllerTest, ResizingSnappedWindowWithMinimumSizeTest) {
   int64_t display_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
   display::DisplayManager* display_manager = Shell::Get()->display_manager();
   display::test::ScopedSetInternalDisplayId set_internal(display_manager,
@@ -1033,10 +1033,10 @@
   EndSplitView();
 }
 
-// Tests that if a snapped window's minumum size is larger than one third but
-// smaller than half of the work area's longer side. The divider should be
-// snapped to a position that is larger than the window's minimum size.
-TEST_F(SplitViewControllerTest, DividerPositionWithWindowMinimumSizeTest) {
+// Tests that the divider should not be moved to a position that is smaller than
+// the snapped window's minimum size after resizing.
+TEST_F(SplitViewControllerTest,
+       DividerPositionOnResizingSnappedWindowWithMinimumSizeTest) {
   const gfx::Rect bounds(0, 0, 200, 200);
   std::unique_ptr<aura::Window> window1(CreateWindow(bounds));
   aura::test::TestWindowDelegate* delegate1 =
@@ -1116,4 +1116,40 @@
   EndSplitView();
 }
 
+// Tests that the divider and snapped windows bounds should be updated if
+// snapping a new window with minimum size, which is larger than the bounds
+// of its snap position.
+TEST_F(SplitViewControllerTest,
+       DividerPositionWithWindowMinimumSizeOnSnapTest) {
+  const gfx::Rect bounds(0, 0, 200, 300);
+  std::unique_ptr<aura::Window> window1(CreateWindow(bounds));
+  const gfx::Rect workarea_bounds =
+      split_view_controller()->GetDisplayWorkAreaBoundsInScreen(window1.get());
+
+  // Divider should be moved to the middle at the beginning.
+  split_view_controller()->SnapWindow(window1.get(), SplitViewController::LEFT);
+  ASSERT_TRUE(split_view_divider());
+  EXPECT_GT(divider_position(), 0.33f * workarea_bounds.width());
+  EXPECT_LE(divider_position(), 0.5f * workarea_bounds.width());
+
+  // Drag the divider to two-third position.
+  ui::test::EventGenerator& generator(GetEventGenerator());
+  gfx::Rect divider_bounds =
+      split_view_divider()->GetDividerBoundsInScreen(false);
+  generator.set_current_location(divider_bounds.CenterPoint());
+  generator.DragMouseTo(gfx::Point(workarea_bounds.width() * 0.67f, 0));
+  EXPECT_GT(divider_position(), 0.5f * workarea_bounds.width());
+  EXPECT_LE(divider_position(), 0.67f * workarea_bounds.width());
+
+  std::unique_ptr<aura::Window> window2(CreateWindow(bounds));
+  aura::test::TestWindowDelegate* delegate2 =
+      static_cast<aura::test::TestWindowDelegate*>(window2->delegate());
+  delegate2->set_minimum_size(
+      gfx::Size(workarea_bounds.width() * 0.4f, workarea_bounds.height()));
+  split_view_controller()->SnapWindow(window2.get(),
+                                      SplitViewController::RIGHT);
+  EXPECT_GT(divider_position(), 0.33f * workarea_bounds.width());
+  EXPECT_LE(divider_position(), 0.5f * workarea_bounds.width());
+}
+
 }  // namespace ash
diff --git a/base/allocator/partition_allocator/address_space_randomization_unittest.cc b/base/allocator/partition_allocator/address_space_randomization_unittest.cc
index dec8a2be..4d6aa794 100644
--- a/base/allocator/partition_allocator/address_space_randomization_unittest.cc
+++ b/base/allocator/partition_allocator/address_space_randomization_unittest.cc
@@ -187,7 +187,13 @@
   }
 }
 
-TEST(AddressSpaceRandomizationTest, Random) {
+// TODO(crbug.com/809367): Flaky on Linux TSAN.
+#if defined(OS_LINUX) && defined(THREAD_SANITIZER)
+#define MAYBE_Random DISABLED_Random
+#else
+#define MAYBE_Random Random
+#endif
+TEST(AddressSpaceRandomizationTest, MAYBE_Random) {
   uintptr_t mask = GetMask();
   if (!mask)
     return;
diff --git a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc b/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
index 9c55f3a6..3cbcd3c 100644
--- a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
+++ b/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
@@ -71,8 +71,9 @@
       settings.image_provider = &image_provider;
 
       raster_source->PlaybackToCanvas(
-          &canvas, gfx::ColorSpace(), content_rect, content_rect,
-          gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), settings);
+          &canvas, gfx::ColorSpace(), content_rect.size(), content_rect,
+          content_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
+          settings);
 
       timer.NextLap();
     } while (!timer.HasTimeLimitExpired());
diff --git a/cc/debug/debug_colors.cc b/cc/debug/debug_colors.cc
index 8e84ef61..eef3fcb7 100644
--- a/cc/debug/debug_colors.cc
+++ b/cc/debug/debug_colors.cc
@@ -267,17 +267,6 @@
   return SkColorSetARGB(30, 112, 229, 0);
 }
 
-// Non-Painted rects in cyan.
-SkColor DebugColors::NonPaintedFillColor() { return SK_ColorCYAN; }
-
-// Missing picture rects in magenta.
-SkColor DebugColors::MissingPictureFillColor() { return SK_ColorMAGENTA; }
-
-// Missing resize invalidations are in salmon pink.
-SkColor DebugColors::MissingResizeInvalidations() {
-  return SkColorSetARGB(255, 255, 155, 170);
-}
-
 // Picture borders in transparent blue.
 SkColor DebugColors::PictureBorderColor() {
   return SkColorSetARGB(100, 0, 0, 200);
diff --git a/cc/layers/recording_source.cc b/cc/layers/recording_source.cc
index 78cfa2d..80648d3 100644
--- a/cc/layers/recording_source.cc
+++ b/cc/layers/recording_source.cc
@@ -17,12 +17,6 @@
 
 namespace {
 
-#ifdef NDEBUG
-const bool kDefaultClearCanvasSetting = false;
-#else
-const bool kDefaultClearCanvasSetting = true;
-#endif
-
 // We don't perform per-layer solid color analysis when there are too many skia
 // operations.
 const int kMaxOpsToAnalyzeForLayer = 10;
@@ -35,7 +29,6 @@
     : slow_down_raster_scale_factor_for_debug_(0),
       requires_clear_(false),
       is_solid_color_(false),
-      clear_canvas_with_debug_color_(kDefaultClearCanvasSetting),
       solid_color_(SK_ColorTRANSPARENT),
       background_color_(SK_ColorTRANSPARENT),
       recording_scale_factor_(1.f) {}
diff --git a/cc/layers/texture_layer_impl.cc b/cc/layers/texture_layer_impl.cc
index cb8c3cf..b57570f 100644
--- a/cc/layers/texture_layer_impl.cc
+++ b/cc/layers/texture_layer_impl.cc
@@ -194,8 +194,10 @@
   if (own_resource_) {
     DCHECK(!resource_id_);
     if (release_callback_) {
-      // We didn't use the resource, so don't need to return a SyncToken.
-      release_callback_->Run(gpu::SyncToken(), false);
+      // We didn't use the resource, but the client might need the SyncToken
+      // before it can use the resource with its own GL context.
+      release_callback_->Run(transferable_resource_.mailbox_holder.sync_token,
+                             false);
     }
     transferable_resource_ = viz::TransferableResource();
     release_callback_ = nullptr;
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc
index 1e5dade..f2f4fd6 100644
--- a/cc/layers/texture_layer_unittest.cc
+++ b/cc/layers/texture_layer_unittest.cc
@@ -771,8 +771,9 @@
 // Test conditions for results of TextureLayerImpl::WillDraw under
 // different configurations of different mailbox, texture_id, and draw_mode.
 TEST_F(TextureLayerImplWithResourceTest, TestWillDraw) {
-  EXPECT_CALL(test_data_.mock_callback_,
-              Release(test_data_.mailbox_name1_, gpu::SyncToken(), false))
+  EXPECT_CALL(
+      test_data_.mock_callback_,
+      Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
       .Times(AnyNumber());
   EXPECT_CALL(
       test_data_.mock_callback_,
@@ -847,10 +848,11 @@
       test_data_.resource1_,
       viz::SingleReleaseCallback::Create(test_data_.release_callback1_));
 
-  // Test multiple commits without an activation. The resource wasn't used so no
-  // sync token is returned.
-  EXPECT_CALL(test_data_.mock_callback_,
-              Release(test_data_.mailbox_name1_, gpu::SyncToken(), false))
+  // Test multiple commits without an activation. The resource wasn't used so
+  // the original sync token is returned.
+  EXPECT_CALL(
+      test_data_.mock_callback_,
+      Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
       .Times(1);
   pending_layer->SetTransferableResource(
       test_data_.resource2_,
@@ -883,9 +885,11 @@
   active_layer->DidBecomeActive();
   Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
 
-  // Test destructor. The resource wasn't used so no sync token is returned.
-  EXPECT_CALL(test_data_.mock_callback_,
-              Release(test_data_.mailbox_name1_, gpu::SyncToken(), false))
+  // Test destructor. The resource wasn't used so the original sync token is
+  // returned.
+  EXPECT_CALL(
+      test_data_.mock_callback_,
+      Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
       .Times(1);
   pending_layer->SetTransferableResource(
       test_data_.resource1_,
diff --git a/cc/paint/oop_pixeltest.cc b/cc/paint/oop_pixeltest.cc
index ef3ee59..824e4c7d 100644
--- a/cc/paint/oop_pixeltest.cc
+++ b/cc/paint/oop_pixeltest.cc
@@ -34,6 +34,16 @@
 namespace cc {
 namespace {
 
+scoped_refptr<DisplayItemList> MakeNoopDisplayItemList() {
+  auto display_item_list = base::MakeRefCounted<DisplayItemList>();
+  display_item_list->StartPaint();
+  display_item_list->push<SaveOp>();
+  display_item_list->push<RestoreOp>();
+  display_item_list->EndPaintOfUnpaired(gfx::Rect(10000, 10000));
+  display_item_list->Finalize();
+  return display_item_list;
+}
+
 class NoOpImageProvider : public ImageProvider {
  public:
   ~NoOpImageProvider() override = default;
@@ -111,17 +121,24 @@
     bool use_lcd_text = false;
     bool use_distance_field_text = false;
     SkColorType color_type = kRGBA_8888_SkColorType;
-    gfx::Rect bitmap_rect;
+    gfx::Size resource_size;
+    gfx::Size content_size;
+    gfx::Rect full_raster_rect;
     gfx::Rect playback_rect;
     gfx::Vector2dF post_translate = {0.f, 0.f};
     float post_scale = 1.f;
     gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB();
+    bool requires_clear = false;
+    bool preclear = false;
+    SkColor preclear_color;
   };
 
   SkBitmap Raster(scoped_refptr<DisplayItemList> display_item_list,
                   const gfx::Size& playback_size) {
     RasterOptions options;
-    options.bitmap_rect = gfx::Rect(playback_size);
+    options.resource_size = playback_size;
+    options.content_size = options.resource_size;
+    options.full_raster_rect = gfx::Rect(playback_size);
     options.playback_rect = gfx::Rect(playback_size);
     return Raster(display_item_list, options);
   }
@@ -129,8 +146,8 @@
   SkBitmap Raster(scoped_refptr<DisplayItemList> display_item_list,
                   const RasterOptions& options) {
     gpu::gles2::GLES2Interface* gl = context_->GetImplementation();
-    int width = options.bitmap_rect.width();
-    int height = options.bitmap_rect.height();
+    int width = options.resource_size.width();
+    int height = options.resource_size.height();
 
     // Create and allocate a texture on the raster interface.
     GLuint raster_texture_id;
@@ -144,17 +161,26 @@
     EXPECT_EQ(raster_implementation_->GetError(),
               static_cast<unsigned>(GL_NO_ERROR));
 
+    RasterColorSpace color_space(options.color_space, ++color_space_id_);
+
+    if (options.preclear) {
+      raster_implementation_->BeginRasterCHROMIUM(
+          raster_texture_id, options.preclear_color, options.msaa_sample_count,
+          options.use_lcd_text, options.use_distance_field_text,
+          options.color_type, color_space);
+      raster_implementation_->EndRasterCHROMIUM();
+    }
+
     // "Out of process" raster! \o/
 
     raster_implementation_->BeginRasterCHROMIUM(
         raster_texture_id, options.background_color, options.msaa_sample_count,
         options.use_lcd_text, options.use_distance_field_text,
-        options.color_type,
-        RasterColorSpace(options.color_space, ++color_space_id_));
+        options.color_type, color_space);
     raster_implementation_->RasterCHROMIUM(
-        display_item_list.get(), &image_provider_,
-        options.bitmap_rect.OffsetFromOrigin(), options.playback_rect,
-        options.post_translate, options.post_scale);
+        display_item_list.get(), &image_provider_, options.content_size,
+        options.full_raster_rect, options.playback_rect, options.post_translate,
+        options.post_scale, options.requires_clear);
     raster_implementation_->EndRasterCHROMIUM();
 
     // Produce a mailbox and insert an ordering barrier (assumes the raster
@@ -200,10 +226,10 @@
 
     SkBitmap bitmap;
     bitmap.allocN32Pixels(width, height);
-    SkPixmap pixmap(SkImageInfo::MakeN32Premul(options.bitmap_rect.width(),
-                                               options.bitmap_rect.height()),
+    SkPixmap pixmap(SkImageInfo::MakeN32Premul(options.resource_size.width(),
+                                               options.resource_size.height()),
                     colors.data(),
-                    options.bitmap_rect.width() * sizeof(SkColor));
+                    options.resource_size.width() * sizeof(SkColor));
     bitmap.writePixels(pixmap);
     return bitmap;
   }
@@ -212,7 +238,8 @@
       scoped_refptr<DisplayItemList> display_item_list,
       const gfx::Size& playback_size) {
     RasterOptions options;
-    options.bitmap_rect = gfx::Rect(playback_size);
+    options.resource_size = playback_size;
+    options.full_raster_rect = gfx::Rect(playback_size);
     options.playback_rect = gfx::Rect(playback_size);
     return RasterExpectedBitmap(display_item_list, options);
   }
@@ -227,17 +254,15 @@
     recording.UpdateDisplayItemList(display_item_list, 0u, 1.f);
     recording.SetBackgroundColor(options.background_color);
     Region fake_invalidation;
-    gfx::Rect layer_rect(
-        gfx::Size(options.bitmap_rect.right(), options.bitmap_rect.bottom()));
+    gfx::Rect layer_rect(gfx::Size(options.full_raster_rect.right(),
+                                   options.full_raster_rect.bottom()));
     recording.UpdateAndExpandInvalidation(&fake_invalidation, layer_rect.size(),
                                           layer_rect);
+    recording.SetRequiresClear(options.requires_clear);
 
     auto raster_source = recording.CreateRasterSource();
     RasterSource::PlaybackSettings settings;
     settings.use_lcd_text = options.use_lcd_text;
-    // OOP raster does not support the complicated debug color clearing from
-    // RasterSource::ClearCanvasForPlayback, so disable it for consistency.
-    settings.clear_canvas_before_raster = false;
     // TODO(enne): add a fake image provider here.
 
     uint32_t flags = options.use_distance_field_text
@@ -258,39 +283,51 @@
         gl, capabilities, max_resource_cache_bytes,
         max_glyph_cache_texture_bytes);
     SkImageInfo image_info = SkImageInfo::MakeN32Premul(
-        options.bitmap_rect.width(), options.bitmap_rect.height());
+        options.resource_size.width(), options.resource_size.height());
     auto surface = SkSurface::MakeRenderTarget(scoped_grcontext.get(),
                                                SkBudgeted::kYes, image_info);
     SkCanvas* canvas = surface->getCanvas();
-    canvas->drawColor(options.background_color);
+    if (options.preclear)
+      canvas->drawColor(options.preclear_color);
+    else
+      canvas->drawColor(options.background_color);
 
     gfx::AxisTransform2d raster_transform(options.post_scale,
                                           options.post_translate);
-    raster_source->PlaybackToCanvas(canvas, options.color_space,
-                                    options.bitmap_rect, options.playback_rect,
-                                    raster_transform, settings);
+    gfx::ColorSpace target_color_space;
+    raster_source->PlaybackToCanvas(
+        canvas, options.color_space, options.content_size,
+        options.full_raster_rect, options.playback_rect, raster_transform,
+        settings);
     surface->prepareForExternalIO();
     EXPECT_EQ(gl->GetError(), static_cast<unsigned>(GL_NO_ERROR));
 
     SkBitmap bitmap;
     SkImageInfo info = SkImageInfo::Make(
-        options.bitmap_rect.width(), options.bitmap_rect.height(),
+        options.resource_size.width(), options.resource_size.height(),
         SkColorType::kBGRA_8888_SkColorType, SkAlphaType::kPremul_SkAlphaType);
-    bitmap.allocPixels(info, options.bitmap_rect.width() * 4);
+    bitmap.allocPixels(info, options.resource_size.width() * 4);
     bool success = surface->readPixels(bitmap, 0, 0);
     CHECK(success);
     EXPECT_EQ(gl->GetError(), static_cast<unsigned>(GL_NO_ERROR));
     return bitmap;
   }
 
-  void ExpectEquals(SkBitmap actual, SkBitmap expected) {
+  void ExpectEquals(SkBitmap actual,
+                    SkBitmap expected,
+                    const char* label = nullptr) {
     EXPECT_EQ(actual.dimensions(), expected.dimensions());
     auto expected_url = GetPNGDataUrl(expected);
     auto actual_url = GetPNGDataUrl(actual);
     if (actual_url == expected_url)
       return;
-    ADD_FAILURE() << "\nExpected: " << expected_url
-                  << "\nActual:   " << actual_url;
+    if (label) {
+      ADD_FAILURE() << "\nCase: " << label << "\nExpected: " << expected_url
+                    << "\nActual:   " << actual_url;
+    } else {
+      ADD_FAILURE() << "\nExpected: " << expected_url
+                    << "\nActual:   " << actual_url;
+    }
   }
 
  private:
@@ -367,6 +404,380 @@
   ExpectEquals(actual, expected);
 }
 
+TEST_F(OopPixelTest, Preclear) {
+  gfx::Rect rect(10, 10);
+  auto display_item_list = base::MakeRefCounted<DisplayItemList>();
+  display_item_list->Finalize();
+
+  RasterOptions options;
+  options.resource_size = rect.size();
+  options.full_raster_rect = rect;
+  options.playback_rect = rect;
+  options.background_color = SK_ColorMAGENTA;
+  options.preclear = true;
+  options.preclear_color = SK_ColorGREEN;
+
+  auto actual = Raster(display_item_list, options);
+
+  options.preclear = false;
+  options.background_color = SK_ColorGREEN;
+  auto expected = RasterExpectedBitmap(display_item_list, options);
+  ExpectEquals(actual, expected);
+}
+
+TEST_F(OopPixelTest, ClearingOpaqueCorner) {
+  // Verify that clears work properly for both the right and bottom sides
+  // of an opaque corner tile.
+
+  RasterOptions options;
+  gfx::Point arbitrary_offset(10, 20);
+  options.resource_size = gfx::Size(10, 10);
+  options.full_raster_rect = gfx::Rect(arbitrary_offset, gfx::Size(8, 7));
+  options.content_size = gfx::Size(options.full_raster_rect.right(),
+                                   options.full_raster_rect.bottom());
+  options.playback_rect = options.full_raster_rect;
+  options.background_color = SK_ColorGREEN;
+  float arbitrary_scale = 0.25f;
+  options.post_scale = arbitrary_scale;
+  options.requires_clear = false;
+  options.preclear = true;
+  options.preclear_color = SK_ColorRED;
+
+  // Make a non-empty but noop display list to avoid early outs.
+  auto display_item_list = MakeNoopDisplayItemList();
+
+  auto oop_result = Raster(display_item_list, options);
+  auto gpu_result = RasterExpectedBitmap(display_item_list, options);
+
+  SkBitmap bitmap;
+  bitmap.allocPixelsFlags(
+      SkImageInfo::MakeN32Premul(options.resource_size.width(),
+                                 options.resource_size.height()),
+      SkBitmap::kZeroPixels_AllocFlag);
+
+  // Expect a two pixel border from texels 7-9 on the column and 6-8 on row.
+  SkCanvas canvas(bitmap);
+  canvas.drawColor(options.preclear_color);
+  SkPaint green;
+  green.setColor(options.background_color);
+  canvas.drawRect(SkRect::MakeXYWH(7, 0, 2, 8), green);
+  canvas.drawRect(SkRect::MakeXYWH(0, 6, 9, 2), green);
+
+  ExpectEquals(oop_result, bitmap, "oop");
+  ExpectEquals(gpu_result, bitmap, "gpu");
+}
+
+TEST_F(OopPixelTest, ClearingOpaqueCornerExactEdge) {
+  // Verify that clears work properly for both the right and bottom sides
+  // of an opaque corner tile whose content rect exactly lines up with
+  // the edge of the resource.
+
+  RasterOptions options;
+  gfx::Point arbitrary_offset(10, 20);
+  options.resource_size = gfx::Size(10, 10);
+  options.full_raster_rect = gfx::Rect(arbitrary_offset, options.resource_size);
+  options.content_size = gfx::Size(options.full_raster_rect.right(),
+                                   options.full_raster_rect.bottom());
+  options.playback_rect = options.full_raster_rect;
+  options.background_color = SK_ColorGREEN;
+  float arbitrary_scale = 0.25f;
+  options.post_scale = arbitrary_scale;
+  options.requires_clear = false;
+  options.preclear = true;
+  options.preclear_color = SK_ColorRED;
+
+  // Make a non-empty but noop display list to avoid early outs.
+  auto display_item_list = MakeNoopDisplayItemList();
+
+  auto oop_result = Raster(display_item_list, options);
+  auto gpu_result = RasterExpectedBitmap(display_item_list, options);
+
+  SkBitmap bitmap;
+  bitmap.allocPixelsFlags(
+      SkImageInfo::MakeN32Premul(options.resource_size.width(),
+                                 options.resource_size.height()),
+      SkBitmap::kZeroPixels_AllocFlag);
+
+  // Expect a one pixel border on the bottom/right edge.
+  SkCanvas canvas(bitmap);
+  canvas.drawColor(options.preclear_color);
+  SkPaint green;
+  green.setColor(options.background_color);
+  canvas.drawRect(SkRect::MakeXYWH(9, 0, 1, 10), green);
+  canvas.drawRect(SkRect::MakeXYWH(0, 9, 10, 1), green);
+
+  ExpectEquals(oop_result, bitmap, "oop");
+  ExpectEquals(gpu_result, bitmap, "gpu");
+}
+
+TEST_F(OopPixelTest, ClearingOpaqueCornerPartialRaster) {
+  // Verify that clears do nothing on an opaque corner tile whose
+  // partial raster rect doesn't intersect the edge of the content.
+
+  RasterOptions options;
+  options.resource_size = gfx::Size(10, 10);
+  gfx::Point arbitrary_offset(30, 12);
+  options.full_raster_rect = gfx::Rect(arbitrary_offset, gfx::Size(8, 7));
+  options.content_size = gfx::Size(options.full_raster_rect.right(),
+                                   options.full_raster_rect.bottom());
+  options.playback_rect =
+      gfx::Rect(arbitrary_offset.x() + 5, arbitrary_offset.y() + 3, 2, 4);
+  options.background_color = SK_ColorGREEN;
+  options.requires_clear = false;
+  options.preclear = true;
+  options.preclear_color = SK_ColorRED;
+
+  // Make a non-empty but noop display list to avoid early outs.
+  auto display_item_list = MakeNoopDisplayItemList();
+
+  auto oop_result = Raster(display_item_list, options);
+  auto gpu_result = RasterExpectedBitmap(display_item_list, options);
+
+  SkBitmap bitmap;
+  bitmap.allocPixelsFlags(
+      SkImageInfo::MakeN32Premul(options.resource_size.width(),
+                                 options.resource_size.height()),
+      SkBitmap::kZeroPixels_AllocFlag);
+
+  // Expect no clearing here because the playback rect is internal.
+  SkCanvas canvas(bitmap);
+  canvas.drawColor(options.preclear_color);
+
+  ExpectEquals(oop_result, bitmap, "oop");
+  ExpectEquals(gpu_result, bitmap, "gpu");
+}
+
+TEST_F(OopPixelTest, ClearingOpaqueRightEdge) {
+  // Verify that a tile that intersects the right edge of content
+  // but not the bottom only clears the right pixels.
+
+  RasterOptions options;
+  gfx::Point arbitrary_offset(30, 40);
+  options.resource_size = gfx::Size(10, 10);
+  options.full_raster_rect = gfx::Rect(arbitrary_offset, gfx::Size(3, 10));
+  options.content_size = gfx::Size(options.full_raster_rect.right(),
+                                   options.full_raster_rect.bottom() + 1000);
+  options.playback_rect = options.full_raster_rect;
+  options.background_color = SK_ColorGREEN;
+  options.requires_clear = false;
+  options.preclear = true;
+  options.preclear_color = SK_ColorRED;
+
+  // Make a non-empty but noop display list to avoid early outs.
+  auto display_item_list = MakeNoopDisplayItemList();
+
+  auto oop_result = Raster(display_item_list, options);
+  auto gpu_result = RasterExpectedBitmap(display_item_list, options);
+
+  SkBitmap bitmap;
+  bitmap.allocPixelsFlags(
+      SkImageInfo::MakeN32Premul(options.resource_size.width(),
+                                 options.resource_size.height()),
+      SkBitmap::kZeroPixels_AllocFlag);
+
+  // Expect a two pixel column border from texels 2-4.
+  SkCanvas canvas(bitmap);
+  canvas.drawColor(options.preclear_color);
+  SkPaint green;
+  green.setColor(options.background_color);
+  canvas.drawRect(SkRect::MakeXYWH(2, 0, 2, 10), green);
+
+  ExpectEquals(oop_result, bitmap, "oop");
+  ExpectEquals(gpu_result, bitmap, "gpu");
+}
+
+TEST_F(OopPixelTest, ClearingOpaqueBottomEdge) {
+  // Verify that a tile that intersects the bottom edge of content
+  // but not the right only clears the bottom pixels.
+
+  RasterOptions options;
+  gfx::Point arbitrary_offset(10, 20);
+  options.resource_size = gfx::Size(10, 10);
+  options.full_raster_rect = gfx::Rect(arbitrary_offset, gfx::Size(10, 5));
+  options.content_size = gfx::Size(options.full_raster_rect.right() + 1000,
+                                   options.full_raster_rect.bottom());
+  options.playback_rect = options.full_raster_rect;
+  options.background_color = SK_ColorGREEN;
+  float arbitrary_scale = 0.25f;
+  options.post_scale = arbitrary_scale;
+  options.requires_clear = false;
+  options.preclear = true;
+  options.preclear_color = SK_ColorRED;
+
+  // Make a non-empty but noop display list to avoid early outs.
+  auto display_item_list = MakeNoopDisplayItemList();
+
+  auto oop_result = Raster(display_item_list, options);
+  auto gpu_result = RasterExpectedBitmap(display_item_list, options);
+
+  SkBitmap bitmap;
+  bitmap.allocPixelsFlags(
+      SkImageInfo::MakeN32Premul(options.resource_size.width(),
+                                 options.resource_size.height()),
+      SkBitmap::kZeroPixels_AllocFlag);
+
+  // Expect a two pixel border from texels 4-6 on the row
+  SkCanvas canvas(bitmap);
+  canvas.drawColor(options.preclear_color);
+  SkPaint green;
+  green.setColor(options.background_color);
+  canvas.drawRect(SkRect::MakeXYWH(0, 4, 10, 2), green);
+
+  ExpectEquals(oop_result, bitmap, "oop");
+  ExpectEquals(gpu_result, bitmap, "gpu");
+}
+
+TEST_F(OopPixelTest, ClearingOpaqueInternal) {
+  // Verify that an internal opaque tile does no clearing.
+
+  RasterOptions options;
+  gfx::Point arbitrary_offset(35, 12);
+  options.resource_size = gfx::Size(10, 10);
+  options.full_raster_rect = gfx::Rect(arbitrary_offset, options.resource_size);
+  // Very large content rect to make this an internal tile.
+  options.content_size = gfx::Size(1000, 1000);
+  options.playback_rect = options.full_raster_rect;
+  options.background_color = SK_ColorGREEN;
+  float arbitrary_scale = 1.2345f;
+  options.post_scale = arbitrary_scale;
+  options.requires_clear = false;
+  options.preclear = true;
+  options.preclear_color = SK_ColorRED;
+
+  // Make a non-empty but noop display list to avoid early outs.
+  auto display_item_list = MakeNoopDisplayItemList();
+
+  auto oop_result = Raster(display_item_list, options);
+  auto gpu_result = RasterExpectedBitmap(display_item_list, options);
+
+  SkBitmap bitmap;
+  bitmap.allocPixelsFlags(
+      SkImageInfo::MakeN32Premul(options.resource_size.width(),
+                                 options.resource_size.height()),
+      SkBitmap::kZeroPixels_AllocFlag);
+
+  // Expect no clears here, as this tile does not intersect the edge of the
+  // tile.
+  SkCanvas canvas(bitmap);
+  canvas.drawColor(options.preclear_color);
+
+  ExpectEquals(oop_result, bitmap, "oop");
+  ExpectEquals(gpu_result, bitmap, "gpu");
+}
+
+TEST_F(OopPixelTest, ClearingTransparentCorner) {
+  RasterOptions options;
+  gfx::Point arbitrary_offset(5, 8);
+  options.resource_size = gfx::Size(10, 10);
+  options.full_raster_rect = gfx::Rect(arbitrary_offset, gfx::Size(8, 7));
+  options.content_size = gfx::Size(options.full_raster_rect.right(),
+                                   options.full_raster_rect.bottom());
+  options.playback_rect = options.full_raster_rect;
+  options.background_color = SK_ColorTRANSPARENT;
+  float arbitrary_scale = 3.7f;
+  options.post_scale = arbitrary_scale;
+  options.requires_clear = true;
+  options.preclear = true;
+  options.preclear_color = SK_ColorRED;
+
+  // Make a non-empty but noop display list to avoid early outs.
+  auto display_item_list = MakeNoopDisplayItemList();
+
+  auto oop_result = Raster(display_item_list, options);
+  auto gpu_result = RasterExpectedBitmap(display_item_list, options);
+
+  // Because this is rastering the entire tile, clear the entire thing
+  // even if the full raster rect doesn't cover the whole resource.
+  SkBitmap bitmap;
+  bitmap.allocPixelsFlags(
+      SkImageInfo::MakeN32Premul(options.resource_size.width(),
+                                 options.resource_size.height()),
+      SkBitmap::kZeroPixels_AllocFlag);
+
+  SkCanvas canvas(bitmap);
+  canvas.drawColor(SK_ColorTRANSPARENT);
+
+  ExpectEquals(oop_result, bitmap, "oop");
+  ExpectEquals(gpu_result, bitmap, "gpu");
+}
+
+TEST_F(OopPixelTest, ClearingTransparentInternalTile) {
+  // Content rect much larger than full raster rect or playback rect.
+  // This should still clear the tile.
+  RasterOptions options;
+  gfx::Point arbitrary_offset(100, 200);
+  options.resource_size = gfx::Size(10, 10);
+  options.full_raster_rect = gfx::Rect(arbitrary_offset, options.resource_size);
+  options.content_size = gfx::Size(1000, 1000);
+  options.playback_rect = options.full_raster_rect;
+  options.background_color = SK_ColorTRANSPARENT;
+  float arbitrary_scale = 3.7f;
+  options.post_scale = arbitrary_scale;
+  options.requires_clear = true;
+  options.preclear = true;
+  options.preclear_color = SK_ColorRED;
+
+  // Make a non-empty but noop display list to avoid early outs.
+  auto display_item_list = MakeNoopDisplayItemList();
+
+  auto oop_result = Raster(display_item_list, options);
+  auto gpu_result = RasterExpectedBitmap(display_item_list, options);
+
+  // Because this is rastering the entire tile, clear the entire thing
+  // even if the full raster rect doesn't cover the whole resource.
+  SkBitmap bitmap;
+  bitmap.allocPixelsFlags(
+      SkImageInfo::MakeN32Premul(options.resource_size.width(),
+                                 options.resource_size.height()),
+      SkBitmap::kZeroPixels_AllocFlag);
+
+  SkCanvas canvas(bitmap);
+  canvas.drawColor(SK_ColorTRANSPARENT);
+
+  ExpectEquals(oop_result, bitmap, "oop");
+  ExpectEquals(gpu_result, bitmap, "gpu");
+}
+
+TEST_F(OopPixelTest, ClearingTransparentCornerPartialRaster) {
+  RasterOptions options;
+  options.resource_size = gfx::Size(10, 10);
+  gfx::Point arbitrary_offset(30, 12);
+  options.full_raster_rect = gfx::Rect(arbitrary_offset, gfx::Size(8, 7));
+  options.content_size = gfx::Size(options.full_raster_rect.right(),
+                                   options.full_raster_rect.bottom());
+  options.playback_rect =
+      gfx::Rect(arbitrary_offset.x() + 5, arbitrary_offset.y() + 3, 2, 4);
+  options.background_color = SK_ColorTRANSPARENT;
+  float arbitrary_scale = 0.23f;
+  options.post_scale = arbitrary_scale;
+  options.requires_clear = true;
+  options.preclear = true;
+  options.preclear_color = SK_ColorRED;
+
+  // Make a non-empty but noop display list to avoid early outs.
+  auto display_item_list = MakeNoopDisplayItemList();
+
+  auto oop_result = Raster(display_item_list, options);
+  auto gpu_result = RasterExpectedBitmap(display_item_list, options);
+
+  SkBitmap bitmap;
+  bitmap.allocPixelsFlags(
+      SkImageInfo::MakeN32Premul(options.resource_size.width(),
+                                 options.resource_size.height()),
+      SkBitmap::kZeroPixels_AllocFlag);
+
+  // Result should be a red background with a cleared hole where the
+  // playback_rect is.
+  SkCanvas canvas(bitmap);
+  canvas.drawColor(options.preclear_color);
+  canvas.translate(-arbitrary_offset.x(), -arbitrary_offset.y());
+  canvas.clipRect(gfx::RectToSkRect(options.playback_rect));
+  canvas.drawColor(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
+
+  ExpectEquals(oop_result, bitmap, "oop");
+  ExpectEquals(gpu_result, bitmap, "gpu");
+}
+
 // Test various bitmap and playback rects in the raster options, to verify
 // that in process (RasterSource) and out of process (GLES2Implementation)
 // raster behave identically.
@@ -384,13 +795,16 @@
   std::vector<std::pair<gfx::Rect, gfx::Rect>> input = {
       {{0, 0, 10, 10}, {0, 0, 10, 10}},
       {{1, 2, 10, 10}, {4, 2, 5, 6}},
-      {{5, 5, 15, 10}, {0, 0, 10, 10}}};
+      {{5, 5, 15, 10}, {5, 5, 10, 10}}};
 
   for (size_t i = 0; i < input.size(); ++i) {
     SCOPED_TRACE(base::StringPrintf("Case %zd", i));
 
     RasterOptions options;
-    options.bitmap_rect = input[i].first;
+    options.resource_size = input[i].first.size(),
+    options.full_raster_rect = input[i].first;
+    options.content_size = gfx::Size(options.full_raster_rect.right(),
+                                     options.full_raster_rect.bottom());
     options.playback_rect = input[i].second;
     options.background_color = SK_ColorMAGENTA;
 
@@ -418,8 +832,10 @@
   // with the left and top sides of the greenish box partially blended due to
   // the post translate.
   RasterOptions options;
-  options.bitmap_rect = {5, 5, 20, 20};
-  options.playback_rect = {3, 2, 15, 12};
+  options.resource_size = {20, 20};
+  options.content_size = {25, 25};
+  options.full_raster_rect = {5, 5, 20, 20};
+  options.playback_rect = {5, 5, 13, 9};
   options.background_color = SK_ColorCYAN;
   options.post_translate = {0.5f, 0.25f};
   options.post_scale = 2.f;
@@ -449,7 +865,9 @@
 
   // Draw a "tile" in the middle of the display list with a post scale.
   RasterOptions options;
-  options.bitmap_rect = {0, 10, 1, 10};
+  options.resource_size = {10, 10};
+  options.content_size = {20, 20};
+  options.full_raster_rect = {0, 10, 1, 10};
   options.playback_rect = {0, 10, 1, 10};
   options.background_color = SK_ColorGRAY;
   options.post_translate = {0.f, 0.f};
@@ -462,8 +880,10 @@
 
 TEST_F(OopPixelTest, DrawRectColorSpace) {
   RasterOptions options;
-  options.bitmap_rect = gfx::Rect(100, 100);
-  options.playback_rect = options.bitmap_rect;
+  options.resource_size = gfx::Size(100, 100);
+  options.content_size = options.resource_size;
+  options.full_raster_rect = gfx::Rect(options.content_size);
+  options.playback_rect = options.full_raster_rect;
   options.color_space = gfx::ColorSpace::CreateDisplayP3D65();
 
   auto display_item_list = base::MakeRefCounted<DisplayItemList>();
@@ -471,8 +891,9 @@
   PaintFlags flags;
   flags.setStyle(PaintFlags::kFill_Style);
   flags.setColor(SK_ColorGREEN);
-  display_item_list->push<DrawRectOp>(SkRect::MakeWH(100.f, 100.f), flags);
-  display_item_list->EndPaintOfUnpaired(options.bitmap_rect);
+  display_item_list->push<DrawRectOp>(
+      gfx::RectToSkRect(gfx::Rect(options.resource_size)), flags);
+  display_item_list->EndPaintOfUnpaired(options.full_raster_rect);
   display_item_list->Finalize();
 
   auto actual = Raster(display_item_list, options);
diff --git a/cc/paint/paint_op_buffer_serializer.cc b/cc/paint/paint_op_buffer_serializer.cc
index 4cfe89a..4dc024e 100644
--- a/cc/paint/paint_op_buffer_serializer.cc
+++ b/cc/paint/paint_op_buffer_serializer.cc
@@ -42,10 +42,8 @@
 void PaintOpBufferSerializer::Serialize(const PaintOpBuffer* buffer,
                                         const std::vector<size_t>* offsets,
                                         const Preamble& preamble) {
-  // Reset the canvas to the maximum extents of our playback rect, ensuring this
-  // rect will not reject images.
-  canvas_.resetCanvas(preamble.playback_rect.right(),
-                      preamble.playback_rect.bottom());
+  canvas_.resetCanvas(preamble.full_raster_rect.width(),
+                      preamble.full_raster_rect.height());
   DCHECK(canvas_.getTotalMatrix().isIdentity());
   static const int kInitialSaveCount = 1;
   DCHECK_EQ(kInitialSaveCount, canvas_.getSaveCount());
@@ -75,18 +73,103 @@
   SerializeBuffer(buffer, nullptr);
 }
 
+void PaintOpBufferSerializer::Serialize(const PaintOpBuffer* buffer,
+                                        const gfx::Rect& playback_rect,
+                                        const gfx::SizeF& post_scale) {
+  // Reset the canvas to the maximum extents of our playback rect, ensuring this
+  // rect will not reject images.
+  canvas_.resetCanvas(playback_rect.width(), playback_rect.height());
+  DCHECK(canvas_.getTotalMatrix().isIdentity());
+
+  PaintOp::SerializeOptions options(image_provider_, transfer_cache_, &canvas_,
+                                    canvas_.getTotalMatrix());
+  PlaybackParams params(image_provider_, canvas_.getTotalMatrix());
+
+  // TODO(khushalsagar): remove this clip rect if it's not needed.
+  if (!playback_rect.IsEmpty()) {
+    ClipRectOp clip_op(gfx::RectToSkRect(playback_rect), SkClipOp::kIntersect,
+                       false);
+    SerializeOp(&clip_op, options, params);
+  }
+
+  if (post_scale.width() != 1.f || post_scale.height() != 1.f) {
+    ScaleOp scale_op(post_scale.width(), post_scale.height());
+    SerializeOp(&scale_op, options, params);
+  }
+
+  SerializeBuffer(buffer, nullptr);
+}
+
 void PaintOpBufferSerializer::SerializePreamble(
     const Preamble& preamble,
     const PaintOp::SerializeOptions& options,
     const PlaybackParams& params) {
-  if (!preamble.translation.IsZero()) {
-    TranslateOp translate_op(-preamble.translation.x(),
-                             -preamble.translation.y());
+  DCHECK(preamble.full_raster_rect.Contains(preamble.playback_rect))
+      << "full: " << preamble.full_raster_rect.ToString()
+      << ", playback: " << preamble.playback_rect.ToString();
+
+  // Should full clears be clipped?
+  bool is_partial_raster = preamble.full_raster_rect != preamble.playback_rect;
+
+  // If rastering the entire tile, clear pre-clip.  This is so that any
+  // external texels outside of the playback rect also get cleared.  There's
+  // not enough information at this point to know if this texture is being
+  // reused from another tile, so the external texels could have been
+  // cleared to some wrong value.
+  if (preamble.requires_clear && !is_partial_raster) {
+    // If the tile is transparent, then just clear the whole thing.
+    DrawColorOp clear(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
+    SerializeOp(&clear, options, params);
+  } else if (!is_partial_raster) {
+    // The last texel of this content is not guaranteed to be fully opaque, so
+    // inset by one to generate the fully opaque coverage rect .  This rect is
+    // in device space.
+    SkIRect coverage_device_rect = SkIRect::MakeWH(
+        preamble.content_size.width() - preamble.full_raster_rect.x() - 1,
+        preamble.content_size.height() - preamble.full_raster_rect.y() - 1);
+
+    SkIRect playback_device_rect = gfx::RectToSkIRect(preamble.playback_rect);
+    playback_device_rect.fLeft -= preamble.full_raster_rect.x();
+    playback_device_rect.fTop -= preamble.full_raster_rect.y();
+
+    // If not fully covered, we need to clear one texel inside the coverage rect
+    // (because of blending during raster) and one texel outside the full raster
+    // rect (because of bilinear filtering during draw).  See comments in
+    // RasterSource.
+    SkIRect device_column = SkIRect::MakeXYWH(coverage_device_rect.right(), 0,
+                                              2, coverage_device_rect.bottom());
+    // row includes the corner, column excludes it.
+    SkIRect device_row = SkIRect::MakeXYWH(0, coverage_device_rect.bottom(),
+                                           coverage_device_rect.right() + 2, 2);
+    // Only bother clearing if we need to.
+    if (SkIRect::Intersects(device_column, playback_device_rect)) {
+      Save(options, params);
+      ClipRectOp clip_op(SkRect::MakeFromIRect(device_column),
+                         SkClipOp::kIntersect, false);
+      SerializeOp(&clip_op, options, params);
+      DrawColorOp clear_op(preamble.background_color, SkBlendMode::kSrc);
+      SerializeOp(&clear_op, options, params);
+      RestoreToCount(1, options, params);
+    }
+    if (SkIRect::Intersects(device_row, playback_device_rect)) {
+      Save(options, params);
+      ClipRectOp clip_op(SkRect::MakeFromIRect(device_row),
+                         SkClipOp::kIntersect, false);
+      SerializeOp(&clip_op, options, params);
+      DrawColorOp clear_op(preamble.background_color, SkBlendMode::kSrc);
+      SerializeOp(&clear_op, options, params);
+      RestoreToCount(1, options, params);
+    }
+  }
+
+  if (!preamble.full_raster_rect.OffsetFromOrigin().IsZero()) {
+    TranslateOp translate_op(-preamble.full_raster_rect.x(),
+                             -preamble.full_raster_rect.y());
     SerializeOp(&translate_op, options, params);
   }
 
   if (!preamble.playback_rect.IsEmpty()) {
-    ClipRectOp clip_op(gfx::RectFToSkRect(preamble.playback_rect),
+    ClipRectOp clip_op(gfx::RectToSkRect(preamble.playback_rect),
                        SkClipOp::kIntersect, false);
     SerializeOp(&clip_op, options, params);
   }
@@ -102,6 +185,14 @@
     ScaleOp scale_op(preamble.post_scale.width(), preamble.post_scale.height());
     SerializeOp(&scale_op, options, params);
   }
+
+  // If tile is transparent and this is partial raster, just clear the
+  // section that is being rastered.  If this is opaque, trust the raster
+  // to write all the pixels inside of the full_raster_rect.
+  if (preamble.requires_clear && is_partial_raster) {
+    DrawColorOp clear_op(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
+    SerializeOp(&clear_op, options, params);
+  }
 }
 
 void PaintOpBufferSerializer::SerializeBuffer(
diff --git a/cc/paint/paint_op_buffer_serializer.h b/cc/paint/paint_op_buffer_serializer.h
index b7e55e5c..af793ef 100644
--- a/cc/paint/paint_op_buffer_serializer.h
+++ b/cc/paint/paint_op_buffer_serializer.h
@@ -24,20 +24,44 @@
   virtual ~PaintOpBufferSerializer();
 
   struct Preamble {
-    gfx::Vector2dF translation;
-    gfx::RectF playback_rect;
+    // The full size of the content, to know whether edge texel clearing
+    // is required or not.  The full_raster_rect and playback_rect must
+    // be contained in this size.
+    gfx::Size content_size;
+    // Rect in content space (1 unit = 1 pixel) of this tile.
+    gfx::Rect full_raster_rect;
+    // A subrect in content space (full_raster_rect must contain this) of
+    // the partial content to play back.
+    gfx::Rect playback_rect;
+    // The translation and scale to do after
     gfx::Vector2dF post_translation;
     gfx::SizeF post_scale = gfx::SizeF(1.f, 1.f);
+    // If requires_clear is true, then this will raster will be cleared to
+    // transparent.  If false, it assumes that the content will raster
+    // opaquely up to content_size inset by 1 (with the last pixel being
+    // potentially being partially transparent, if post scaled).
+    bool requires_clear = true;
+    // If clearing is needed, the color to clear to.
+    SkColor background_color = SK_ColorTRANSPARENT;
   };
   // Serialize the buffer with a preamble. This function wraps the buffer in a
-  // save/restore and includes any translations and/or scales as specified by
-  // the preamble.
+  // save/restore and includes any translations, scales, and clearing as
+  // specified by the preamble.  This should generally be used for top level
+  // rastering of an entire tile.
   void Serialize(const PaintOpBuffer* buffer,
                  const std::vector<size_t>* offsets,
                  const Preamble& preamble);
   // Serialize the buffer without a preamble. This function serializes the whole
-  // buffer without any extra ops added.
+  // buffer without any extra ops added.  No clearing is done.  This should
+  // generally be used for internal PaintOpBuffers that want to be sent as-is.
   void Serialize(const PaintOpBuffer* buffer);
+  // Serialize the buffer with a scale and a playback rect.  This should
+  // generally be used for internal PaintOpBuffers in PaintShaders that have
+  // a scale and a tiling, but don't want the clearing or other complicated
+  // logic of the top level Serialize.
+  void Serialize(const PaintOpBuffer* buffer,
+                 const gfx::Rect& playback_rect,
+                 const gfx::SizeF& post_scale);
 
   bool valid() const { return valid_; }
 
diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc
index 61e698d..b7c5d32 100644
--- a/cc/paint/paint_op_buffer_unittest.cc
+++ b/cc/paint/paint_op_buffer_unittest.cc
@@ -1984,7 +1984,10 @@
   PushDrawIRectOps(&buffer);
 
   PaintOpBufferSerializer::Preamble preamble;
-  preamble.playback_rect = gfx::RectF(1000.f, 1000.f);
+  preamble.content_size = gfx::Size(1000, 1000);
+  preamble.playback_rect = gfx::Rect(preamble.content_size);
+  preamble.full_raster_rect = preamble.playback_rect;
+  preamble.requires_clear = true;
 
   std::unique_ptr<char, base::AlignedFreeDeleter> memory(
       static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
@@ -2002,9 +2005,9 @@
                                     options_provider.deserialize_options());
   ASSERT_TRUE(deserialized_buffer);
 
-  // The deserialized buffer has an extra pair of save/restores, for the
-  // preamble and root buffer.
-  ASSERT_EQ(deserialized_buffer->size(), buffer.size() + 3u);
+  // The deserialized buffer has an extra pair of save/restores and a clear, for
+  // the preamble and root buffer.
+  ASSERT_EQ(deserialized_buffer->size(), buffer.size() + 4u);
 
   size_t i = 0;
   auto serialized_iter = PaintOpBuffer::Iterator(&buffer);
@@ -2020,11 +2023,17 @@
     }
 
     if (i == 2) {
-      // Preamble.
+      // Preamble partial raster clear.
+      ASSERT_EQ(op->GetType(), PaintOpType::DrawColor)
+          << PaintOpTypeToString(op->GetType());
+      continue;
+    }
+    if (i == 3) {
+      // Preamble playback rect clip.
       ASSERT_EQ(op->GetType(), PaintOpType::ClipRect)
           << PaintOpTypeToString(op->GetType());
       EXPECT_EQ(static_cast<const ClipRectOp*>(op)->rect,
-                gfx::RectFToSkRect(preamble.playback_rect));
+                gfx::RectToSkRect(preamble.playback_rect));
       continue;
     }
 
@@ -2045,10 +2054,12 @@
 
 TEST(PaintOpSerializationTest, Preamble) {
   PaintOpBufferSerializer::Preamble preamble;
-  preamble.translation = gfx::Vector2dF(10.f, 20.f);
-  preamble.playback_rect = gfx::RectF(5.f, 5.f);
+  preamble.content_size = gfx::Size(30, 40);
+  preamble.full_raster_rect = gfx::Rect(10, 20, 8, 7);
+  preamble.playback_rect = gfx::Rect(12, 25, 1, 2);
   preamble.post_translation = gfx::Vector2dF(4.3f, 7.f);
   preamble.post_scale = gfx::SizeF(0.5f, 0.5f);
+  preamble.requires_clear = true;
 
   PaintOpBuffer buffer;
   buffer.push<DrawColorOp>(SK_ColorBLUE, SkBlendMode::kSrc);
@@ -2068,8 +2079,8 @@
       PaintOpBuffer::MakeFromMemory(memory.get(), serializer.written(),
                                     options_provider.deserialize_options());
   ASSERT_TRUE(deserialized_buffer);
-  // 4 ops for the preamble and 2 for save/restore.
-  ASSERT_EQ(deserialized_buffer->size(), buffer.size() + 6u);
+  // 5 ops for the preamble and 2 for save/restore.
+  ASSERT_EQ(deserialized_buffer->size(), buffer.size() + 7u);
 
   size_t i = 0;
   for (const auto* op : PaintOpBuffer::Iterator(deserialized_buffer.get())) {
@@ -2087,8 +2098,8 @@
       ASSERT_EQ(op->GetType(), PaintOpType::Translate)
           << PaintOpTypeToString(op->GetType());
       const auto* translate_op = static_cast<const TranslateOp*>(op);
-      EXPECT_EQ(translate_op->dx, -preamble.translation.x());
-      EXPECT_EQ(translate_op->dy, -preamble.translation.y());
+      EXPECT_EQ(translate_op->dx, -preamble.full_raster_rect.x());
+      EXPECT_EQ(translate_op->dy, -preamble.full_raster_rect.y());
       continue;
     }
 
@@ -2123,6 +2134,16 @@
     }
 
     if (i == 6) {
+      // Partial raster clear goes last.
+      ASSERT_EQ(op->GetType(), PaintOpType::DrawColor)
+          << PaintOpTypeToString(op->GetType());
+      const auto* draw_color_op = static_cast<const DrawColorOp*>(op);
+      EXPECT_EQ(draw_color_op->color, SK_ColorTRANSPARENT);
+      EXPECT_EQ(draw_color_op->mode, SkBlendMode::kSrc);
+      continue;
+    }
+
+    if (i == 7) {
       // Buffer.
       EXPECT_EQ(*op, *buffer.GetFirstOp());
       continue;
@@ -2157,18 +2178,24 @@
       PaintOpBuffer::MakeFromMemory(memory.get(), serializer.written(),
                                     options_provider.deserialize_options());
   ASSERT_TRUE(deserialized_buffer);
-  ASSERT_EQ(deserialized_buffer->size(), record->size() + 4u);
+  ASSERT_EQ(deserialized_buffer->size(), record->size() + 5u);
 
   size_t i = 0;
   auto serialized_iter = PaintOpBuffer::Iterator(record.get());
   for (const auto* op : PaintOpBuffer::Iterator(deserialized_buffer.get())) {
     i++;
-    if (i <= 2) {
+    if (i == 1 || i == 3) {
       // First 2 saves.
       ASSERT_EQ(op->GetType(), PaintOpType::Save)
           << PaintOpTypeToString(op->GetType());
       continue;
     }
+    // Clear.
+    if (i == 2) {
+      ASSERT_EQ(op->GetType(), PaintOpType::DrawColor)
+          << PaintOpTypeToString(op->GetType());
+      continue;
+    }
 
     if (serialized_iter) {
       // Nested buffer.
@@ -2216,7 +2243,12 @@
                                       options_provider.image_provider(),
                                       options_provider.transfer_cache_helper());
     PaintOpBufferSerializer::Preamble preamble;
-    preamble.playback_rect = gfx::RectF(test_case.clip_rect);
+    preamble.playback_rect = test_case.clip_rect;
+    preamble.full_raster_rect = gfx::Rect(0, 0, test_case.clip_rect.right(),
+                                          test_case.clip_rect.bottom());
+    // Avoid clearing.
+    preamble.content_size = gfx::Size(1000, 1000);
+    preamble.requires_clear = false;
     serializer.Serialize(&buffer, nullptr, preamble);
     ASSERT_NE(serializer.written(), 0u);
 
@@ -2258,7 +2290,10 @@
   buffer.push<RestoreOp>();
 
   PaintOpBufferSerializer::Preamble preamble;
-  preamble.playback_rect = gfx::RectF(1000.f, 1000.f);
+  preamble.content_size = gfx::Size(1000, 1000);
+  preamble.playback_rect = gfx::Rect(gfx::Size(100, 100));
+  preamble.full_raster_rect = preamble.playback_rect;
+  preamble.requires_clear = false;
 
   std::unique_ptr<char, base::AlignedFreeDeleter> memory(
       static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize,
@@ -2276,7 +2311,7 @@
                                     options_provider.deserialize_options());
   ASSERT_TRUE(deserialized_buffer);
 
-  // 3 additional ops for save, clip and restore.
+  // 4 additional ops for save, clip, clear, and restore.
   ASSERT_EQ(deserialized_buffer->size(), 4u);
   size_t i = 0;
   for (const auto* op : PaintOpBuffer::Iterator(deserialized_buffer.get())) {
diff --git a/cc/paint/paint_op_writer.cc b/cc/paint/paint_op_writer.cc
index 8421035..4e4aaf5 100644
--- a/cc/paint/paint_op_writer.cc
+++ b/cc/paint/paint_op_writer.cc
@@ -13,6 +13,7 @@
 #include "cc/paint/paint_typeface_transfer_cache_entry.h"
 #include "cc/paint/transfer_cache_serialize_helper.h"
 #include "third_party/skia/include/core/SkTextBlob.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/skia_util.h"
 
 namespace cc {
@@ -244,13 +245,15 @@
   Write(shader->image_);
   if (shader->record_) {
     Write(true);
-    base::Optional<PaintOpBufferSerializer::Preamble> preamble;
+    base::Optional<gfx::Rect> playback_rect;
+    base::Optional<gfx::SizeF> post_scale;
     if (shader->tile_scale()) {
-      preamble.emplace();
-      preamble->playback_rect = gfx::SkRectToRectF(shader->tile());
-      preamble->post_scale = *shader->tile_scale();
+      playback_rect.emplace(
+          gfx::ToEnclosingRect(gfx::SkRectToRectF(shader->tile())));
+      post_scale.emplace(*shader->tile_scale());
     }
-    Write(shader->record_.get(), std::move(preamble));
+    Write(shader->record_.get(), std::move(playback_rect),
+          std::move(post_scale));
   } else {
     Write(false);
   }
@@ -565,9 +568,10 @@
   Write(filter.input().get());
 }
 
-void PaintOpWriter::Write(
-    const PaintRecord* record,
-    base::Optional<PaintOpBufferSerializer::Preamble> preamble) {
+void PaintOpWriter::Write(const PaintRecord* record,
+                          base::Optional<gfx::Rect> playback_rect,
+                          base::Optional<gfx::SizeF> post_scale) {
+  DCHECK_EQ(playback_rect.has_value(), post_scale.has_value());
   // We need to record how many bytes we will serialize, but we don't know this
   // information until we do the serialization. So, skip the amount needed
   // before writing.
@@ -593,10 +597,11 @@
 
   SimpleBufferSerializer serializer(memory_, remaining_bytes_, image_provider_,
                                     transfer_cache_);
-  if (preamble)
-    serializer.Serialize(record, nullptr, *preamble);
-  else
+  if (playback_rect) {
+    serializer.Serialize(record, *playback_rect, *post_scale);
+  } else {
     serializer.Serialize(record);
+  }
 
   if (!serializer.valid()) {
     valid_ = false;
diff --git a/cc/paint/paint_op_writer.h b/cc/paint/paint_op_writer.h
index 98ff494..6aeaeb55 100644
--- a/cc/paint/paint_op_writer.h
+++ b/cc/paint/paint_op_writer.h
@@ -121,8 +121,8 @@
   void Write(const LightingSpotPaintFilter& filter);
 
   void Write(const PaintRecord* record,
-             base::Optional<PaintOpBufferSerializer::Preamble> preamble =
-                 base::nullopt);
+             base::Optional<gfx::Rect> playback_rect = base::nullopt,
+             base::Optional<gfx::SizeF> post_scale = base::nullopt);
   void Write(const PaintImage& image);
   void Write(const SkRegion& region);
 
diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc
index df582c8e..58f2663b 100644
--- a/cc/raster/gpu_raster_buffer_provider.cc
+++ b/cc/raster/gpu_raster_buffer_provider.cc
@@ -37,7 +37,6 @@
 static void RasterizeSourceOOP(
     const RasterSource* raster_source,
     bool resource_has_previous_content,
-    const gfx::Size& resource_size,
     const gfx::Rect& raster_full_rect,
     const gfx::Rect& playback_rect,
     const gfx::AxisTransform2d& transform,
@@ -55,10 +54,15 @@
                           playback_settings.raster_color_space);
   float recording_to_raster_scale =
       transform.scale() / raster_source->recording_scale_factor();
+  gfx::Size content_size = raster_source->GetContentSize(transform.scale());
+  // TODO(enne): could skip the clear on new textures, as the service side has
+  // to do that anyway.  resource_has_previous_content implies that the texture
+  // is not new, but the reverse does not hold, so more plumbing is needed.
   ri->RasterCHROMIUM(raster_source->GetDisplayItemList().get(),
-                     playback_settings.image_provider,
-                     raster_full_rect.OffsetFromOrigin(), playback_rect,
-                     transform.translation(), recording_to_raster_scale);
+                     playback_settings.image_provider, content_size,
+                     raster_full_rect, playback_rect, transform.translation(),
+                     recording_to_raster_scale,
+                     raster_source->requires_clear());
   ri->EndRasterCHROMIUM();
 
   ri->DeleteTextures(1, &texture_id);
@@ -88,7 +92,6 @@
 static void RasterizeSource(
     const RasterSource* raster_source,
     bool resource_has_previous_content,
-    const gfx::Size& resource_size,
     const gfx::Rect& raster_full_rect,
     const gfx::Rect& playback_rect,
     const gfx::AxisTransform2d& transform,
@@ -123,9 +126,10 @@
     if (raster_full_rect == playback_rect)
       canvas->discard();
 
+    gfx::Size content_size = raster_source->GetContentSize(transform.scale());
     raster_source->PlaybackToCanvas(
-        canvas, resource_lock->color_space_for_raster(), raster_full_rect,
-        playback_rect, transform, playback_settings);
+        canvas, resource_lock->color_space_for_raster(), content_size,
+        raster_full_rect, playback_rect, transform, playback_settings);
   }
 
   ri->DeleteTextures(1, &texture_id);
@@ -319,17 +323,15 @@
   }
 
   if (enable_oop_rasterization_) {
-    RasterizeSourceOOP(raster_source, resource_has_previous_content,
-                       resource_lock->size(), raster_full_rect, playback_rect,
-                       transform, playback_settings, worker_context_provider_,
-                       resource_lock, use_distance_field_text_,
-                       msaa_sample_count_);
+    RasterizeSourceOOP(
+        raster_source, resource_has_previous_content, raster_full_rect,
+        playback_rect, transform, playback_settings, worker_context_provider_,
+        resource_lock, use_distance_field_text_, msaa_sample_count_);
   } else {
     RasterizeSource(raster_source, resource_has_previous_content,
-                    resource_lock->size(), raster_full_rect, playback_rect,
-                    transform, playback_settings, worker_context_provider_,
-                    resource_lock, use_distance_field_text_,
-                    msaa_sample_count_);
+                    raster_full_rect, playback_rect, transform,
+                    playback_settings, worker_context_provider_, resource_lock,
+                    use_distance_field_text_, msaa_sample_count_);
   }
 
   // Generate sync token for cross context synchronization.
diff --git a/cc/raster/raster_buffer_provider.cc b/cc/raster/raster_buffer_provider.cc
index d11ae43..1cef946 100644
--- a/cc/raster/raster_buffer_provider.cc
+++ b/cc/raster/raster_buffer_provider.cc
@@ -78,6 +78,8 @@
     stride = info.minRowBytes();
   DCHECK_GT(stride, 0u);
 
+  gfx::Size content_size = raster_source->GetContentSize(transform.scale());
+
   switch (format) {
     case viz::RGBA_8888:
     case viz::BGRA_8888:
@@ -90,8 +92,9 @@
       // See: http://crbug.com/721744.
       CHECK(surface);
       raster_source->PlaybackToCanvas(surface->getCanvas(), target_color_space,
-                                      canvas_bitmap_rect, canvas_playback_rect,
-                                      transform, playback_settings);
+                                      content_size, canvas_bitmap_rect,
+                                      canvas_playback_rect, transform,
+                                      playback_settings);
       return;
     }
     case viz::RGBA_4444:
@@ -99,9 +102,9 @@
       sk_sp<SkSurface> surface = SkSurface::MakeRaster(info, &surface_props);
       // TODO(reveman): Improve partial raster support by reducing the size of
       // playback rect passed to PlaybackToCanvas. crbug.com/519070
-      raster_source->PlaybackToCanvas(surface->getCanvas(), target_color_space,
-                                      canvas_bitmap_rect, canvas_bitmap_rect,
-                                      transform, playback_settings);
+      raster_source->PlaybackToCanvas(
+          surface->getCanvas(), target_color_space, content_size,
+          canvas_bitmap_rect, canvas_bitmap_rect, transform, playback_settings);
 
       if (format == viz::ETC1) {
         TRACE_EVENT0("cc",
diff --git a/cc/raster/raster_buffer_provider_perftest.cc b/cc/raster/raster_buffer_provider_perftest.cc
index 908a0122..0812013 100644
--- a/cc/raster/raster_buffer_provider_perftest.cc
+++ b/cc/raster/raster_buffer_provider_perftest.cc
@@ -353,8 +353,11 @@
     switch (GetParam()) {
       case RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY:
         Create3dResourceProvider();
-        raster_buffer_provider_ = ZeroCopyRasterBufferProvider::Create(
-            resource_provider_.get(), viz::PlatformColor::BestTextureFormat());
+        raster_buffer_provider_ =
+            std::make_unique<ZeroCopyRasterBufferProvider>(
+                resource_provider_.get(), &gpu_memory_buffer_manager_,
+                compositor_context_provider_.get(),
+                viz::PlatformColor::BestTextureFormat());
         resource_pool_ = std::make_unique<ResourcePool>(
             resource_provider_.get(), task_runner_,
             gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
diff --git a/cc/raster/raster_buffer_provider_unittest.cc b/cc/raster/raster_buffer_provider_unittest.cc
index 29832ba..3afd4b87 100644
--- a/cc/raster/raster_buffer_provider_unittest.cc
+++ b/cc/raster/raster_buffer_provider_unittest.cc
@@ -157,8 +157,11 @@
     switch (GetParam()) {
       case RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY:
         Create3dResourceProvider();
-        raster_buffer_provider_ = ZeroCopyRasterBufferProvider::Create(
-            resource_provider_.get(), viz::PlatformColor::BestTextureFormat());
+        raster_buffer_provider_ =
+            std::make_unique<ZeroCopyRasterBufferProvider>(
+                resource_provider_.get(), &gpu_memory_buffer_manager_,
+                context_provider_.get(),
+                viz::PlatformColor::BestTextureFormat());
         pool_ = std::make_unique<ResourcePool>(
             resource_provider_.get(), base::ThreadTaskRunnerHandle::Get(),
             gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, base::TimeDelta(), true);
diff --git a/cc/raster/raster_source.cc b/cc/raster/raster_source.cc
index d82cb170..61d356f0 100644
--- a/cc/raster/raster_source.cc
+++ b/cc/raster/raster_source.cc
@@ -49,15 +49,72 @@
       solid_color_(other->solid_color_),
       recorded_viewport_(other->recorded_viewport_),
       size_(other->size_),
-      clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_),
       slow_down_raster_scale_factor_for_debug_(
           other->slow_down_raster_scale_factor_for_debug_),
       recording_scale_factor_(other->recording_scale_factor_) {}
 RasterSource::~RasterSource() = default;
 
-void RasterSource::PlaybackToCanvas(
+void RasterSource::ClearForFullRaster(
     SkCanvas* raster_canvas,
+    const gfx::Size& content_size,
+    const gfx::Rect& canvas_bitmap_rect,
+    const gfx::Rect& canvas_playback_rect) const {
+  // If this raster source has opaque contents, it is guaranteeing that it
+  // will draw an opaque rect the size of the layer.  If it is not, then we
+  // must clear this canvas ourselves (i.e. requires_clear_).
+  if (requires_clear_) {
+    TrackRasterSourceNeededClear(RasterSourceClearType::kFull);
+    raster_canvas->clear(SK_ColorTRANSPARENT);
+    return;
+  }
+
+  // The last texel of this content is not guaranteed to be fully opaque, so
+  // inset by one to generate the fully opaque coverage rect .  This rect is
+  // in device space.
+  SkIRect coverage_device_rect =
+      SkIRect::MakeWH(content_size.width() - canvas_bitmap_rect.x() - 1,
+                      content_size.height() - canvas_bitmap_rect.y() - 1);
+
+  // Remove playback rect offset, which is equal to bitmap rect offset,
+  // as this is full raster.
+  SkIRect playback_device_rect = SkIRect::MakeWH(canvas_playback_rect.width(),
+                                                 canvas_playback_rect.height());
+
+  // If not fully covered, we need to clear one texel inside the coverage
+  // rect (because of blending during raster) and one texel outside the full
+  // raster rect (because of bilinear filtering during draw).  See comments
+  // in RasterSource.
+  SkIRect device_column = SkIRect::MakeXYWH(coverage_device_rect.right(), 0, 2,
+                                            coverage_device_rect.bottom());
+  // row includes the corner, column excludes it.
+  SkIRect device_row = SkIRect::MakeXYWH(0, coverage_device_rect.bottom(),
+                                         coverage_device_rect.right() + 2, 2);
+
+  RasterSourceClearType clear_type = RasterSourceClearType::kNone;
+  // Only bother clearing if we need to.
+  if (SkIRect::Intersects(device_column, playback_device_rect)) {
+    clear_type = RasterSourceClearType::kBorder;
+    raster_canvas->save();
+    raster_canvas->clipRect(SkRect::MakeFromIRect(device_column),
+                            SkClipOp::kIntersect, false);
+    raster_canvas->drawColor(background_color_, SkBlendMode::kSrc);
+    raster_canvas->restore();
+  }
+  if (SkIRect::Intersects(device_row, playback_device_rect)) {
+    clear_type = RasterSourceClearType::kBorder;
+    raster_canvas->save();
+    raster_canvas->clipRect(SkRect::MakeFromIRect(device_row),
+                            SkClipOp::kIntersect, false);
+    raster_canvas->drawColor(background_color_, SkBlendMode::kSrc);
+    raster_canvas->restore();
+  }
+  TrackRasterSourceNeededClear(clear_type);
+}
+
+void RasterSource::PlaybackToCanvas(
+    SkCanvas* input_canvas,
     const gfx::ColorSpace& target_color_space,
+    const gfx::Size& content_size,
     const gfx::Rect& canvas_bitmap_rect,
     const gfx::Rect& canvas_playback_rect,
     const gfx::AxisTransform2d& raster_transform,
@@ -69,20 +126,6 @@
   // Treat all subnormal values as zero for performance.
   ScopedSubnormalFloatDisabler disabler;
 
-  raster_canvas->save();
-  raster_canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y());
-  raster_canvas->clipRect(SkRect::MakeFromIRect(raster_bounds));
-  raster_canvas->translate(raster_transform.translation().x(),
-                           raster_transform.translation().y());
-  raster_canvas->scale(raster_transform.scale() / recording_scale_factor_,
-                       raster_transform.scale() / recording_scale_factor_);
-  PlaybackToCanvas(raster_canvas, target_color_space, settings);
-  raster_canvas->restore();
-}
-
-void RasterSource::PlaybackToCanvas(SkCanvas* input_canvas,
-                                    const gfx::ColorSpace& target_color_space,
-                                    const PlaybackSettings& settings) const {
   // TODO(enne): color transform needs to be replicated in gles2_cmd_decoder
   SkCanvas* raster_canvas = input_canvas;
   std::unique_ptr<SkCanvas> color_transform_canvas;
@@ -92,91 +135,33 @@
     raster_canvas = color_transform_canvas.get();
   }
 
-  // Some tests want to avoid complicated clearing logic for consistency.
-  if (settings.clear_canvas_before_raster)
-    ClearCanvasForPlayback(raster_canvas);
+  bool is_partial_raster = canvas_bitmap_rect != canvas_playback_rect;
+  if (!is_partial_raster && settings.clear_canvas_before_raster) {
+    ClearForFullRaster(raster_canvas, content_size, canvas_bitmap_rect,
+                       canvas_playback_rect);
+  }
 
-  RasterCommon(raster_canvas, settings.image_provider);
+  raster_canvas->save();
+  raster_canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y());
+  raster_canvas->clipRect(SkRect::MakeFromIRect(raster_bounds));
+  raster_canvas->translate(raster_transform.translation().x(),
+                           raster_transform.translation().y());
+  raster_canvas->scale(raster_transform.scale() / recording_scale_factor_,
+                       raster_transform.scale() / recording_scale_factor_);
+
+  if (is_partial_raster && settings.clear_canvas_before_raster &&
+      requires_clear_) {
+    // TODO(enne): Should this be considered a partial clear?
+    TrackRasterSourceNeededClear(RasterSourceClearType::kFull);
+    raster_canvas->clear(SK_ColorTRANSPARENT);
+  }
+
+  PlaybackToCanvas(raster_canvas, settings.image_provider);
+  raster_canvas->restore();
 }
 
-void RasterSource::ClearCanvasForPlayback(SkCanvas* canvas) const {
-  // If this raster source has opaque contents, it is guaranteeing that it will
-  // draw an opaque rect the size of the layer.  If it is not, then we must
-  // clear this canvas ourselves.
-  if (requires_clear_) {
-    canvas->clear(SK_ColorTRANSPARENT);
-    TrackRasterSourceNeededClear(RasterSourceClearType::kFull);
-    return;
-  }
-
-  if (clear_canvas_with_debug_color_)
-    canvas->clear(DebugColors::NonPaintedFillColor());
-
-  // If the canvas wants us to raster with complex transform, it is hard to
-  // determine the exact region we must clear. Just clear everything.
-  // TODO(trchen): Optimize the common case that transformed content bounds
-  //               covers the whole clip region.
-  if (!canvas->getTotalMatrix().rectStaysRect()) {
-    canvas->clear(SK_ColorTRANSPARENT);
-    TrackRasterSourceNeededClear(RasterSourceClearType::kFull);
-    return;
-  }
-
-  SkRect content_device_rect;
-  canvas->getTotalMatrix().mapRect(
-      &content_device_rect, SkRect::MakeWH(size_.width(), size_.height()));
-
-  // The final texel of content may only be partially covered by a
-  // rasterization; this rect represents the content rect that is fully
-  // covered by content.
-  SkIRect opaque_rect;
-  content_device_rect.roundIn(&opaque_rect);
-
-  if (opaque_rect.contains(canvas->getDeviceClipBounds())) {
-    TrackRasterSourceNeededClear(RasterSourceClearType::kNone);
-    return;
-  }
-
-  // Even if completely covered, for rasterizations that touch the edge of the
-  // layer, we also need to raster the background color underneath the last
-  // texel (since the recording won't cover it) and outside the last texel
-  // (due to linear filtering when using this texture).
-  SkIRect interest_rect;
-  content_device_rect.roundOut(&interest_rect);
-  interest_rect.outset(1, 1);
-
-  if (clear_canvas_with_debug_color_) {
-    // Any non-painted areas outside of the content bounds are left in
-    // this color.  If this is seen then it means that cc neglected to
-    // rerasterize a tile that used to intersect with the content rect
-    // after the content bounds grew.
-    canvas->save();
-    // Use clipRegion to bypass CTM because the rects are device rects.
-    SkRegion interest_region;
-    interest_region.setRect(interest_rect);
-    canvas->clipRegion(interest_region, SkClipOp::kDifference);
-    canvas->clear(DebugColors::MissingResizeInvalidations());
-    canvas->restore();
-  }
-
-  // Drawing at most 2 x 2 x (canvas width + canvas height) texels is 2-3X
-  // faster than clearing, so special case this.
-  canvas->save();
-  // Use clipRegion to bypass CTM because the rects are device rects.
-  SkRegion interest_region;
-  interest_region.setRect(interest_rect);
-  interest_region.op(opaque_rect, SkRegion::kDifference_Op);
-  canvas->clipRegion(interest_region);
-  canvas->clear(background_color_);
-  canvas->restore();
-
-  // If we reached this point, we didn't perform a full clear, but a smaller
-  // clear of the border pixels.
-  TrackRasterSourceNeededClear(RasterSourceClearType::kBorder);
-}
-
-void RasterSource::RasterCommon(SkCanvas* raster_canvas,
-                                ImageProvider* image_provider) const {
+void RasterSource::PlaybackToCanvas(SkCanvas* raster_canvas,
+                                    ImageProvider* image_provider) const {
   DCHECK(display_list_.get());
   int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
   for (int i = 0; i < repeat_count; ++i)
@@ -190,7 +175,7 @@
   SkCanvas* canvas = recorder.beginRecording(size_.width(), size_.height());
   if (!size_.IsEmpty()) {
     canvas->clear(SK_ColorTRANSPARENT);
-    RasterCommon(canvas);
+    PlaybackToCanvas(canvas, nullptr);
   }
 
   return recorder.finishRecordingAsPicture();
@@ -236,6 +221,10 @@
   return size_;
 }
 
+gfx::Size RasterSource::GetContentSize(float content_scale) const {
+  return gfx::ScaleToCeiledSize(GetSize(), content_scale);
+}
+
 bool RasterSource::IsSolidColor() const {
   return is_solid_color_;
 }
diff --git a/cc/raster/raster_source.h b/cc/raster/raster_source.h
index a8ac30e7..33e0231f 100644
--- a/cc/raster/raster_source.h
+++ b/cc/raster/raster_source.h
@@ -57,6 +57,7 @@
   // the content space, so only a sub-rect of the tile gets rastered.
   void PlaybackToCanvas(SkCanvas* canvas,
                         const gfx::ColorSpace& target_color_space,
+                        const gfx::Size& content_size,
                         const gfx::Rect& canvas_bitmap_rect,
                         const gfx::Rect& canvas_playback_rect,
                         const gfx::AxisTransform2d& raster_transform,
@@ -64,16 +65,14 @@
 
   // Raster this RasterSource into the given canvas. Canvas states such as
   // CTM and clip region will be respected. This function will replace pixels
-  // in the clip region without blending. It is assumed that existing pixels
-  // may be uninitialized and will be cleared before playback.
+  // in the clip region without blending.
   //
   // Virtual for testing.
   //
   // Note that this should only be called after the image decode controller has
   // been set, which happens during commit.
   virtual void PlaybackToCanvas(SkCanvas* canvas,
-                                const gfx::ColorSpace& target_color_space,
-                                const PlaybackSettings& settings) const;
+                                ImageProvider* image_provider) const;
 
   // Returns whether the given rect at given scale is of solid color in
   // this raster source, as well as the solid color value.
@@ -86,9 +85,12 @@
   // are unspecified if IsSolidColor returns false.
   SkColor GetSolidColor() const;
 
-  // Returns the size of this raster source.
+  // Returns the recorded layer size of this raster source.
   gfx::Size GetSize() const;
 
+  // Returns the content size of this raster source at a particular scale.
+  gfx::Size GetContentSize(float content_scale) const;
+
   // Populate the given list with all images that may overlap the given
   // rect in layer space.
   void GetDiscardableImagesInRect(const gfx::Rect& layer_rect,
@@ -118,6 +120,8 @@
 
   SkColor background_color() const { return background_color_; }
 
+  bool requires_clear() const { return requires_clear_; }
+
   base::flat_map<PaintImage::Id, PaintImage::DecodingMode>
   TakeDecodingModeMap();
 
@@ -129,6 +133,11 @@
   explicit RasterSource(const RecordingSource* other);
   virtual ~RasterSource();
 
+  void ClearForFullRaster(SkCanvas* raster_canvas,
+                          const gfx::Size& content_size,
+                          const gfx::Rect& canvas_bitmap_rect,
+                          const gfx::Rect& canvas_playback_rect) const;
+
   // These members are const as this raster source may be in use on another
   // thread and so should not be touched after construction.
   const scoped_refptr<DisplayItemList> display_list_;
@@ -139,16 +148,9 @@
   const SkColor solid_color_;
   const gfx::Rect recorded_viewport_;
   const gfx::Size size_;
-  const bool clear_canvas_with_debug_color_;
   const int slow_down_raster_scale_factor_for_debug_;
   const float recording_scale_factor_;
 
- private:
-  void RasterCommon(SkCanvas* canvas,
-                    ImageProvider* image_provider = nullptr) const;
-
-  void ClearCanvasForPlayback(SkCanvas* canvas) const;
-
   DISALLOW_COPY_AND_ASSIGN(RasterSource);
 };
 
diff --git a/cc/raster/raster_source_unittest.cc b/cc/raster/raster_source_unittest.cc
index b89083e..311cb5ee 100644
--- a/cc/raster/raster_source_unittest.cc
+++ b/cc/raster/raster_source_unittest.cc
@@ -293,8 +293,8 @@
       canvas.clear(SK_ColorTRANSPARENT);
 
       raster->PlaybackToCanvas(
-          &canvas, ColorSpaceForTesting(), canvas_rect, canvas_rect,
-          gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
+          &canvas, ColorSpaceForTesting(), content_bounds, canvas_rect,
+          canvas_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
           RasterSource::PlaybackSettings());
 
       SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
@@ -345,8 +345,8 @@
   gfx::Rect raster_full_rect(content_bounds);
   gfx::Rect playback_rect(content_bounds);
   raster->PlaybackToCanvas(
-      &canvas, ColorSpaceForTesting(), raster_full_rect, playback_rect,
-      gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
+      &canvas, ColorSpaceForTesting(), content_bounds, raster_full_rect,
+      playback_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
       RasterSource::PlaybackSettings());
 
   {
@@ -377,8 +377,8 @@
   // that touches the edge pixels of the recording.
   playback_rect.Inset(1, 2, 0, 1);
   raster->PlaybackToCanvas(
-      &canvas, ColorSpaceForTesting(), raster_full_rect, playback_rect,
-      gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
+      &canvas, ColorSpaceForTesting(), content_bounds, raster_full_rect,
+      playback_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
       RasterSource::PlaybackSettings());
 
   SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
@@ -442,8 +442,8 @@
   gfx::Rect raster_full_rect(content_bounds);
   gfx::Rect playback_rect(content_bounds);
   raster->PlaybackToCanvas(
-      &canvas, ColorSpaceForTesting(), raster_full_rect, playback_rect,
-      gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
+      &canvas, ColorSpaceForTesting(), content_bounds, raster_full_rect,
+      playback_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
       RasterSource::PlaybackSettings());
 
   {
@@ -482,8 +482,8 @@
   playback_rect =
       gfx::Rect(gfx::ScaleToCeiledSize(partial_bounds, contents_scale));
   raster->PlaybackToCanvas(
-      &canvas, ColorSpaceForTesting(), raster_full_rect, playback_rect,
-      gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
+      &canvas, ColorSpaceForTesting(), content_bounds, raster_full_rect,
+      playback_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
       RasterSource::PlaybackSettings());
 
   // Test that the whole playback_rect was cleared and repainted with new alpha.
@@ -523,7 +523,7 @@
   SkCanvas canvas(bitmap);
 
   raster->PlaybackToCanvas(
-      &canvas, ColorSpaceForTesting(), canvas_rect, canvas_rect,
+      &canvas, ColorSpaceForTesting(), content_bounds, canvas_rect, canvas_rect,
       gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
       RasterSource::PlaybackSettings());
 
@@ -548,9 +548,6 @@
   EXPECT_LT(total_memory_usage, 2 * kReportedMemoryUsageInBytes);
 }
 
-// In debug there is a bunch of clearing to debug colors that makes mocking
-// very noisy and hard to test against.
-#ifdef NDEBUG
 TEST(RasterSourceTest, RasterTransformWithoutRecordingScale) {
   gfx::Size size(100, 100);
   float recording_scale = 2.f;
@@ -567,23 +564,17 @@
   SkMatrix m;
   m.setScale(1.f / recording_scale, 1.f / recording_scale);
 
+  // The recording source has no ops, so will only do the setup.
   EXPECT_CALL(mock_canvas, willSave()).InSequence(s);
-  // The call to raster_canvas->scale() should have values with the recording
-  // scale removed.
   EXPECT_CALL(mock_canvas, didConcat(m)).InSequence(s);
-
-  // Save/restore/clear around the paint ops being played back.
-  EXPECT_CALL(mock_canvas, willSave()).InSequence(s);
-  EXPECT_CALL(mock_canvas, OnDrawPaintWithColor(_)).InSequence(s);
   EXPECT_CALL(mock_canvas, willRestore()).InSequence(s);
 
-  EXPECT_CALL(mock_canvas, willRestore()).InSequence(s);
-
-  raster_source->PlaybackToCanvas(
-      &mock_canvas, ColorSpaceForTesting(), gfx::Rect(size), gfx::Rect(size),
-      gfx::AxisTransform2d(), RasterSource::PlaybackSettings());
+  gfx::Size small_size(50, 50);
+  raster_source->PlaybackToCanvas(&mock_canvas, ColorSpaceForTesting(), size,
+                                  gfx::Rect(small_size), gfx::Rect(small_size),
+                                  gfx::AxisTransform2d(),
+                                  RasterSource::PlaybackSettings());
 }
-#endif
 
 }  // namespace
 }  // namespace cc
diff --git a/cc/raster/zero_copy_raster_buffer_provider.cc b/cc/raster/zero_copy_raster_buffer_provider.cc
index 4cff236..10c0428d 100644
--- a/cc/raster/zero_copy_raster_buffer_provider.cc
+++ b/cc/raster/zero_copy_raster_buffer_provider.cc
@@ -9,28 +9,139 @@
 #include <algorithm>
 
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/stringprintf.h"
 #include "base/trace_event/trace_event.h"
 #include "base/trace_event/trace_event_argument.h"
 #include "cc/resources/layer_tree_resource_provider.h"
-#include "cc/resources/resource.h"
+#include "cc/resources/resource_pool.h"
+#include "components/viz/common/gpu/context_provider.h"
 #include "components/viz/common/resources/platform_color.h"
 #include "components/viz/common/resources/resource_format_utils.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
+#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
 #include "ui/gfx/buffer_format_util.h"
 #include "ui/gfx/gpu_memory_buffer.h"
 
 namespace cc {
 namespace {
 
+constexpr static auto kBufferUsage = gfx::BufferUsage::GPU_READ_CPU_READ_WRITE;
+
+// Subclass for InUsePoolResource that holds ownership of a zero-copy backing
+// and does cleanup of the backing when destroyed.
+class ZeroCopyGpuBacking : public ResourcePool::GpuBacking {
+ public:
+  ~ZeroCopyGpuBacking() override {
+    gpu::gles2::GLES2Interface* gl = compositor_context_provider->ContextGL();
+    if (returned_sync_token.HasData())
+      gl->WaitSyncTokenCHROMIUM(returned_sync_token.GetConstData());
+    if (texture_id)
+      gl->DeleteTextures(1, &texture_id);
+    if (image_id)
+      gl->DestroyImageCHROMIUM(image_id);
+  }
+
+  base::trace_event::MemoryAllocatorDumpGuid MemoryDumpGuid(
+      uint64_t tracing_process_id) override {
+    if (!gpu_memory_buffer)
+      return {};
+    return gpu_memory_buffer->GetGUIDForTracing(tracing_process_id);
+  }
+
+  base::UnguessableToken SharedMemoryGuid() override {
+    return gpu_memory_buffer->GetHandle().handle.GetGUID();
+  }
+
+  // The ContextProvider used to clean up the texture and image ids.
+  viz::ContextProvider* compositor_context_provider = nullptr;
+  // The backing for zero-copy gpu resources. The |texture_id| is bound to
+  // this.
+  std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer;
+  // The texture id bound to the GpuMemoryBuffer.
+  uint32_t texture_id = 0;
+  // The image id that associates the |gpu_memory_buffer| and the
+  // |texture_id|.
+  uint32_t image_id = 0;
+};
+
+// RasterBuffer for the zero copy upload, which is given to the raster worker
+// threads for raster/upload.
 class ZeroCopyRasterBufferImpl : public RasterBuffer {
  public:
   ZeroCopyRasterBufferImpl(
-      LayerTreeResourceProvider* resource_provider,
-      const ResourcePool::InUsePoolResource& in_use_resource)
-      : lock_(resource_provider, in_use_resource.gpu_backing_resource_id()),
+      viz::ContextProvider* context_provider,
+      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
+      const ResourcePool::InUsePoolResource& in_use_resource,
+      ZeroCopyGpuBacking* backing)
+      : backing_(backing),
+        gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
         resource_size_(in_use_resource.size()),
-        resource_format_(in_use_resource.format()) {}
+        resource_format_(in_use_resource.format()),
+        resource_color_space_(in_use_resource.color_space()),
+        gpu_memory_buffer_(std::move(backing_->gpu_memory_buffer)) {}
+
+  ~ZeroCopyRasterBufferImpl() override {
+    // This is destroyed on the compositor thread when raster is complete, but
+    // before the backing is prepared for export to the display compositor. So
+    // we can set up the texture and SyncToken here.
+    // TODO(danakj): This could be done with the worker context in Playback. Do
+    // we need to do things in IsResourceReadyToDraw() and OrderingBarrier then?
+    gpu::gles2::GLES2Interface* gl =
+        backing_->compositor_context_provider->ContextGL();
+    const gpu::Capabilities& caps =
+        backing_->compositor_context_provider->ContextCapabilities();
+
+    if (backing_->returned_sync_token.HasData()) {
+      gl->WaitSyncTokenCHROMIUM(backing_->returned_sync_token.GetConstData());
+      backing_->returned_sync_token = gpu::SyncToken();
+    }
+
+    if (!backing_->texture_id) {
+      // Make a texture and a mailbox for export of the GpuMemoryBuffer to the
+      // display compositor.
+      gl->GenTextures(1, &backing_->texture_id);
+      backing_->texture_target = gpu::GetBufferTextureTarget(
+          kBufferUsage, viz::BufferFormat(resource_format_), caps);
+      backing_->mailbox = gpu::Mailbox::Generate();
+      gl->ProduceTextureDirectCHROMIUM(backing_->texture_id,
+                                       backing_->mailbox.name);
+
+      gl->BindTexture(backing_->texture_target, backing_->texture_id);
+      gl->TexParameteri(backing_->texture_target, GL_TEXTURE_MIN_FILTER,
+                        GL_LINEAR);
+      gl->TexParameteri(backing_->texture_target, GL_TEXTURE_MAG_FILTER,
+                        GL_LINEAR);
+      gl->TexParameteri(backing_->texture_target, GL_TEXTURE_WRAP_S,
+                        GL_CLAMP_TO_EDGE);
+      gl->TexParameteri(backing_->texture_target, GL_TEXTURE_WRAP_T,
+                        GL_CLAMP_TO_EDGE);
+    } else {
+      gl->BindTexture(backing_->texture_target, backing_->texture_id);
+    }
+
+    if (!backing_->image_id) {
+      // If GpuMemoryBuffer allocation failed (https://crbug.com/554541), then
+      // we don't have anything to give to the display compositor, but also no
+      // way to report an error, so we just make a texture but don't bind
+      // anything to it..
+      if (gpu_memory_buffer_) {
+        backing_->image_id = gl->CreateImageCHROMIUM(
+            gpu_memory_buffer_->AsClientBuffer(), resource_size_.width(),
+            resource_size_.height(), viz::GLInternalFormat(resource_format_));
+        gl->BindTexImage2DCHROMIUM(backing_->texture_target,
+                                   backing_->image_id);
+      }
+    } else {
+      gl->ReleaseTexImage2DCHROMIUM(backing_->texture_target,
+                                    backing_->image_id);
+      gl->BindTexImage2DCHROMIUM(backing_->texture_target, backing_->image_id);
+    }
+    gl->BindTexture(backing_->texture_target, 0);
+
+    backing_->mailbox_sync_token =
+        LayerTreeResourceProvider::GenerateSyncTokenHelper(gl);
+    backing_->gpu_memory_buffer = std::move(gpu_memory_buffer_);
+  }
 
   // Overridden from RasterBuffer:
   void Playback(
@@ -41,48 +152,56 @@
       const gfx::AxisTransform2d& transform,
       const RasterSource::PlaybackSettings& playback_settings) override {
     TRACE_EVENT0("cc", "ZeroCopyRasterBuffer::Playback");
-    gfx::GpuMemoryBuffer* buffer = lock_.GetGpuMemoryBuffer();
-    if (!buffer)
-      return;
 
-    DCHECK_EQ(1u, gfx::NumberOfPlanesForBufferFormat(buffer->GetFormat()));
-    bool rv = buffer->Map();
+    if (!gpu_memory_buffer_) {
+      gpu_memory_buffer_ = gpu_memory_buffer_manager_->CreateGpuMemoryBuffer(
+          resource_size_, viz::BufferFormat(resource_format_), kBufferUsage,
+          gpu::kNullSurfaceHandle);
+      // GpuMemoryBuffer allocation can fail (https://crbug.com/554541).
+      if (!gpu_memory_buffer_)
+        return;
+    }
+
+    DCHECK_EQ(1u, gfx::NumberOfPlanesForBufferFormat(
+                      gpu_memory_buffer_->GetFormat()));
+    bool rv = gpu_memory_buffer_->Map();
     DCHECK(rv);
-    DCHECK(buffer->memory(0));
+    DCHECK(gpu_memory_buffer_->memory(0));
     // RasterBufferProvider::PlaybackToMemory only supports unsigned strides.
-    DCHECK_GE(buffer->stride(0), 0);
+    DCHECK_GE(gpu_memory_buffer_->stride(0), 0);
 
     // TODO(danakj): Implement partial raster with raster_dirty_rect.
     RasterBufferProvider::PlaybackToMemory(
-        buffer->memory(0), resource_format_, resource_size_, buffer->stride(0),
-        raster_source, raster_full_rect, raster_full_rect, transform,
-        lock_.color_space_for_raster(), playback_settings);
-    buffer->Unmap();
+        gpu_memory_buffer_->memory(0), resource_format_, resource_size_,
+        gpu_memory_buffer_->stride(0), raster_source, raster_full_rect,
+        raster_full_rect, transform, resource_color_space_, playback_settings);
+    gpu_memory_buffer_->Unmap();
   }
 
  private:
-  LayerTreeResourceProvider::ScopedWriteLockGpuMemoryBuffer lock_;
+  // This field may only be used on the compositor thread.
+  ZeroCopyGpuBacking* backing_;
+
+  // These fields are for use on the worker thread.
+  gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
   gfx::Size resource_size_;
   viz::ResourceFormat resource_format_;
+  gfx::ColorSpace resource_color_space_;
+  std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
 
   DISALLOW_COPY_AND_ASSIGN(ZeroCopyRasterBufferImpl);
 };
 
 }  // namespace
 
-// static
-std::unique_ptr<RasterBufferProvider> ZeroCopyRasterBufferProvider::Create(
-    LayerTreeResourceProvider* resource_provider,
-    viz::ResourceFormat preferred_tile_format) {
-  return base::WrapUnique<RasterBufferProvider>(
-      new ZeroCopyRasterBufferProvider(resource_provider,
-                                       preferred_tile_format));
-}
-
 ZeroCopyRasterBufferProvider::ZeroCopyRasterBufferProvider(
     LayerTreeResourceProvider* resource_provider,
+    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
+    viz::ContextProvider* compositor_context_provider,
     viz::ResourceFormat preferred_tile_format)
     : resource_provider_(resource_provider),
+      gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
+      compositor_context_provider_(compositor_context_provider),
       preferred_tile_format_(preferred_tile_format) {}
 
 ZeroCopyRasterBufferProvider::~ZeroCopyRasterBufferProvider() = default;
@@ -92,8 +211,17 @@
     const ResourcePool::InUsePoolResource& resource,
     uint64_t resource_content_id,
     uint64_t previous_content_id) {
-  return std::make_unique<ZeroCopyRasterBufferImpl>(resource_provider_,
-                                                    resource);
+  if (!resource.gpu_backing()) {
+    auto backing = std::make_unique<ZeroCopyGpuBacking>();
+    backing->compositor_context_provider = compositor_context_provider_;
+    resource.set_gpu_backing(std::move(backing));
+  }
+  ZeroCopyGpuBacking* backing =
+      static_cast<ZeroCopyGpuBacking*>(resource.gpu_backing());
+
+  return std::make_unique<ZeroCopyRasterBufferImpl>(
+      compositor_context_provider_, gpu_memory_buffer_manager_, resource,
+      backing);
 }
 
 void ZeroCopyRasterBufferProvider::OrderingBarrier() {
@@ -104,12 +232,12 @@
 
 viz::ResourceFormat ZeroCopyRasterBufferProvider::GetResourceFormat(
     bool must_support_alpha) const {
-  if (resource_provider_->IsTextureFormatSupported(preferred_tile_format_) &&
-      (DoesResourceFormatSupportAlpha(preferred_tile_format_) ||
-       !must_support_alpha)) {
-    return preferred_tile_format_;
+  if (resource_provider_->IsTextureFormatSupported(preferred_tile_format_)) {
+    if (!must_support_alpha)
+      return preferred_tile_format_;
+    if (DoesResourceFormatSupportAlpha(preferred_tile_format_))
+      return preferred_tile_format_;
   }
-
   return resource_provider_->best_texture_format();
 }
 
diff --git a/cc/raster/zero_copy_raster_buffer_provider.h b/cc/raster/zero_copy_raster_buffer_provider.h
index d78e24c109..2e4c8dc0 100644
--- a/cc/raster/zero_copy_raster_buffer_provider.h
+++ b/cc/raster/zero_copy_raster_buffer_provider.h
@@ -18,16 +18,21 @@
 }
 }
 
+namespace gpu {
+class GpuMemoryBufferManager;
+}
+
 namespace cc {
 class LayerTreeResourceProvider;
 
 class CC_EXPORT ZeroCopyRasterBufferProvider : public RasterBufferProvider {
  public:
-  ~ZeroCopyRasterBufferProvider() override;
-
-  static std::unique_ptr<RasterBufferProvider> Create(
+  ZeroCopyRasterBufferProvider(
       LayerTreeResourceProvider* resource_provider,
+      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
+      viz::ContextProvider* compositor_context_provider,
       viz::ResourceFormat preferred_tile_format);
+  ~ZeroCopyRasterBufferProvider() override;
 
   // Overridden from RasterBufferProvider:
   std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
@@ -47,15 +52,13 @@
       uint64_t pending_callback_id) const override;
   void Shutdown() override;
 
- protected:
-  ZeroCopyRasterBufferProvider(LayerTreeResourceProvider* resource_provider,
-                               viz::ResourceFormat preferred_tile_format);
-
  private:
   std::unique_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue()
       const;
 
   LayerTreeResourceProvider* resource_provider_;
+  gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
+  viz::ContextProvider* compositor_context_provider_;
   viz::ResourceFormat preferred_tile_format_;
 
   DISALLOW_COPY_AND_ASSIGN(ZeroCopyRasterBufferProvider);
diff --git a/cc/resources/layer_tree_resource_provider.cc b/cc/resources/layer_tree_resource_provider.cc
index e3845ab..8a55a5b 100644
--- a/cc/resources/layer_tree_resource_provider.cc
+++ b/cc/resources/layer_tree_resource_provider.cc
@@ -87,7 +87,12 @@
   ImportedResource(viz::ResourceId id,
                    const viz::TransferableResource& resource,
                    std::unique_ptr<viz::SingleReleaseCallback> release_callback)
-      : resource(resource), release_callback(std::move(release_callback)) {
+      : resource(resource),
+        release_callback(std::move(release_callback)),
+        // If the resource is immediately deleted, it returns the same SyncToken
+        // it came with. The client may need to wait on that before deleting the
+        // backing or reusing it.
+        returned_sync_token(resource.mailbox_holder.sync_token) {
     // Replace the |resource| id with the local id from this
     // LayerTreeResourceProvider.
     this->resource.id = id;
diff --git a/cc/resources/layer_tree_resource_provider_unittest.cc b/cc/resources/layer_tree_resource_provider_unittest.cc
index 0f41a4d..6a926810 100644
--- a/cc/resources/layer_tree_resource_provider_unittest.cc
+++ b/cc/resources/layer_tree_resource_provider_unittest.cc
@@ -98,8 +98,10 @@
   // The local id is different.
   EXPECT_NE(id, tran.id);
 
-  // No sync token was returned since the resource was never exported.
-  EXPECT_CALL(release, Released(gpu::SyncToken(), false));
+  // The same SyncToken that was sent is returned when the resource was never
+  // exported. The SyncToken may be from any context, and the ReleaseCallback
+  // may need to wait on it before interacting with the resource on its context.
+  EXPECT_CALL(release, Released(tran.mailbox_holder.sync_token, false));
   provider().RemoveImportedResource(id);
 }
 
diff --git a/cc/resources/resource_pool.cc b/cc/resources/resource_pool.cc
index 8615941..4a83bf0 100644
--- a/cc/resources/resource_pool.cc
+++ b/cc/resources/resource_pool.cc
@@ -149,7 +149,7 @@
 // TODO(danakj): When gpu raster buffer providers make their own backings,
 // then they need to switch to the else branch.
 #if DCHECK_IS_ON()
-    if (use_gpu_memory_buffers_ || use_gpu_resources_)
+    if (use_gpu_resources_)
       DCHECK(resource_provider_->CanLockForWrite(resource->resource_id()));
     else
       DCHECK(!resource->resource_id());
@@ -163,20 +163,6 @@
     if (resource->color_space() != color_space)
       continue;
 
-    if (!use_gpu_memory_buffers_ && !use_gpu_resources_) {
-      DCHECK(!resource->sync_token().HasData());
-    } else {
-      // TODO(danakj): This will have to happen for Gpu backed resources. We
-      // should make the RasterBufferProvider ask for the SyncToken, and wait on
-      // it before doing raster, then reset the SyncToken on the
-      // InUsePoolResource.
-      // if (resource->sync_token().HasData()) {
-      //   resource_provider_->WaitSyncToken(
-      //       resource->sync_token());
-      //   resource->set_sync_token(gpu::SyncToken());
-      // }
-    }
-
     // Transfer resource to |in_use_resources_|.
     in_use_resources_[resource->unique_id()] = std::move(*it);
     unused_resources_.erase(it);
@@ -195,8 +181,7 @@
 
   viz::ResourceId resource_id;
   if (use_gpu_memory_buffers_) {
-    resource_id = resource_provider_->CreateGpuMemoryBufferResource(
-        size, viz::ResourceTextureHint::kDefault, format, usage_, color_space);
+    resource_id = 0;
   } else if (use_gpu_resources_) {
     resource_id = resource_provider_->CreateGpuTextureResource(
         size, hint_, format, color_space);
@@ -293,26 +278,12 @@
 // TODO(danakj): When gpu raster buffer providers make their own backings,
 // then they need to switch to the else branch.
 #if DCHECK_IS_ON()
-    if (use_gpu_memory_buffers_ || use_gpu_resources_)
+    if (use_gpu_resources_)
       DCHECK(resource_provider_->CanLockForWrite(resource->resource_id()));
     else
       DCHECK(!resource->resource_id());
 #endif
 
-    if (!use_gpu_memory_buffers_ && !use_gpu_resources_) {
-      DCHECK(!resource->sync_token().HasData());
-    } else {
-      // TODO(danakj): This will have to happen for Gpu backed resources. We
-      // should make the RasterBufferProvider ask for the SyncToken, and wait on
-      // it before doing raster, then reset the SyncToken on the
-      // InUsePoolResource.
-      // if (resource->sync_token().HasData()) {
-      //   resource_provider_->WaitSyncToken(
-      //       resource->sync_token());
-      //   resource->set_sync_token(gpu::SyncToken());
-      // }
-    }
-
     // Transfer resource to |in_use_resources_|.
     in_use_resources_[resource->unique_id()] =
         std::move(*iter_resource_to_return);
@@ -360,7 +331,10 @@
   }
 
   resource->set_resource_id(0);
-  resource->set_sync_token(sync_token);
+  // TODO(danakj): Use this branch for gpu resources that aren't gpu memory
+  // buffers.
+  if (use_gpu_memory_buffers_)
+    resource->gpu_backing()->returned_sync_token = sync_token;
   DidFinishUsingResource(std::move(*busy_it));
   busy_resources_.erase(busy_it);
 }
@@ -368,13 +342,27 @@
 void ResourcePool::PrepareForExport(const InUsePoolResource& resource) {
   // TODO(danakj): Add branches for gpu too once a gpu-backed raster provider
   // does this.
-  if (use_gpu_memory_buffers_ || use_gpu_resources_)
+  if (use_gpu_resources_)
     return;
 
-  auto transferable = viz::TransferableResource::MakeSoftware(
-      resource.resource_->shared_bitmap()->id(),
-      resource.resource_->shared_bitmap()->sequence_number(),
-      resource.resource_->size());
+  viz::TransferableResource transferable;
+  if (use_gpu_memory_buffers_) {
+    transferable = viz::TransferableResource::MakeGLOverlay(
+        resource.resource_->gpu_backing()->mailbox, GL_LINEAR,
+        resource.resource_->gpu_backing()->texture_target,
+        resource.resource_->gpu_backing()->mailbox_sync_token,
+        resource.resource_->size(),
+        /*is_overlay_candidate=*/true);
+    // Clear the SyncToken that we have sent away to the display compositor. It
+    // will be owned by the ResourceProvider now.
+    resource.resource_->gpu_backing()->mailbox_sync_token = gpu::SyncToken();
+  } else {
+    transferable = viz::TransferableResource::MakeSoftware(
+        resource.resource_->shared_bitmap()->id(),
+        resource.resource_->shared_bitmap()->sequence_number(),
+        resource.resource_->size());
+  }
+  transferable.color_space = resource.resource_->color_space();
   resource.resource_->set_resource_id(resource_provider_->ImportResource(
       std::move(transferable),
       viz::SingleReleaseCallback::Create(base::BindOnce(
@@ -438,7 +426,7 @@
 
   // TODO(danakj): When gpu raster buffer providers make their own backings,
   // then they need to switch to this branch.
-  if (!use_gpu_memory_buffers_ && !use_gpu_resources_) {
+  if (!use_gpu_resources_) {
     // If the resource was exported, then it has a resource id. By removing the
     // resource id, we will be notified in the ReleaseCallback when the resource
     // is no longer exported and can be reused.
@@ -499,7 +487,7 @@
   --total_resource_count_;
   // TODO(danakj): When gpu raster buffer providers make their own backings,
   // then they need to switch off this branch.
-  if (use_gpu_memory_buffers_ || use_gpu_resources_)
+  if (use_gpu_resources_)
     resource_provider_->DeleteResource(resource->resource_id());
 }
 
@@ -518,7 +506,7 @@
 void ResourcePool::CheckBusyResources() {
   // TODO(danakj): When gpu raster buffer providers make their own backings,
   // then they need to switch to this branch.
-  if (!use_gpu_memory_buffers_ && !use_gpu_resources_) {
+  if (!use_gpu_resources_) {
     // The ReleaseCallback tells ResourcePool when they are no longer busy, so
     // there is nothing to do here.
     return;
@@ -615,7 +603,7 @@
                     MemoryAllocatorDump::kUnitsBytes,
                     total_memory_usage_bytes_);
   } else {
-    bool dump_parent = use_gpu_resources_ || use_gpu_memory_buffers_;
+    bool dump_parent = use_gpu_resources_;
     for (const auto& resource : unused_resources_) {
       resource->OnMemoryDump(pmd, resource_provider_, dump_parent,
                              true /* is_free */);
@@ -665,9 +653,7 @@
     // If |dump_parent| is false, the ownership of the resource is in the
     // ResourcePool, so we can see if any memory is allocated. If not, then
     // don't dump it.
-    // TODO(danakj): Early out for gpu paths as they move ownership to
-    // ResourcePool.
-    if (!shared_bitmap_)
+    if (!shared_bitmap_ && !gpu_backing_)
       return;
   }
 
@@ -692,15 +678,32 @@
     // chosen historically and there is no need to adjust it.
     const int kImportance = 2;
     if (shared_bitmap_) {
+      // Software resources are in shared memory but are kept closed to avoid
+      // holding an fd open. So there is no SharedMemoryHandle to get a guid
+      // from.
+      DCHECK(!shared_bitmap_->GetSharedMemoryHandle().IsValid());
       base::trace_event::MemoryAllocatorDumpGuid guid =
           viz::GetSharedBitmapGUIDForTracing(shared_bitmap_->id());
       DCHECK(!guid.empty());
       pmd->CreateSharedGlobalAllocatorDump(guid);
       pmd->AddOwnershipEdge(dump->guid(), guid, kImportance);
+    } else {
+      // Gpu compositing resources can be shared memory-backed (e.g.
+      // GpuMemoryBuffers can be backed by it).
+      const base::UnguessableToken& shm_guid = gpu_backing_->SharedMemoryGuid();
+      if (!shm_guid.is_empty()) {
+        pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shm_guid,
+                                             kImportance);
+      } else {
+        auto* dump_manager =
+            base::trace_event::MemoryDumpManager::GetInstance();
+        auto backing_guid =
+            gpu_backing_->MemoryDumpGuid(dump_manager->GetTracingProcessId());
+        DCHECK(!backing_guid.empty());
+        pmd->CreateSharedGlobalAllocatorDump(backing_guid);
+        pmd->AddOwnershipEdge(dump->guid(), backing_guid, kImportance);
+      }
     }
-
-    // TODO(danakj): Gpu paths need to report guids as they move ownership to
-    // ResourcePool.
   }
 
   uint64_t total_bytes =
diff --git a/cc/resources/resource_pool.h b/cc/resources/resource_pool.h
index df423e9a..3a165c1 100644
--- a/cc/resources/resource_pool.h
+++ b/cc/resources/resource_pool.h
@@ -17,7 +17,9 @@
 #include "base/memory/ptr_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
+#include "base/trace_event/memory_allocator_dump_guid.h"
 #include "base/trace_event/memory_dump_provider.h"
+#include "base/unguessable_token.h"
 #include "cc/cc_export.h"
 #include "cc/resources/resource.h"
 #include "cc/resources/scoped_resource.h"
@@ -25,6 +27,7 @@
 #include "components/viz/common/resources/resource_format.h"
 #include "gpu/command_buffer/common/sync_token.h"
 #include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/gpu_memory_buffer.h"
 
 namespace base {
 class SingleThreadTaskRunner;
@@ -41,6 +44,25 @@
   static constexpr base::TimeDelta kDefaultExpirationDelay =
       base::TimeDelta::FromSeconds(5);
 
+  // A base class to hold ownership of gpu backed PoolResources. Allows the
+  // client to define destruction semantics.
+  class GpuBacking {
+   public:
+    virtual ~GpuBacking() = default;
+
+    gpu::Mailbox mailbox;
+    gpu::SyncToken mailbox_sync_token;
+    uint32_t texture_target;
+    gpu::SyncToken returned_sync_token;
+
+    // Guids for for memory dumps. This guid will always be valid.
+    virtual base::trace_event::MemoryAllocatorDumpGuid MemoryDumpGuid(
+        uint64_t tracing_process_id) = 0;
+    // Some gpu resources can be shared memory-backed, and this guid should be
+    // prefered in that case. But if not then this will be empty.
+    virtual base::UnguessableToken SharedMemoryGuid() = 0;
+  };
+
   // Scoped move-only object returned when getting a resource from the pool.
   // Ownership must be given back to the pool to release the resource.
   class InUsePoolResource {
@@ -86,12 +108,21 @@
       return resource_->resource_id();
     }
 
+    // Only valid when the ResourcePool is vending texture-backed resources.
+    GpuBacking* gpu_backing() const {
+      DCHECK(is_gpu_);
+      return resource_->gpu_backing();
+    }
+    void set_gpu_backing(std::unique_ptr<GpuBacking> gpu) const {
+      DCHECK(is_gpu_);
+      return resource_->set_gpu_backing(std::move(gpu));
+    }
+
     // Only valid when the ResourcePool is vending software-backed resources.
     viz::SharedBitmap* shared_bitmap() const {
       DCHECK(!is_gpu_);
       return resource_->shared_bitmap();
     }
-    // Only valid when the ResourcePool is vending software-backed resources.
     void set_shared_bitmap(
         std::unique_ptr<viz::SharedBitmap> shared_bitmap) const {
       DCHECK(!is_gpu_);
@@ -212,6 +243,11 @@
     const viz::ResourceId& resource_id() const { return resource_id_; }
     void set_resource_id(viz::ResourceId id) { resource_id_ = id; }
 
+    GpuBacking* gpu_backing() const { return gpu_backing_.get(); }
+    void set_gpu_backing(std::unique_ptr<GpuBacking> gpu) {
+      gpu_backing_ = std::move(gpu);
+    }
+
     viz::SharedBitmap* shared_bitmap() const { return shared_bitmap_.get(); }
     void set_shared_bitmap(std::unique_ptr<viz::SharedBitmap> shared_bitmap) {
       shared_bitmap_ = std::move(shared_bitmap);
@@ -228,9 +264,6 @@
       invalidated_rect_ = invalidated_rect;
     }
 
-    const gpu::SyncToken& sync_token() const { return sync_token_; }
-    void set_sync_token(const gpu::SyncToken& token) { sync_token_ = token; }
-
     void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
                       const LayerTreeResourceProvider* resource_provider,
                       bool dump_parent,
@@ -246,17 +279,18 @@
     base::TimeTicks last_usage_;
     gfx::Rect invalidated_rect_;
 
-    // TODO(danakj): Own a backing for gpu resources here also,
-    // instead of owning it through the |resource_id_|.
+    // An id used to name the backing for transfer to the display compositor.
     viz::ResourceId resource_id_ = 0;
 
-    // The backing for software resources. Initially null for resources given
-    // out by ResourcePool, to be filled in by the client.
-    std::unique_ptr<viz::SharedBitmap> shared_bitmap_;
+    // The backing for gpu resources. Initially null for resources given
+    // out by ResourcePool, to be filled in by the client. Is destroyed on the
+    // compositor thread.
+    std::unique_ptr<GpuBacking> gpu_backing_;
 
-    // If a resource was exported and returned, then this will hold the token
-    // that must be waited on before re-using the resource.
-    gpu::SyncToken sync_token_;
+    // The backing for software resources. Initially null for resources given
+    // out by ResourcePool, to be filled in by the client. Is destroyed on the
+    // compositor thread.
+    std::unique_ptr<viz::SharedBitmap> shared_bitmap_;
   };
 
   // Callback from the ResourceProvider to notify when an exported PoolResource
diff --git a/cc/test/fake_raster_source.cc b/cc/test/fake_raster_source.cc
index 177a7f1..df1ed6b 100644
--- a/cc/test/fake_raster_source.cc
+++ b/cc/test/fake_raster_source.cc
@@ -146,13 +146,11 @@
 
 FakeRasterSource::~FakeRasterSource() = default;
 
-void FakeRasterSource::PlaybackToCanvas(
-    SkCanvas* canvas,
-    const gfx::ColorSpace& canvas_color_space,
-    const PlaybackSettings& settings) const {
+void FakeRasterSource::PlaybackToCanvas(SkCanvas* canvas,
+                                        ImageProvider* image_provider) const {
   if (playback_allowed_event_)
     playback_allowed_event_->Wait();
-  RasterSource::PlaybackToCanvas(canvas, canvas_color_space, settings);
+  RasterSource::PlaybackToCanvas(canvas, image_provider);
 }
 
 }  // namespace cc
diff --git a/cc/test/fake_raster_source.h b/cc/test/fake_raster_source.h
index 0fc04df..7e6119d 100644
--- a/cc/test/fake_raster_source.h
+++ b/cc/test/fake_raster_source.h
@@ -38,8 +38,7 @@
       base::WaitableEvent* playback_allowed_event);
 
   void PlaybackToCanvas(SkCanvas* canvas,
-                        const gfx::ColorSpace& canvas_color_space,
-                        const PlaybackSettings& settings) const override;
+                        ImageProvider* image_provider) const override;
 
  protected:
   explicit FakeRasterSource(const RecordingSource* recording_source);
diff --git a/cc/test/layer_tree_pixel_resource_test.cc b/cc/test/layer_tree_pixel_resource_test.cc
index 8720213..3e2c178 100644
--- a/cc/test/layer_tree_pixel_resource_test.cc
+++ b/cc/test/layer_tree_pixel_resource_test.cc
@@ -52,6 +52,8 @@
   LayerTreeResourceProvider* resource_provider = host_impl->resource_provider();
   viz::SharedBitmapManager* shared_bitmap_manager =
       host_impl->layer_tree_frame_sink()->shared_bitmap_manager();
+  gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager =
+      host_impl->layer_tree_frame_sink()->gpu_memory_buffer_manager();
   int max_bytes_per_copy_operation = 1024 * 1024;
   int max_staging_buffer_usage_in_bytes = 32 * 1024 * 1024;
 
@@ -82,10 +84,12 @@
       break;
     case ZERO_COPY:
       EXPECT_TRUE(compositor_context_provider);
+      EXPECT_TRUE(gpu_memory_buffer_manager);
       EXPECT_EQ(PIXEL_TEST_GL, test_type_);
 
-      *raster_buffer_provider = ZeroCopyRasterBufferProvider::Create(
-          resource_provider, viz::PlatformColor::BestTextureFormat());
+      *raster_buffer_provider = std::make_unique<ZeroCopyRasterBufferProvider>(
+          resource_provider, gpu_memory_buffer_manager,
+          compositor_context_provider, viz::PlatformColor::BestTextureFormat());
       *resource_pool = std::make_unique<ResourcePool>(
           resource_provider, std::move(task_runner),
           gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index bc16690..091fed51 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -2661,8 +2661,10 @@
         ResourcePool::kDefaultExpirationDelay,
         settings_.disallow_non_exact_resource_reuse);
 
-    *raster_buffer_provider = ZeroCopyRasterBufferProvider::Create(
-        resource_provider_.get(), settings_.preferred_tile_format);
+    *raster_buffer_provider = std::make_unique<ZeroCopyRasterBufferProvider>(
+        resource_provider_.get(),
+        layer_tree_frame_sink_->gpu_memory_buffer_manager(),
+        compositor_context_provider, settings_.preferred_tile_format);
     return;
   }
 
diff --git a/chrome/android/java/res/drawable-hdpi/infobar_clipboard.png b/chrome/android/java/res/drawable-hdpi/infobar_clipboard.png
new file mode 100644
index 0000000..8df2460
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/infobar_clipboard.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/infobar_clipboard.png b/chrome/android/java/res/drawable-mdpi/infobar_clipboard.png
new file mode 100644
index 0000000..b44c8d7
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/infobar_clipboard.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/infobar_clipboard.png b/chrome/android/java/res/drawable-xhdpi/infobar_clipboard.png
new file mode 100644
index 0000000..f40aeb7
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/infobar_clipboard.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/infobar_clipboard.png b/chrome/android/java/res/drawable-xxhdpi/infobar_clipboard.png
new file mode 100644
index 0000000..e9496160
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/infobar_clipboard.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/infobar_clipboard.png b/chrome/android/java/res/drawable-xxxhdpi/infobar_clipboard.png
new file mode 100644
index 0000000..2a66bd1
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/infobar_clipboard.png
Binary files differ
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
index 9d165f6..98a3f11 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -158,6 +158,8 @@
     public static final String CCT_EXTERNAL_LINK_HANDLING = "CCTExternalLinkHandling";
     public static final String CCT_POST_MESSAGE_API = "CCTPostMessageAPI";
     public static final String CCT_REDIRECT_PRECONNECT = "CCTRedirectPreconnect";
+    public static final String CHROME_DUPLEX = "ChromeDuplex";
+    // TODO(mdjones): Remove CHROME_HOME completely.
     public static final String CHROME_HOME = "ChromeHome";
     public static final String CHROME_HOME_BOTTOM_NAV_LABELS = "ChromeHomeBottomNavLabels";
     public static final String CHROME_HOME_CLEAR_URL_ON_OPEN = "ChromeHomeClearUrlOnOpen";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
index 10104366..c4065db 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -305,8 +305,7 @@
         Set<ContextMenuItem> disabledOptions = getDisabledOptions(params);
         // Split the items into their respective groups.
         List<Pair<Integer, List<ContextMenuItem>>> groupedItems = new ArrayList<>();
-        if (params.isAnchor()
-                && !ChromeFeatureList.isEnabled(ChromeFeatureList.CUSTOM_CONTEXT_MENU)) {
+        if (params.isAnchor()) {
             populateItemGroup(LINK, R.string.contextmenu_link_title, groupedItems, supportedOptions,
                     disabledOptions);
         }
@@ -318,11 +317,6 @@
             populateItemGroup(VIDEO, R.string.contextmenu_video_title, groupedItems,
                     supportedOptions, disabledOptions);
         }
-        if (params.isAnchor()
-                && ChromeFeatureList.isEnabled(ChromeFeatureList.CUSTOM_CONTEXT_MENU)) {
-            populateItemGroup(LINK, R.string.contextmenu_link_title, groupedItems, supportedOptions,
-                    disabledOptions);
-        }
 
         // If there are no groups there still needs to be a way to add items from the OTHER_GROUP
         // and CUSTOM_TAB_GROUP.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerDelegate.java
index 3aa4da0a..f623f659 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerDelegate.java
@@ -132,10 +132,14 @@
     /**
      * Removes a download from Android DownloadManager.
      * @param downloadGuid The GUID of the download.
+     * @param externallyRemoved If download is externally removed in other application.
      */
-    void removeCompletedDownload(String downloadGuid) {
+    void removeCompletedDownload(String downloadGuid, boolean externallyRemoved) {
         long downloadId = removeDownloadIdMapping(downloadGuid);
-        if (downloadId != INVALID_SYSTEM_DOWNLOAD_ID) {
+
+        // Let Android DownloadManager to remove download only if the user removed the file in
+        // Chrome. If the user renamed or moved the file, Chrome should keep it intact.
+        if (downloadId != INVALID_SYSTEM_DOWNLOAD_ID && !externallyRemoved) {
             DownloadManager manager =
                     (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
             manager.remove(downloadId);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
index de46903..549903a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -990,9 +990,11 @@
      * Removes a download from the list.
      * @param downloadGuid GUID of the download.
      * @param isOffTheRecord Whether the download is off the record.
+     * @param externallyRemoved If the file is externally removed by other applications.
      */
     @Override
-    public void removeDownload(final String downloadGuid, boolean isOffTheRecord) {
+    public void removeDownload(
+            final String downloadGuid, boolean isOffTheRecord, boolean externallyRemoved) {
         mHandler.post(() -> {
             nativeRemoveDownload(getNativeDownloadManagerService(), downloadGuid, isOffTheRecord);
             removeDownloadProgress(downloadGuid);
@@ -1001,7 +1003,7 @@
         new AsyncTask<Void, Void, Void>() {
             @Override
             public Void doInBackground(Void... params) {
-                mDownloadManagerDelegate.removeCompletedDownload(downloadGuid);
+                mDownloadManagerDelegate.removeCompletedDownload(downloadGuid, externallyRemoved);
                 return null;
             }
         }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/BackendProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/BackendProvider.java
index 88a3dd5..e69265b1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/BackendProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/BackendProvider.java
@@ -33,7 +33,7 @@
         void checkForExternallyRemovedDownloads(boolean isOffTheRecord);
 
         /** See {@link DownloadManagerService#removeDownload}. */
-        void removeDownload(String guid, boolean isOffTheRecord);
+        void removeDownload(String guid, boolean isOffTheRecord, boolean externallyRemoved);
 
         /** See {@link DownloadManagerService#isDownloadOpenableInBrowser}. */
         boolean isDownloadOpenableInBrowser(boolean isOffTheRecord, String mimeType);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java
index b2cfa5ce..c36fb5e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java
@@ -384,7 +384,8 @@
         @Override
         public boolean removePermanently() {
             // Tell the DownloadManager to remove the file from history.
-            mBackendProvider.getDownloadDelegate().removeDownload(getId(), isOffTheRecord());
+            mBackendProvider.getDownloadDelegate().removeDownload(
+                    getId(), isOffTheRecord(), hasBeenExternallyRemoved());
             mBackendProvider.getThumbnailProvider().removeThumbnailsFromDisk(getId());
             return true;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
index ec2216b..cf2eb7b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
@@ -12,7 +12,6 @@
 import android.content.pm.ResolveInfo;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.StrictMode;
 import android.os.UserManager;
 import android.speech.RecognizerIntent;
 
@@ -25,10 +24,7 @@
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.firstrun.FirstRunUtils;
-import org.chromium.chrome.browser.locale.LocaleManager;
-import org.chromium.chrome.browser.metrics.UmaSessionStats;
 import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
-import org.chromium.chrome.browser.preferences.PrefServiceBridge;
 import org.chromium.chrome.browser.tabmodel.DocumentModeAssassin;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.ui.base.DeviceFormFactor;
@@ -42,13 +38,8 @@
 public class FeatureUtilities {
     private static final String TAG = "FeatureUtilities";
 
-    private static final String SYNTHETIC_CHROME_HOME_EXPERIMENT_NAME = "SyntheticChromeHome";
-    private static final String ENABLED_EXPERIMENT_GROUP = "Enabled";
-    private static final String DISABLED_EXPERIMENT_GROUP = "Disabled";
-
     private static Boolean sHasGoogleAccountAuthenticator;
     private static Boolean sHasRecognitionIntentHandler;
-    private static Boolean sChromeHomeEnabled;
     private static String sChromeHomeSwipeLogicType;
 
     private static Boolean sIsSoleEnabled;
@@ -189,6 +180,8 @@
     }
 
     /**
+     * DEPRECATED: DO NOT USE.
+     *
      * Cache whether or not Chrome Home and related features are enabled. If this method is called
      * multiple times, the existing cached state is cleared and re-computed.
      */
@@ -196,67 +189,31 @@
         // Chrome Home doesn't work with tablets.
         if (DeviceFormFactor.isTablet()) return;
         ChromePreferenceManager.getInstance().clearObsoleteChromeHomePrefs();
-
-        boolean isChromeHomeEnabled = ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_HOME);
-        ChromePreferenceManager manager = ChromePreferenceManager.getInstance();
-        manager.setChromeHomeEnabled(isChromeHomeEnabled);
-
-        PrefServiceBridge.getInstance().setChromeHomePersonalizedOmniboxSuggestionsEnabled(
-                areChromeHomePersonalizedOmniboxSuggestionsEnabled());
-
-        UmaSessionStats.registerSyntheticFieldTrial(SYNTHETIC_CHROME_HOME_EXPERIMENT_NAME,
-                isChromeHomeEnabled() ? ENABLED_EXPERIMENT_GROUP : DISABLED_EXPERIMENT_GROUP);
-    }
-
-    private static boolean areChromeHomePersonalizedOmniboxSuggestionsEnabled() {
-        LocaleManager localeManager = LocaleManager.getInstance();
-        return isChromeHomeEnabled() && !localeManager.hasCompletedSearchEnginePromo()
-                && !localeManager.hasShownSearchEnginePromoThisSession()
-                && ChromeFeatureList.isEnabled(
-                           ChromeFeatureList.CHROME_HOME_PERSONALIZED_OMNIBOX_SUGGESTIONS);
     }
 
     /**
+     * DEPRECATED: DO NOT USE.
+     *
      * @return Whether or not chrome should attach the toolbar to the bottom of the screen.
      */
     @CalledByNative
     public static boolean isChromeHomeEnabled() {
-        if (DeviceFormFactor.isTablet()) return false;
-
-        if (sChromeHomeEnabled == null) {
-            ChromePreferenceManager prefManager = ChromePreferenceManager.getInstance();
-
-            // Allow disk access for preferences while Chrome Home is in experimentation.
-            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
-            try {
-                sChromeHomeEnabled = prefManager.isChromeHomeEnabled();
-            } finally {
-                StrictMode.setThreadPolicy(oldPolicy);
-            }
-
-            // If the browser has been initialized by this point, check the experiment as well to
-            // avoid the restart logic in cacheChromeHomeEnabled.
-            if (ChromeFeatureList.isInitialized()) {
-                boolean chromeHomeExperimentEnabled =
-                        ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_HOME);
-
-                if (chromeHomeExperimentEnabled != sChromeHomeEnabled) {
-                    sChromeHomeEnabled = chromeHomeExperimentEnabled;
-                    ChromePreferenceManager.getInstance().setChromeHomeEnabled(
-                            chromeHomeExperimentEnabled);
-                }
-            }
-            ChromePreferenceManager.setChromeHomeEnabledDate(sChromeHomeEnabled);
-        }
-        return sChromeHomeEnabled;
+        return false;
     }
 
     /**
      * Resets whether Chrome Home is enabled for tests. After this is called, the next call to
      * #isChromeHomeEnabled() will retrieve the value from shared preferences.
      */
-    public static void resetChromeHomeEnabledForTests() {
-        sChromeHomeEnabled = null;
+    @Deprecated
+    public static void resetChromeHomeEnabledForTests() {}
+
+    /**
+     * @return Whether Chrome Duplex, split toolbar Chrome Home, is enabled.
+     */
+    public static boolean isChromeDuplexEnabled() {
+        return ChromeFeatureList.isInitialized()
+                && ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_DUPLEX);
     }
 
     /**
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 6ef9abe..9a478cd 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1499,7 +1499,6 @@
   "javatests/src/org/chromium/chrome/browser/WebShareTest.java",
   "javatests/src/org/chromium/chrome/browser/accessibility/FontSizePrefsTest.java",
   "javatests/src/org/chromium/chrome/browser/appmenu/AppMenuTest.java",
-  "javatests/src/org/chromium/chrome/browser/appmenu/ChromeHomeAppMenuTest.java",
   "javatests/src/org/chromium/chrome/browser/appmenu/DataSaverAppMenuTest.java",
   "javatests/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryTest.java",
   "javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java",
@@ -1552,7 +1551,6 @@
   "javatests/src/org/chromium/chrome/browser/dom_distiller/DistillabilityServiceTest.java",
   "javatests/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsTest.java",
   "javatests/src/org/chromium/chrome/browser/download/ChromeDownloadDelegateTest.java",
-  "javatests/src/org/chromium/chrome/browser/download/ChromeHomeDownloadManagerTest.java",
   "javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java",
   "javatests/src/org/chromium/chrome/browser/download/DownloadManagerServiceTest.java",
   "javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java",
@@ -1665,7 +1663,6 @@
   "javatests/src/org/chromium/chrome/browser/omaha/RequestGeneratorTest.java",
   "javatests/src/org/chromium/chrome/browser/omaha/StringSanitizerTest.java",
   "javatests/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelperTest.java",
-  "javatests/src/org/chromium/chrome/browser/omnibox/BottomSheetLocationBarTest.java",
   "javatests/src/org/chromium/chrome/browser/omnibox/OmniboxTest.java",
   "javatests/src/org/chromium/chrome/browser/omnibox/OmniboxUrlEmphasizerTest.java",
   "javatests/src/org/chromium/chrome/browser/omnibox/SuggestionAnswerTest.java",
@@ -1882,10 +1879,6 @@
   "javatests/src/org/chromium/chrome/browser/widget/ThumbnailProviderImplTest.java",
   "javatests/src/org/chromium/chrome/browser/widget/ToolbarProgressBarTest.java",
   "javatests/src/org/chromium/chrome/browser/widget/ViewHighlighterTest.java",
-  "javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetBackBehaviorTest.java",
-  "javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentControllerTest.java",
-  "javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNavigateTest.java",
-  "javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java",
   "javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java",
   "javatests/src/org/chromium/chrome/browser/widget/findinpage/FindTest.java",
   "javatests/src/org/chromium/chrome/test/crash/IntentionalCrashTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ExampleUiCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ExampleUiCaptureTest.java
index 375b641..cb81e50 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ExampleUiCaptureTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ExampleUiCaptureTest.java
@@ -31,7 +31,6 @@
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
 @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // Tab switcher button only exists on phones.
-@ScreenShooter.Directory("Example")
 public class ExampleUiCaptureTest {
     @Rule
     public ChromeActivityTestRule<ChromeTabbedActivity> mActivityTestRule =
@@ -53,7 +52,6 @@
     @Test
     @SmallTest
     @Feature({"UiCatalogue"})
-    @ScreenShooter.Directory("TabSwitcher")
     public void testCaptureTabSwitcher() throws IOException, InterruptedException {
         mScreenShooter.shoot("NTP", ScreenShooter.TagsEnum.UiCatalogueExample);
         Espresso.onView(ViewMatchers.withId(R.id.tab_switcher_button)).perform(ViewActions.click());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/FeaturesAnnotationsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/FeaturesAnnotationsTest.java
index edd3bca..1134fd13 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/FeaturesAnnotationsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/FeaturesAnnotationsTest.java
@@ -20,6 +20,7 @@
 
 import org.chromium.base.CommandLine;
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.chrome.browser.util.FeatureUtilities;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
@@ -72,6 +73,7 @@
      * here explicitly calls {@link Features#enable(String...)}, so its feature should also be added
      * to the set of registered flags.
      */
+    @DisabledTest(message = "https://crbug.com/805160")
     @Test
     @SmallTest
     @ChromeHome.Enable
@@ -121,6 +123,7 @@
         assertThat(finalEnabledList.size(), equalTo(4));
     }
 
+    @DisabledTest(message = "https://crbug.com/805160")
     @Test
     @SmallTest
     @ChromeHome.Enable
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/ChromeHomeAppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/ChromeHomeAppMenuTest.java
deleted file mode 100644
index 5be8f0a3..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/ChromeHomeAppMenuTest.java
+++ /dev/null
@@ -1,396 +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.
-
-package org.chromium.chrome.browser.appmenu;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.support.annotation.Nullable;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.text.TextUtils;
-import android.widget.ListView;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.Callback;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.CallbackHelper;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Restriction;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeFeatureList;
-import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
-import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
-import org.chromium.chrome.browser.preferences.datareduction.DataReductionMainMenuItem;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
-import org.chromium.chrome.browser.widget.bottomsheet.ChromeHomeIphMenuHeader;
-import org.chromium.chrome.browser.widget.bottomsheet.ChromeHomeIphMenuHeader.ChromeHomeIphMenuHeaderTestObserver;
-import org.chromium.chrome.test.BottomSheetTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.ChromeTabUtils;
-import org.chromium.chrome.test.util.MenuUtils;
-import org.chromium.components.feature_engagement.FeatureConstants;
-import org.chromium.components.feature_engagement.Tracker;
-import org.chromium.components.feature_engagement.TriggerState;
-import org.chromium.content.browser.test.util.Criteria;
-import org.chromium.content.browser.test.util.CriteriaHelper;
-import org.chromium.net.test.EmbeddedTestServer;
-import org.chromium.ui.test.util.UiRestriction;
-
-import java.util.concurrent.TimeoutException;
-
-/**
- * Tests for the app menu when Chrome Home is enabled.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
-public class ChromeHomeAppMenuTest {
-    private static final String TEST_PAGE = "/chrome/test/data/android/test.html";
-
-    private static class TestTracker implements Tracker {
-        public CallbackHelper mDimissedCallbackHelper = new CallbackHelper();
-
-        private String mEnabledFeature;
-
-        public TestTracker(String enabledFeature) {
-            mEnabledFeature = enabledFeature;
-        }
-
-        @Override
-        public void notifyEvent(String event) {}
-
-        @Override
-        public boolean shouldTriggerHelpUI(String feature) {
-            return TextUtils.equals(mEnabledFeature, feature);
-        }
-
-        @Override
-        public boolean wouldTriggerHelpUI(String feature) {
-            return TextUtils.equals(mEnabledFeature, feature);
-        }
-
-        @Override
-        public int getTriggerState(String feature) {
-            return TextUtils.equals(mEnabledFeature, feature) ? TriggerState.HAS_NOT_BEEN_DISPLAYED
-                                                              : TriggerState.HAS_BEEN_DISPLAYED;
-        }
-
-        @Override
-        public void dismissed(String feature) {
-            Assert.assertEquals("Wrong feature dismissed.", mEnabledFeature, feature);
-            mDimissedCallbackHelper.notifyCalled();
-        }
-
-        @Nullable
-        @Override
-        public DisplayLockHandle acquireDisplayLock() {
-            return null;
-        }
-
-        @Override
-        public boolean isInitialized() {
-            return true;
-        }
-
-        @Override
-        public void addOnInitializedCallback(Callback<Boolean> callback) {}
-    }
-
-    private AppMenuHandler mAppMenuHandler;
-    private BottomSheet mBottomSheet;
-    private EmbeddedTestServer mTestServer;
-    private String mTestUrl;
-
-    @Rule
-    public BottomSheetTestRule mBottomSheetTestRule = new BottomSheetTestRule();
-
-    @Before
-    public void setUp() throws Exception {
-        mBottomSheetTestRule.startMainActivityOnBlankPage();
-        mAppMenuHandler = mBottomSheetTestRule.getActivity().getAppMenuHandler();
-        mBottomSheet = mBottomSheetTestRule.getBottomSheet();
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-
-        mTestServer = EmbeddedTestServer.createAndStartServer(
-                InstrumentationRegistry.getInstrumentation().getContext());
-        mTestUrl = mTestServer.getURL(TEST_PAGE);
-    }
-
-    @After
-    public void tearDown() {
-        mTestServer.stopAndDestroyServer();
-    }
-
-    @Test
-    @SmallTest
-    public void testPageMenu() throws IllegalArgumentException, InterruptedException {
-        loadTestPage();
-
-        showAppMenuAndAssertMenuShown();
-        AppMenu appMenu = mAppMenuHandler.getAppMenu();
-        AppMenuIconRowFooter iconRow = (AppMenuIconRowFooter) appMenu.getFooterView();
-
-        assertFalse("Forward button should not be enabled",
-                iconRow.getForwardButtonForTests().isEnabled());
-        assertTrue("Bookmark button should be enabled",
-                iconRow.getBookmarkButtonForTests().isEnabled());
-        assertTrue("Download button should be enabled",
-                iconRow.getDownloadButtonForTests().isEnabled());
-        assertTrue(
-                "Info button should be enabled", iconRow.getPageInfoButtonForTests().isEnabled());
-        assertTrue(
-                "Reload button should be enabled", iconRow.getReloadButtonForTests().isEnabled());
-
-        // Navigate backward, open the menu and assert forward button is enabled.
-        ThreadUtils.runOnUiThreadBlocking(() -> {
-            mAppMenuHandler.hideAppMenu();
-            mBottomSheetTestRule.getActivity().getActivityTab().goBack();
-        });
-
-        showAppMenuAndAssertMenuShown();
-        iconRow = (AppMenuIconRowFooter) appMenu.getFooterView();
-        assertTrue(
-                "Forward button should be enabled", iconRow.getForwardButtonForTests().isEnabled());
-    }
-
-    @Test
-    @SmallTest
-    public void testTabSwitcherMenu() throws IllegalArgumentException {
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> mBottomSheetTestRule.getActivity().getLayoutManager().showOverview(false));
-
-        showAppMenuAndAssertMenuShown();
-        AppMenu appMenu = mAppMenuHandler.getAppMenu();
-
-        assertNull("Footer view should be null", appMenu.getFooterView());
-        Assert.assertEquals(
-                "There should be four app menu items.", appMenu.getListView().getCount(), 4);
-        Assert.assertEquals("'New tab' should be the first item", R.id.new_tab_menu_id,
-                appMenu.getListView().getItemIdAtPosition(0));
-        Assert.assertEquals("'New incognito tab' should be the second item",
-                R.id.new_incognito_tab_menu_id, appMenu.getListView().getItemIdAtPosition(1));
-        Assert.assertEquals("'Close all tabs' should be the third item",
-                R.id.close_all_tabs_menu_id, appMenu.getListView().getItemIdAtPosition(2));
-        Assert.assertEquals("'Settings' should be the fourth item", R.id.preferences_id,
-                appMenu.getListView().getItemIdAtPosition(3));
-    }
-
-    @Test
-    @SmallTest
-    public void testNewTabMenu() {
-        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
-                mBottomSheetTestRule.getActivity(), R.id.new_tab_menu_id);
-        ThreadUtils.runOnUiThreadBlocking(() -> mBottomSheet.endAnimations());
-
-        showAppMenuAndAssertMenuShown();
-        AppMenu appMenu = mAppMenuHandler.getAppMenu();
-
-        assertNull("Footer view should be null", appMenu.getFooterView());
-        Assert.assertEquals(
-                "There should be four app menu items.", appMenu.getListView().getCount(), 4);
-        Assert.assertEquals("'New incognito tab' should be the first item",
-                R.id.new_incognito_tab_menu_id, appMenu.getListView().getItemIdAtPosition(0));
-        Assert.assertEquals("'Recent tabs' should be the second item", R.id.recent_tabs_menu_id,
-                appMenu.getListView().getItemIdAtPosition(1));
-        Assert.assertEquals("'Settings' should be the third item", R.id.preferences_id,
-                appMenu.getListView().getItemIdAtPosition(2));
-        Assert.assertEquals("'Help & feedback' should be the fourth item", R.id.help_id,
-                appMenu.getListView().getItemIdAtPosition(3));
-    }
-
-    @Test
-    @SmallTest
-    public void testNewIncognitoTabMenu() {
-        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
-                mBottomSheetTestRule.getActivity(), R.id.new_incognito_tab_menu_id);
-        ThreadUtils.runOnUiThreadBlocking(() -> mBottomSheet.endAnimations());
-
-        showAppMenuAndAssertMenuShown();
-        AppMenu appMenu = mAppMenuHandler.getAppMenu();
-
-        assertNull("Footer view should be null", appMenu.getFooterView());
-        Assert.assertEquals(
-                "There should be three app menu items.", appMenu.getListView().getCount(), 3);
-        Assert.assertEquals("'New tab' should be the first item", R.id.new_tab_menu_id,
-                appMenu.getListView().getItemIdAtPosition(0));
-        Assert.assertEquals("'Settings' should be the second item", R.id.preferences_id,
-                appMenu.getListView().getItemIdAtPosition(1));
-        Assert.assertEquals("'Help & feedback' should be the third item", R.id.help_id,
-                appMenu.getListView().getItemIdAtPosition(2));
-    }
-
-    @Test
-    @SmallTest
-    public void testIphAppMenuHeader_Click() throws InterruptedException, TimeoutException {
-        TestTracker tracker = new TestTracker(FeatureConstants.CHROME_HOME_MENU_HEADER_FEATURE);
-        TrackerFactory.setTrackerForTests(tracker);
-
-        // Create a callback to be notified when the menu header is clicked.
-        final CallbackHelper menuItemClickedCallback = new CallbackHelper();
-        final CallbackHelper menuDismissedCallback = new CallbackHelper();
-        ThreadUtils.runOnUiThreadBlocking(() -> {
-            ChromeHomeIphMenuHeader.setObserverForTests(new ChromeHomeIphMenuHeaderTestObserver() {
-                @Override
-                public void onMenuItemClicked() {
-                    menuItemClickedCallback.notifyCalled();
-                }
-
-                @Override
-                public void onMenuDismissed(boolean dismissIph) {
-                    Assert.assertFalse("In-product help should not be dismissed when menu is"
-                                    + " dismissed.",
-                            dismissIph);
-                    menuDismissedCallback.notifyCalled();
-                }
-            });
-        });
-
-        // Load a test page and show the app menu. The header is only shown on the page menu.
-        loadTestPage();
-        showAppMenuAndAssertMenuShown();
-
-        // Check for the existence of a header.
-        ListView listView = mAppMenuHandler.getAppMenu().getListView();
-        Assert.assertEquals("There should be one header.", 1, listView.getHeaderViewsCount());
-
-        // Click the header.
-        ChromeHomeIphMenuHeader iphHeader =
-                (ChromeHomeIphMenuHeader) listView.findViewById(R.id.chrome_home_iph_menu_header);
-        ThreadUtils.runOnUiThreadBlocking(() -> { iphHeader.performClick(); });
-
-        // Wait for the app menu to hide, then check state.
-        menuItemClickedCallback.waitForCallback(0);
-        menuDismissedCallback.waitForCallback(0);
-        assertFalse("Menu should be hidden.", mAppMenuHandler.isAppMenuShowing());
-        Assert.assertEquals("IPH should not be dimissed yet.", 0,
-                tracker.mDimissedCallbackHelper.getCallCount());
-        Assert.assertTrue("Bottom sheet help bubble should be showing.",
-                mBottomSheet.getHelpBubbleForTests().isShowing());
-
-        // Dismiss the help bubble
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> { mBottomSheet.getHelpBubbleForTests().dismiss(); });
-
-        Assert.assertEquals(
-                "IPH should be dimissed.", 1, tracker.mDimissedCallbackHelper.getCallCount());
-
-        // Reset state.
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> { ChromeHomeIphMenuHeader.setObserverForTests(null); });
-        TrackerFactory.setTrackerForTests(null);
-    }
-
-    @Test
-    @SmallTest
-    public void testIphAppMenuHeader_Dismiss() throws InterruptedException, TimeoutException {
-        TestTracker tracker = new TestTracker(FeatureConstants.CHROME_HOME_MENU_HEADER_FEATURE);
-        TrackerFactory.setTrackerForTests(tracker);
-
-        // Create a callback to be notified when the menu header is clicked.
-        final CallbackHelper menuItemClickedCallback = new CallbackHelper();
-        final CallbackHelper menuDismissedCallback = new CallbackHelper();
-        ThreadUtils.runOnUiThreadBlocking(() -> {
-            ChromeHomeIphMenuHeader.setObserverForTests(new ChromeHomeIphMenuHeaderTestObserver() {
-                @Override
-                public void onMenuItemClicked() {
-                    menuItemClickedCallback.notifyCalled();
-                }
-
-                @Override
-                public void onMenuDismissed(boolean dismissIph) {
-                    Assert.assertTrue("In-product help should be dismissed when menu is"
-                                    + " dismissed.",
-                            dismissIph);
-                    menuDismissedCallback.notifyCalled();
-                }
-            });
-        });
-
-        // Load a test page and show the app menu. The header is only shown on the page menu.
-        loadTestPage();
-        showAppMenuAndAssertMenuShown();
-
-        // Check for the existence of a header.
-        ListView listView = mAppMenuHandler.getAppMenu().getListView();
-        Assert.assertEquals("There should be one header.", 1, listView.getHeaderViewsCount());
-
-        // Check that the right header is showing.
-        ChromeHomeIphMenuHeader iphHeader =
-                (ChromeHomeIphMenuHeader) listView.findViewById(R.id.chrome_home_iph_menu_header);
-        Assert.assertNotNull(iphHeader);
-
-        // Hide the app menu.
-        ThreadUtils.runOnUiThreadBlocking(() -> { mAppMenuHandler.hideAppMenu(); });
-
-        // Wait for the app menu to hide, then check state.
-        menuDismissedCallback.waitForCallback(0);
-        Assert.assertEquals("menuItemClickedCallback should not have been called.", 0,
-                menuItemClickedCallback.getCallCount());
-        Assert.assertEquals(
-                "IPH should be dimissed.", 1, tracker.mDimissedCallbackHelper.getCallCount());
-        Assert.assertNull(
-                "Bottom sheet help bubble should be null.", mBottomSheet.getHelpBubbleForTests());
-
-        // Reset state.
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> { ChromeHomeIphMenuHeader.setObserverForTests(null); });
-        TrackerFactory.setTrackerForTests(null);
-    }
-
-    @Test
-    @SmallTest
-    @CommandLineFlags.Add({"disable-features=IPH_ChromeHomeMenuHeader",
-            "enable-features=" + ChromeFeatureList.DATA_REDUCTION_MAIN_MENU})
-    public void testDataSaverAppMenuHeader() {
-        showAppMenuAndAssertMenuShown();
-
-        // There should currently be no headers.
-        ListView listView = mAppMenuHandler.getAppMenu().getListView();
-        Assert.assertEquals("There should not be a header.", 0, listView.getHeaderViewsCount());
-
-        // Hide the app menu.
-        ThreadUtils.runOnUiThreadBlocking(() -> { mAppMenuHandler.hideAppMenu(); });
-
-        // Turn Data Saver on and re-open the menu.
-        ThreadUtils.runOnUiThreadBlocking(() -> {
-            DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(
-                    mBottomSheetTestRule.getActivity().getApplicationContext(), true);
-        });
-        showAppMenuAndAssertMenuShown();
-
-        // Check for the existence of a header.
-        listView = mAppMenuHandler.getAppMenu().getListView();
-        Assert.assertEquals("There should be one header.", 1, listView.getHeaderViewsCount());
-
-        // Check that the right header is showing.
-        DataReductionMainMenuItem dataReductionHeader =
-                (DataReductionMainMenuItem) listView.findViewById(R.id.data_reduction_menu_item);
-        Assert.assertNotNull(dataReductionHeader);
-    }
-
-    private void loadTestPage() throws InterruptedException {
-        final Tab tab = mBottomSheet.getActiveTab();
-        ChromeTabUtils.loadUrlOnUiThread(tab, mTestUrl);
-        ChromeTabUtils.waitForTabPageLoaded(tab, mTestUrl);
-    }
-
-    private void showAppMenuAndAssertMenuShown() {
-        ThreadUtils.runOnUiThread((Runnable) () -> mAppMenuHandler.showAppMenu(null, false));
-        CriteriaHelper.pollUiThread(new Criteria("AppMenu did not show") {
-            @Override
-            public boolean isSatisfied() {
-                return mAppMenuHandler.isAppMenuShowing();
-            }
-        });
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ChromeHomeDownloadManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/ChromeHomeDownloadManagerTest.java
deleted file mode 100644
index b1cded7..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ChromeHomeDownloadManagerTest.java
+++ /dev/null
@@ -1,195 +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.
-
-package org.chromium.chrome.browser.download;
-
-import android.content.Context;
-import android.content.Intent;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.ActivityState;
-import org.chromium.base.ApplicationStatus;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Restriction;
-import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.customtabs.CustomTabActivity;
-import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
-import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
-import org.chromium.chrome.test.BottomSheetTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.content.browser.test.util.Criteria;
-import org.chromium.content.browser.test.util.CriteriaHelper;
-import org.chromium.net.test.EmbeddedTestServer;
-import org.chromium.ui.test.util.UiRestriction;
-
-/**
- * Tests showing the download manager when Chrome Home is enabled.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
-@CommandLineFlags.Add({
-        "enable-features=ChromeHome", ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
-})
-public class ChromeHomeDownloadManagerTest {
-    private static final String TEST_PAGE = "/chrome/test/data/android/google.html";
-
-    @Rule
-    public BottomSheetTestRule mBottomSheetTestRule = new BottomSheetTestRule();
-
-    @Rule
-    public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule();
-
-    private EmbeddedTestServer mTestServer;
-    private String mTestPage;
-
-    @Before
-    public void setUp() throws Exception {
-        Context appContext = InstrumentationRegistry.getInstrumentation()
-                                     .getTargetContext()
-                                     .getApplicationContext();
-        mTestServer = EmbeddedTestServer.createAndStartServer(appContext);
-        mTestPage = mTestServer.getURL(TEST_PAGE);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mTestServer.stopAndDestroyServer();
-    }
-
-    @Test
-    @SmallTest
-    public void testShowDownloadManagerNoActivitiesRunning() {
-        Assert.assertNull(ApplicationStatus.getLastTrackedFocusedActivity());
-
-        showDownloadManager();
-
-        CriteriaHelper.pollUiThread(
-                new Criteria("DownloadActivity should be last tracked focused activity.") {
-                    @Override
-                    public boolean isSatisfied() {
-                        return ApplicationStatus.getLastTrackedFocusedActivity()
-                                       instanceof DownloadActivity;
-                    }
-                });
-    }
-
-    @Test
-    @SmallTest
-    public void testShowDownloadManagerLastTrackedActivityCustomTab_TabbedActivityNotRunning() {
-        startCustomTabActivity();
-        showDownloadManager();
-
-        CriteriaHelper.pollUiThread(
-                new Criteria("DownloadActivity should be last tracked focused activity.") {
-                    @Override
-                    public boolean isSatisfied() {
-                        return ApplicationStatus.getLastTrackedFocusedActivity()
-                                       instanceof DownloadActivity;
-                    }
-                });
-    }
-
-    @Test
-    @SmallTest
-    public void testShowDownloadManagerLastTrackedActivityCustomTab_TabbedActivityRunning()
-            throws InterruptedException {
-        startTabbedActivity();
-        startCustomTabActivity();
-        showDownloadManager();
-        assertBottomSheetShowingDownloadsManager();
-    }
-
-    @Test
-    @SmallTest
-    public void testShowDownloadManagerLastTrackedActivityNull_TabbedActivityRunning()
-            throws InterruptedException {
-        startTabbedActivity();
-        startCustomTabActivity();
-
-        // Go to the home screen so that the ChromeTabbedActivity does not resume when the
-        // CustomTabActivity is killed.
-        ThreadUtils.runOnUiThreadBlocking(() -> {
-            Intent intent = new Intent(Intent.ACTION_MAIN);
-            intent.addCategory(Intent.CATEGORY_HOME);
-            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            InstrumentationRegistry.getTargetContext().startActivity(intent);
-        });
-
-        // Finish the custom tab activity and assert that the last tracked focused activity is null.
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> { ApplicationStatus.getLastTrackedFocusedActivity().finish(); });
-        CriteriaHelper.pollUiThread(new Criteria("Last tracked focused activity should be null.") {
-            @Override
-            public boolean isSatisfied() {
-                return ApplicationStatus.getLastTrackedFocusedActivity() == null;
-            }
-        });
-
-        showDownloadManager();
-        assertBottomSheetShowingDownloadsManager();
-    }
-
-    private void startTabbedActivity() throws InterruptedException {
-        mBottomSheetTestRule.startMainActivityOnBlankPage();
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-    }
-
-    private void startCustomTabActivity() {
-        final Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(
-                InstrumentationRegistry.getTargetContext(), mTestPage);
-
-        try {
-            mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
-        } catch (InterruptedException e) {
-            Assert.fail("Failed to create CustomTabActivity");
-        }
-
-        CriteriaHelper.pollUiThread(
-                new Criteria("CustomTabActivity should be last focused activity.") {
-                    @Override
-                    public boolean isSatisfied() {
-                        return ApplicationStatus.getLastTrackedFocusedActivity()
-                                       instanceof CustomTabActivity;
-                    }
-                });
-    }
-
-    private void showDownloadManager() {
-        ThreadUtils.runOnUiThreadBlocking(() -> { DownloadUtils.showDownloadManager(null, null); });
-    }
-
-    private void assertBottomSheetShowingDownloadsManager() {
-        CriteriaHelper.pollUiThread(new Criteria("ChromeTabbedActivity should be resumed.") {
-            @Override
-            public boolean isSatisfied() {
-                return ApplicationStatus.getStateForActivity(mBottomSheetTestRule.getActivity())
-                        == ActivityState.RESUMED;
-            }
-        });
-
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> { mBottomSheetTestRule.getBottomSheet().endAnimations(); });
-
-        CriteriaHelper.pollUiThread(new Criteria("Animations sould be finished.") {
-            @Override
-            public boolean isSatisfied() {
-                return !mBottomSheetTestRule.getBottomSheet().isRunningSettleAnimation()
-                        && !mBottomSheetTestRule.getBottomSheet().isRunningContentSwapAnimation();
-            }
-        });
-
-        Assert.assertEquals("Bottom sheet should be at full height", BottomSheet.SHEET_STATE_FULL,
-                mBottomSheetTestRule.getBottomSheet().getSheetState());
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/StubbedProvider.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/StubbedProvider.java
index 0f9d559..354d6a4 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/StubbedProvider.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/StubbedProvider.java
@@ -80,7 +80,8 @@
         }
 
         @Override
-        public void removeDownload(final String guid, final boolean isOffTheRecord) {
+        public void removeDownload(
+                final String guid, final boolean isOffTheRecord, boolean externallyRemoved) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarAppearanceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarAppearanceTest.java
index 9ae80f0..4eed5d7 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarAppearanceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarAppearanceTest.java
@@ -36,7 +36,6 @@
 // clang-format off
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-@ScreenShooter.Directory("InfoBars")
 public class InfoBarAppearanceTest {
     // clang-format on
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageUiCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageUiCaptureTest.java
index 9014d77..e5291066 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageUiCaptureTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageUiCaptureTest.java
@@ -94,7 +94,6 @@
     @Test
     @MediumTest
     @Feature({"NewTabPage", "UiCatalogue"})
-    @ScreenShooter.Directory("New Tab Page")
     public void testCaptureNewTabPage() {
         assertThat(ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_MODERN_LAYOUT),
                 is(mEnableNTPModernLayout));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
index 709509c..06ac73d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
@@ -4,9 +4,6 @@
 
 package org.chromium.chrome.browser.ntp.snippets;
 
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Color;
@@ -31,16 +28,12 @@
 import org.chromium.base.Callback;
 import org.chromium.base.DiscardableReferencePool;
 import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
 import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
-import org.chromium.base.test.params.ParameterSet;
-import org.chromium.base.test.params.ParameterizedRunner;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
-import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.favicon.IconType;
 import org.chromium.chrome.browser.favicon.LargeIconBridge;
@@ -61,22 +54,20 @@
 import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView;
 import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate;
 import org.chromium.chrome.browser.suggestions.ThumbnailGradient;
-import org.chromium.chrome.browser.util.FeatureUtilities;
 import org.chromium.chrome.browser.widget.ThumbnailProvider;
 import org.chromium.chrome.browser.widget.ThumbnailProvider.ThumbnailRequest;
 import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle;
 import org.chromium.chrome.browser.widget.displaystyle.UiConfig;
 import org.chromium.chrome.browser.widget.displaystyle.VerticalDisplayStyle;
 import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
 import org.chromium.chrome.test.util.RenderTestRule;
-import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.chrome.test.util.browser.compositor.layouts.DisableChromeAnimations;
 import org.chromium.chrome.test.util.browser.suggestions.DummySuggestionsEventReporter;
 import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource;
 import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule;
 import org.chromium.net.NetworkChangeNotifier;
-import org.chromium.ui.base.DeviceFormFactor;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -86,7 +77,7 @@
 /**
  * Tests for the appearance of Article Snippets.
  */
-@RunWith(ParameterizedRunner.class)
+@RunWith(ChromeJUnit4ClassRunner.class)
 @UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
 public class ArticleSnippetsTest {
@@ -103,17 +94,6 @@
     @Rule
     public TestRule mDisableChromeAnimations = new DisableChromeAnimations();
 
-    private final boolean mChromeHomeEnabled;
-
-    @ClassParameter
-    private static List<ParameterSet> sClassParams = new ArrayList<>();
-    static {
-        sClassParams.add(new ParameterSet().name("ChromeHomeDisabled").value(false));
-        if (!DeviceFormFactor.isTablet()) {
-            sClassParams.add(new ParameterSet().name("ChromeHomeEnabled").value(true));
-        }
-    }
-
     private SuggestionsUiDelegate mUiDelegate;
     private FakeSuggestionsSource mSnippetsSource;
     private MockThumbnailProvider mThumbnailProvider;
@@ -131,21 +111,8 @@
 
     private long mTimestamp;
 
-    public ArticleSnippetsTest(boolean chromeHomeEnabled) {
-        mChromeHomeEnabled = chromeHomeEnabled;
-        if (chromeHomeEnabled) {
-            mRenderTestRule.setVariantPrefix("modern");
-        }
-    }
-
     @Before
     public void setUp() throws Exception {
-        if (mChromeHomeEnabled) {
-            Features.getInstance().enable(ChromeFeatureList.CHROME_HOME);
-        } else {
-            Features.getInstance().disable(ChromeFeatureList.CHROME_HOME);
-        }
-
         mActivityTestRule.startMainActivityOnBlankPage();
         mThumbnailProvider = new MockThumbnailProvider();
         mSnippetsSource = new FakeSuggestionsSource();
@@ -164,13 +131,6 @@
         });
 
         ThreadUtils.runOnUiThreadBlocking(() -> {
-            FeatureUtilities.resetChromeHomeEnabledForTests();
-            FeatureUtilities.cacheChromeHomeEnabled();
-        });
-
-        assertThat(FeatureUtilities.isChromeHomeEnabled(), is(mChromeHomeEnabled));
-
-        ThreadUtils.runOnUiThreadBlocking(() -> {
             ChromeActivity activity = mActivityTestRule.getActivity();
             mContentView = new FrameLayout(activity);
             mUiConfig = new UiConfig(mContentView);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/BottomSheetLocationBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/BottomSheetLocationBarTest.java
deleted file mode 100644
index e9435a9..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/BottomSheetLocationBarTest.java
+++ /dev/null
@@ -1,158 +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.
-
-package org.chromium.chrome.browser.omnibox;
-
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.isEmptyString;
-import static org.hamcrest.Matchers.not;
-
-import android.annotation.SuppressLint;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.widget.ImageButton;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.CallbackHelper;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Restriction;
-import org.chromium.base.test.util.parameter.CommandLineParameter;
-import org.chromium.base.test.util.parameter.SkipCommandLineParameterization;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeFeatureList;
-import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
-import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
-import org.chromium.chrome.test.BottomSheetTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.net.test.EmbeddedTestServer;
-import org.chromium.net.test.ServerCertificate;
-import org.chromium.ui.test.util.UiRestriction;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-
-/**
- * Tests for {@link LocationBarLayout} UI component in the home sheet.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-@CommandLineParameter({"", "disable-features=" + ChromeFeatureList.SPANNABLE_INLINE_AUTOCOMPLETE})
-@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
-@SuppressLint("SetTextI18n")
-public class BottomSheetLocationBarTest {
-    @Rule
-    public BottomSheetTestRule mBottomSheetTestRule = new BottomSheetTestRule();
-
-    private EmbeddedTestServer mTestServer;
-
-    private static final String THEME_COLOR_TEST_PAGE =
-            "/chrome/test/data/android/theme_color_test.html";
-
-    private final CallbackHelper mDidThemeColorChangedCallbackHelper = new CallbackHelper();
-    private final CallbackHelper mOnSSLStateUpdatedCallbackHelper = new CallbackHelper();
-
-    @Before
-    public void setUp() throws Exception {
-        mBottomSheetTestRule.startMainActivityOnBlankPage();
-        new TabModelSelectorTabObserver(mBottomSheetTestRule.getActivity().getTabModelSelector()) {
-            @Override
-            public void onDidChangeThemeColor(Tab tab, int color) {
-                mDidThemeColorChangedCallbackHelper.notifyCalled();
-            }
-            @Override
-            public void onSSLStateUpdated(Tab tab) {
-                mOnSSLStateUpdatedCallbackHelper.notifyCalled();
-            }
-        };
-        mTestServer = EmbeddedTestServer.createAndStartHTTPSServer(
-                InstrumentationRegistry.getInstrumentation().getContext(),
-                ServerCertificate.CERT_OK);
-    }
-
-    @After
-    public void tearDown() {
-        mTestServer.stopAndDestroyServer();
-    }
-
-    /**
-     * Test whether the contents of the location bar are correct for HTTPS scheme.
-     */
-    @Test
-    @SmallTest
-    @SkipCommandLineParameterization
-    @CommandLineFlags.Add({"enable-features=" + ChromeFeatureList.CHROME_HOME_CLEAR_URL_ON_OPEN})
-    public void testHttpsLocationBar() throws Exception {
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-
-        final String testHttpsUrl = mTestServer.getURL(THEME_COLOR_TEST_PAGE);
-
-        mBottomSheetTestRule.loadUrl(testHttpsUrl);
-        mDidThemeColorChangedCallbackHelper.waitForCallback(0);
-        mOnSSLStateUpdatedCallbackHelper.waitForCallback(0);
-
-        LocationBarLayout locationBarLayout =
-                (LocationBarLayout) mBottomSheetTestRule.getActivity().findViewById(
-                        R.id.location_bar);
-        ImageButton securityButton =
-                (ImageButton) mBottomSheetTestRule.getActivity().findViewById(R.id.security_button);
-
-        Assert.assertTrue(
-                "Omnibox should have a security icon", isSecurityButtonShown(locationBarLayout));
-        Assert.assertEquals("security_button with wrong resource-id", R.id.security_button,
-                securityButton.getId());
-
-        Assert.assertTrue(shouldEmphasizeHttpsScheme(locationBarLayout));
-
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_HALF, false);
-
-        Assert.assertFalse("Omnibox should not have a security icon",
-                isSecurityButtonShown(locationBarLayout));
-        Assert.assertThat("Url bar text should be empty.", getLocationBarText(locationBarLayout),
-                isEmptyString());
-
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-
-        Assert.assertTrue(
-                "Omnibox should have a security icon", isSecurityButtonShown(locationBarLayout));
-        Assert.assertThat("Url bar text should not be empty.",
-                getLocationBarText(locationBarLayout), is(not(isEmptyString())));
-    }
-
-    private boolean isSecurityButtonShown(LocationBarLayout locationBar) throws ExecutionException {
-        return ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
-            @Override
-            public Boolean call() {
-                return locationBar.isSecurityButtonShown();
-            }
-        });
-    }
-
-    private String getLocationBarText(LocationBarLayout locationBar) throws ExecutionException {
-        return ThreadUtils.runOnUiThreadBlocking(new Callable<String>() {
-            @Override
-            public String call() {
-                return locationBar.mUrlBar.getText().toString();
-            }
-        });
-    }
-
-    private boolean shouldEmphasizeHttpsScheme(LocationBarLayout locationBar)
-            throws ExecutionException {
-        return ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
-            @Override
-            public Boolean call() {
-                return locationBar.shouldEmphasizeHttpsScheme();
-            }
-        });
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/ContextualSuggestionsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/ContextualSuggestionsTest.java
index 4aee2f1a..b1fb8bd1 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/ContextualSuggestionsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/ContextualSuggestionsTest.java
@@ -46,6 +46,7 @@
 /**
  * Integration tests for Contextual suggestions.
  */
+@DisabledTest(message = "https://crbug.com/805160")
 @RunWith(ChromeJUnit4ClassRunner.class)
 @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
 public class ContextualSuggestionsTest {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetCardsUiCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetCardsUiCaptureTest.java
index c86d5cd..afbb812 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetCardsUiCaptureTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetCardsUiCaptureTest.java
@@ -18,6 +18,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.R;
@@ -39,6 +40,7 @@
 /**
  * Tests for the appearance of the card suggestions in the home sheet.
  */
+@DisabledTest(message = "https://crbug.com/805160")
 @RunWith(ChromeJUnit4ClassRunner.class)
 @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
 public class HomeSheetCardsUiCaptureTest {
@@ -64,7 +66,6 @@
     @Test
     @MediumTest
     @Feature({"UiCatalogue"})
-    @ScreenShooter.Directory("HomeSheetCards")
     public void testContextMenu() throws Exception {
         mActivityRule.setSheetState(BottomSheet.SHEET_STATE_FULL, false);
         waitForWindowUpdates();
@@ -77,7 +78,6 @@
     @Test
     @MediumTest
     @Feature({"UiCatalogue"})
-    @ScreenShooter.Directory("HomeSheetCards")
     public void testScrolling() throws Exception {
         mActivityRule.setSheetState(BottomSheet.SHEET_STATE_FULL, false);
         waitForWindowUpdates();
@@ -105,7 +105,6 @@
     @Test
     @MediumTest
     @Feature({"UiCatalogue"})
-    @ScreenShooter.Directory("HomeSheetCards")
     public void testContentSuggestionPlaceholder() throws Exception {
         FakeSuggestionsSource source = (FakeSuggestionsSource) mDepsFactory.suggestionsSource;
         source.setSuggestionsForCategory(KnownCategories.ARTICLES, Collections.emptyList());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetNoTilesUiCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetNoTilesUiCaptureTest.java
index 3426e860..4888be5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetNoTilesUiCaptureTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetNoTilesUiCaptureTest.java
@@ -13,6 +13,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.ntp.NtpUiCaptureTestData;
@@ -27,6 +28,7 @@
 /**
  * Tests for the appearance of the home sheet when there are no tiles.
  */
+@DisabledTest(message = "https://crbug.com/805160")
 @RunWith(ChromeJUnit4ClassRunner.class)
 @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
 public class HomeSheetNoTilesUiCaptureTest {
@@ -52,7 +54,6 @@
     @Test
     @MediumTest
     @Feature({"UiCatalogue"})
-    @ScreenShooter.Directory("HomeSheetTiles")
     public void testNoTiles() {
         mActivityRule.setSheetState(BottomSheet.SHEET_STATE_FULL, false);
         waitForWindowUpdates();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetTilesUiCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetTilesUiCaptureTest.java
index 171f61b2..4e44c9a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetTilesUiCaptureTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetTilesUiCaptureTest.java
@@ -17,6 +17,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.ntp.NtpUiCaptureTestData;
@@ -31,6 +32,7 @@
 /**
  * Tests for the appearance of the tile suggestions in the home sheet.
  */
+@DisabledTest(message = "https://crbug.com/805160")
 @RunWith(ChromeJUnit4ClassRunner.class)
 @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
 public class HomeSheetTilesUiCaptureTest {
@@ -54,7 +56,6 @@
     @Test
     @MediumTest
     @Feature({"UiCatalogue"})
-    @ScreenShooter.Directory("HomeSheetTiles")
     public void testAppearance() {
         mActivityRule.setSheetState(BottomSheet.SHEET_STATE_FULL, false);
         waitForWindowUpdates();
@@ -64,7 +65,6 @@
     @Test
     @MediumTest
     @Feature({"UiCatalogue"})
-    @ScreenShooter.Directory("HomeSheetTiles")
     public void testContextMenu() {
         mActivityRule.setSheetState(BottomSheet.SHEET_STATE_FULL, false);
         waitForWindowUpdates();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetUiCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetUiCaptureTest.java
index fb36690..2f5205f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetUiCaptureTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/HomeSheetUiCaptureTest.java
@@ -20,6 +20,7 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.params.MethodParamAnnotationRule;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.ntp.NtpUiCaptureTestData;
@@ -35,9 +36,9 @@
 /**
  * Tests for the appearance of the special states of the home sheet.
  */
+@DisabledTest(message = "https://crbug.com/805160")
 @RunWith(ChromeJUnit4ClassRunner.class)
 @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
-@ScreenShooter.Directory("HomeSheetStates")
 public class HomeSheetUiCaptureTest {
     @Rule
     public SuggestionsBottomSheetTestRule mActivityRule = new SuggestionsBottomSheetTestRule();
@@ -61,7 +62,6 @@
     @Test
     @MediumTest
     @Feature({"UiCatalogue"})
-    @ScreenShooter.Directory("SignInPromo")
     public void testSignInPromo() {
         // Needs to be "Full" to for this to work on small screens in landscape.
         mActivityRule.setSheetState(BottomSheet.SHEET_STATE_FULL, false);
@@ -74,7 +74,6 @@
     @Test
     @MediumTest
     @Feature({"UiCatalogue"})
-    @ScreenShooter.Directory("AllDismissed")
     public void testAllDismissed() {
         NewTabPageAdapter adapter = mActivityRule.getAdapter();
         ThreadUtils.runOnUiThreadBlocking(() -> {
@@ -98,7 +97,6 @@
     @Test
     @MediumTest
     @Feature({"UiCatalogue"})
-    @ScreenShooter.Directory("NewTab")
     public void testNewTab() {
         // Select "New tab" from the menu.
         MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java
index 436cbb0..fdac528 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetTest.java
@@ -19,6 +19,7 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ntp.NtpUiCaptureTestData;
@@ -31,6 +32,7 @@
 /**
  * Instrumentation tests for {@link SuggestionsBottomSheetContent}.
  */
+@DisabledTest(message = "https://crbug.com/805160")
 @RunWith(ChromeJUnit4ClassRunner.class)
 @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
 public class SuggestionsBottomSheetTest {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java
index fa354d7..bb5a9f8 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsBottomSheetUiCaptureTest.java
@@ -13,6 +13,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.ntp.NtpUiCaptureTestData;
@@ -26,6 +27,7 @@
 /**
  * Tests for the appearance of the home sheet in different bottom sheet states.
  */
+@DisabledTest
 @RunWith(ChromeJUnit4ClassRunner.class)
 @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
 public class SuggestionsBottomSheetUiCaptureTest {
@@ -49,7 +51,6 @@
     @Test
     @MediumTest
     @Feature({"UiCatalogue"})
-    @ScreenShooter.Directory("SuggestionsBottomSheetPosition")
     public void testBottomSheetPosition() throws Exception {
         mActivityRule.setSheetState(BottomSheet.SHEET_STATE_HALF, false);
         waitForWindowUpdates();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsSheetVisibilityChangeObserverTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsSheetVisibilityChangeObserverTest.java
index 6af91620..4cecaae3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsSheetVisibilityChangeObserverTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/SuggestionsSheetVisibilityChangeObserverTest.java
@@ -26,6 +26,7 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.R;
@@ -43,6 +44,7 @@
 /**
  * Instrumentation tests for {@link SuggestionsSheetVisibilityChangeObserver}.
  */
+@DisabledTest(message = "https://crbug.com/805160")
 @RunWith(ChromeJUnit4ClassRunner.class)
 @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
 public class SuggestionsSheetVisibilityChangeObserverTest {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/TileGridLayoutTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/TileGridLayoutTest.java
index db0c1f31..b5a58137 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/TileGridLayoutTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/TileGridLayoutTest.java
@@ -245,6 +245,7 @@
         mRenderTestRule.render(tileGridLayout, "two_tiles_grid_landscape");
     }
 
+    @DisabledTest(message = "https://crbug.com/805160")
     @Test
     @MediumTest
     @Feature({"NewTabPage", "RenderTest"})
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/test/ScreenShooter.java b/chrome/android/javatests/src/org/chromium/chrome/browser/test/ScreenShooter.java
index 25dad71b9..51a55280 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/test/ScreenShooter.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/test/ScreenShooter.java
@@ -29,10 +29,6 @@
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
 import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.Date;
@@ -43,15 +39,16 @@
 
 /**
  * Rule for taking screen shots within tests. Screenshots are saved as
- * {@code screenshot_dir/test_class_directory/test_directory/shot_name random.png}.
+ * {@code screenshot_dir/shot_name random.png}.
  * The associated JSON file describing the screenshot is saved as
- * {@code screenshot_dir/test_class_directory/test_directory/shot_name random.json}.
+ * {@code screenshot_dir/shot_name random.json}.
  * <p>
  * {@code screenshot_dir} comes from the instrumentation test command line, which is set by the
- * test runners. {@code test_class_directory} and {@code test_directory} can both the set by the
- * {@link ScreenShooter.Directory} annotation. {@code test_class_directory} defaults to nothing
- * (i.e. no directory created at this level), and {@code test_directory} defaults to the name of
- * the individual test. {@code random} is a random value to make the filenames unique.
+ * test runners
+ * <p>
+ * {@code shot_name} is the argument to {@code shoot()}
+ * </p>
+ * {@code random} is a random value to make the filenames unique.
  * <p>
  * The JSON file contains three categories of data:
  * <dl>
@@ -70,7 +67,6 @@
  * &#064;RunWith(ChromeJUnit4ClassRunner.class)
  * &#064;CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
  * &#064;Restriction(RESTRICTION_TYPE_PHONE) // Tab switcher button only exists on phones.
- * &#064;ScreenShooter.Directory("Example")
  * public class ExampleUiCaptureTest {
  *     &#064;Rule
  *     public ChromeActivityTestRule<ChromeTabbedActivity> mActivityTestRule =
@@ -88,7 +84,6 @@
  *     &#064;Test
  *     &#064;SmallTest
  *     &#064;Feature({"UiCatalogue"})
- *     &#064;ScreenShooter.Directory("TabSwitcher")
  *     public void testCaptureTabSwitcher() throws IOException, InterruptedException {
  *         mScreenShooter.shoot("NTP");
  *         Espresso.onView(ViewMatchers.withId(R.id.tab_switcher_button)).
@@ -120,7 +115,6 @@
 
     private final UiDevice mDevice;
     private final String mBaseDir;
-    private File mDir;
     private String mTestClassName;
     private String mTestMethodName;
     private static final String[] FILTERS = {TEST_CLASS_FILTER, TEST_METHOD_FILTER,
@@ -137,12 +131,6 @@
         UiCatalogueExample,
     }
 
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target({ElementType.TYPE, ElementType.METHOD})
-    public @interface Directory {
-        String value();
-    }
-
     public ScreenShooter() {
         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
         mDevice = UiDevice.getInstance(instrumentation);
@@ -151,20 +139,9 @@
 
     @Override
     protected void starting(Description d) {
-        mDir = new File(mBaseDir);
         mTestClassName = d.getClassName();
         mTestMethodName = d.getMethodName();
         Class<?> testClass = d.getTestClass();
-        Directory classDirectoryAnnotation = testClass.getAnnotation(Directory.class);
-        String classDirName =
-                classDirectoryAnnotation == null ? "" : classDirectoryAnnotation.value();
-        if (!classDirName.isEmpty()) mDir = new File(mBaseDir, classDirName);
-        Directory methodDirectoryAnnotation = d.getAnnotation(Directory.class);
-        String testMethodDir = methodDirectoryAnnotation == null
-                ? d.getMethodName()
-                : methodDirectoryAnnotation.value();
-        if (!testMethodDir.isEmpty()) mDir = new File(mDir, testMethodDir);
-        if (!mDir.exists()) assertTrue("Create screenshot directory", mDir.mkdirs());
         mFeatures = d.getAnnotation(Feature.class).value();
     }
 
@@ -180,7 +157,7 @@
      * @param tags User selected tags from {@link TagsEnum}.
      */
     public void shoot(String shotName, TagsEnum... tags) {
-        assertNotNull("ScreenShooter rule initialized", mDir);
+        assertNotNull("ScreenShooter rule initialized", mTestClassName);
         Map<String, String> filters = new HashMap<>();
         setFilterValue(filters, TEST_CLASS_FILTER, mTestClassName);
         setFilterValue(filters, TEST_METHOD_FILTER, mTestMethodName);
@@ -223,7 +200,7 @@
         metadata.put("Android build fingerprint", Build.FINGERPRINT);
 
         try {
-            File shotFile = File.createTempFile(shotName, IMAGE_SUFFIX, mDir);
+            File shotFile = File.createTempFile(shotName, IMAGE_SUFFIX, new File(mBaseDir));
             assertTrue("Screenshot " + shotName, mDevice.takeScreenshot(shotFile));
             writeImageDescription(shotFile, filters, tags, metadata);
         } catch (IOException e) {
@@ -253,7 +230,7 @@
         String jsonFileName =
                 shotFileName.substring(0, shotFileName.length() - IMAGE_SUFFIX.length())
                 + JSON_SUFFIX;
-        try (FileWriter fileWriter = new FileWriter(new File(mDir, jsonFileName));) {
+        try (FileWriter fileWriter = new FileWriter(new File(mBaseDir, jsonFileName));) {
             fileWriter.write(imageDescription.toString());
         }
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetBackBehaviorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetBackBehaviorTest.java
deleted file mode 100644
index 8f717cc..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetBackBehaviorTest.java
+++ /dev/null
@@ -1,302 +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.
-
-package org.chromium.chrome.browser.widget.bottomsheet;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.provider.Browser;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.DisabledTest;
-import org.chromium.base.test.util.FlakyTest;
-import org.chromium.base.test.util.Restriction;
-import org.chromium.base.test.util.RetryOnFailure;
-import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.ChromeTabbedActivity;
-import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
-import org.chromium.chrome.test.BottomSheetTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.ChromeTabUtils;
-import org.chromium.content.browser.test.util.CriteriaHelper;
-import org.chromium.net.test.EmbeddedTestServer;
-import org.chromium.ui.test.util.UiRestriction;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Tests the behavior of the bottom sheet when used with the back button.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
-public class BottomSheetBackBehaviorTest {
-    private static final String TEST_PAGE = "/chrome/test/data/android/simple.html";
-
-    private BottomSheet mBottomSheet;
-    private ChromeTabbedActivity mActivity;
-    private LayoutManagerChrome mLayoutManager;
-
-    @Rule
-    public BottomSheetTestRule mBottomSheetTestRule = new BottomSheetTestRule();
-
-    @Before
-    public void setUp() throws Exception {
-        mBottomSheetTestRule.startMainActivityOnBlankPage();
-        mBottomSheet = mBottomSheetTestRule.getBottomSheet();
-        mActivity = mBottomSheetTestRule.getActivity();
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-        mLayoutManager = mActivity.getLayoutManager();
-    }
-
-    @Test
-    @SmallTest
-    public void testBackButton_sheetOpen() {
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_HALF, false);
-
-        pressBackButton();
-        endBottomSheetAnimations();
-
-        assertFalse("Overview mode should not be showing.", mLayoutManager.overviewVisible());
-        assertEquals("The bottom sheet should be peeking.", BottomSheet.SHEET_STATE_PEEK,
-                mBottomSheet.getSheetState());
-    }
-
-    @Test
-    @SmallTest
-    public void testBackButton_tabSwitcher() throws InterruptedException, TimeoutException {
-        ThreadUtils.runOnUiThreadBlocking(() -> mLayoutManager.showOverview(false));
-
-        assertTrue("Overview mode should be showing.", mLayoutManager.overviewVisible());
-
-        pressBackButton();
-        endBottomSheetAnimations();
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> mLayoutManager.getActiveLayout().finishAnimationsForTests());
-
-        assertFalse("Overview mode should not be showing.", mLayoutManager.overviewVisible());
-        assertEquals("The bottom sheet should be peeking.", BottomSheet.SHEET_STATE_PEEK,
-                mBottomSheet.getSheetState());
-    }
-
-    @Test
-    @SmallTest
-    public void testBackButton_backFromInternalNewTab()
-            throws ExecutionException, InterruptedException, TimeoutException {
-        Tab tab = launchNewTabFromChrome("about:blank");
-
-        assertEquals("Tab should be on about:blank.", "about:blank", tab.getUrl());
-
-        // Back button press should open the bottom sheet since backward navigation is not
-        // possible.
-        pressBackButton();
-        endBottomSheetAnimations();
-
-        assertEquals("The bottom sheet should be at half height.", BottomSheet.SHEET_STATE_HALF,
-                mBottomSheet.getSheetState());
-        assertFalse("Overview mode should not be showing.", mLayoutManager.overviewVisible());
-
-        // Final back press should close the sheet and chrome.
-        pressBackButton();
-        endBottomSheetAnimations();
-
-        assertEquals("The bottom sheet should be peeking.", BottomSheet.SHEET_STATE_PEEK,
-                mBottomSheet.getSheetState());
-        waitForClose();
-    }
-
-    @Test
-    @SmallTest
-    public void testBackButton_backFromInternalNewTab_sheetOpen()
-            throws ExecutionException, InterruptedException, TimeoutException {
-        Tab tab = launchNewTabFromChrome("about:blank");
-
-        assertEquals("Tab should be on about:blank.", "about:blank", tab.getUrl());
-
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_HALF, false);
-
-        // Back button should close the sheet but not send Chrome to the background.
-        pressBackButton();
-        endBottomSheetAnimations();
-
-        assertEquals("The bottom sheet should be peeking.", BottomSheet.SHEET_STATE_PEEK,
-                mBottomSheet.getSheetState());
-        assertTrue("Chrome should have focus.", mActivity.hasWindowFocus());
-
-        // Back button press should open the bottom sheet since backward navigation is not
-        // possible.
-        pressBackButton();
-        endBottomSheetAnimations();
-
-        assertEquals("The bottom sheet should be at half height.", BottomSheet.SHEET_STATE_HALF,
-                mBottomSheet.getSheetState());
-        assertFalse("Overview mode should not be showing.", mLayoutManager.overviewVisible());
-
-        // Final back press should close the sheet and chrome.
-        pressBackButton();
-        endBottomSheetAnimations();
-
-        assertEquals("The bottom sheet should be peeking.", BottomSheet.SHEET_STATE_PEEK,
-                mBottomSheet.getSheetState());
-        waitForClose();
-    }
-
-    @Test
-    @FlakyTest(message = "https://crbug.com/792107")
-    @SmallTest
-    @RetryOnFailure
-    public void testBackButton_backButtonOpensSheetAndShowsToolbar()
-            throws ExecutionException, InterruptedException, TimeoutException {
-        final Tab tab = launchNewTabFromChrome("about:blank");
-
-        assertEquals("Tab should be on about:blank.", "about:blank", tab.getUrl());
-
-        assertEquals("The bottom sheet should be peeking.", BottomSheet.SHEET_STATE_PEEK,
-                mBottomSheet.getSheetState());
-
-        // This also waits for the controls to be hidden.
-        hideBrowserControls(tab);
-
-        // Back button press should open the bottom sheet since backward navigation is not
-        // possible and show the toolbar.
-        pressBackButton();
-        endBottomSheetAnimations();
-
-        waitForShownBrowserControls();
-        assertEquals("The bottom sheet should be at half height.", BottomSheet.SHEET_STATE_HALF,
-                mBottomSheet.getSheetState());
-    }
-
-    @Test
-    @SmallTest
-    public void testBackButton_backWithNavigation()
-            throws ExecutionException, InterruptedException, TimeoutException {
-        final Tab tab = mBottomSheet.getActiveTab();
-
-        EmbeddedTestServer testServer =
-                EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
-
-        String testUrl = testServer.getURL(TEST_PAGE);
-        ChromeTabUtils.loadUrlOnUiThread(tab, testUrl);
-        ChromeTabUtils.waitForTabPageLoaded(tab, testUrl);
-
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_HALF, false);
-
-        // Back button should close the bottom sheet.
-        pressBackButton();
-        endBottomSheetAnimations();
-
-        assertEquals("Tab should be on the test page.", testUrl, tab.getUrl());
-        assertEquals("The bottom sheet should be peeking.", BottomSheet.SHEET_STATE_PEEK,
-                mBottomSheet.getSheetState());
-        assertFalse("Overview mode should not be showing.", mLayoutManager.overviewVisible());
-
-        // Next back button press should navigate back.
-        pressBackButton();
-        endBottomSheetAnimations();
-        ChromeTabUtils.waitForTabPageLoaded(tab, "about:blank");
-
-        assertEquals("Tab should be on about:blank.", "about:blank", tab.getUrl());
-        assertEquals("The bottom sheet should be peeking.", BottomSheet.SHEET_STATE_PEEK,
-                mBottomSheet.getSheetState());
-        assertFalse("Overview mode should not be showing.", mLayoutManager.overviewVisible());
-    }
-
-    @Test
-    @SmallTest
-    @DisabledTest(message = "crbug.com/766350")
-    public void testBackButton_backFromExternalNewTab()
-            throws InterruptedException, TimeoutException {
-        EmbeddedTestServer testServer =
-                EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
-        launchNewTabFromExternalApp(testServer.getURL(TEST_PAGE));
-
-        // Back button should send Chrome to the background.
-        pressBackButton();
-        endBottomSheetAnimations();
-
-        assertEquals("The bottom sheet should be peeking.", BottomSheet.SHEET_STATE_PEEK,
-                mBottomSheet.getSheetState());
-        waitForClose();
-    }
-
-    /**
-     * Launch a new tab from an "external" app.
-     * @param url The URL to launch in the tab.
-     */
-    private void launchNewTabFromExternalApp(String url) throws InterruptedException {
-        final Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.putExtra(Browser.EXTRA_APPLICATION_ID, "externalApp");
-        intent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true);
-        intent.setData(Uri.parse(url));
-
-        final Tab originalTab = mActivity.getActivityTab();
-        ThreadUtils.runOnUiThreadBlocking(() -> mActivity.onNewIntent(intent));
-        CriteriaHelper.pollUiThread(
-                () -> mActivity.getActivityTab() != originalTab, "Failed to select different tab");
-        ChromeTabUtils.waitForTabPageLoaded(mActivity.getActivityTab(), url);
-    }
-
-    /**
-     * Launch a new tab from Chrome internally.
-     * @param url The URL to launch in the tab.
-     */
-    private Tab launchNewTabFromChrome(final String url) throws ExecutionException {
-        return ThreadUtils.runOnUiThreadBlocking(
-                () -> mActivity.getTabCreator(false).launchUrl(url, TabLaunchType.FROM_CHROME_UI));
-    }
-
-    /**
-     * Wait for the browser controls to be hidden.
-     * @param tab The active tab.
-     */
-    private void hideBrowserControls(final Tab tab) throws ExecutionException {
-        // Hide the browser controls.
-        ThreadUtils.runOnUiThreadBlocking(
-                ()
-                        -> tab.getActivity()
-                                   .getFullscreenManager()
-                                   .setHideBrowserControlsAndroidView(true));
-
-        CriteriaHelper.pollUiThread(mBottomSheet::isToolbarAndroidViewHidden);
-    }
-
-    /**
-     * Wait for the browser controls to be shown.
-     */
-    private void waitForShownBrowserControls() throws ExecutionException {
-        CriteriaHelper.pollUiThread(() -> !mBottomSheet.isToolbarAndroidViewHidden());
-    }
-
-    /** Notify the activity that the hardware back button was pressed. */
-    private void pressBackButton() {
-        ThreadUtils.runOnUiThreadBlocking(mActivity::onBackPressed);
-    }
-
-    /** End bottom sheet animations. */
-    private void endBottomSheetAnimations() {
-        ThreadUtils.runOnUiThreadBlocking(mBottomSheet::endAnimations);
-    }
-
-    /** Wait until Chrome doesn't have window focus. */
-    private void waitForClose() {
-        // It takes some time for Chrome to completely close.
-        CriteriaHelper.pollUiThread(() -> !mActivity.hasWindowFocus());
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentControllerTest.java
deleted file mode 100644
index 4d64fa43..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetContentControllerTest.java
+++ /dev/null
@@ -1,187 +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.
-
-package org.chromium.chrome.browser.widget.bottomsheet;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.support.test.filters.SmallTest;
-import android.view.View;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Restriction;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeFeatureList;
-import org.chromium.chrome.browser.ChromeTabbedActivity;
-import org.chromium.chrome.browser.bookmarks.BookmarkSheetContent;
-import org.chromium.chrome.browser.bookmarks.BookmarkUtils;
-import org.chromium.chrome.browser.download.DownloadSheetContent;
-import org.chromium.chrome.browser.download.DownloadUtils;
-import org.chromium.chrome.browser.history.HistoryManagerUtils;
-import org.chromium.chrome.browser.history.HistorySheetContent;
-import org.chromium.chrome.test.BottomSheetTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.ui.test.util.UiRestriction;
-
-import java.util.concurrent.TimeoutException;
-
-/** This class tests the functionality of the {@link BottomSheetContentController}. */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
-public class BottomSheetContentControllerTest {
-    private BottomSheetTestRule.Observer mObserver;
-    private BottomSheet mBottomSheet;
-    private BottomSheetContentController mBottomSheetContentController;
-
-    @Rule
-    public BottomSheetTestRule mBottomSheetTestRule = new BottomSheetTestRule();
-
-    @Before
-    public void setUp() throws Exception {
-        mBottomSheetTestRule.startMainActivityOnBlankPage();
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-        mObserver = mBottomSheetTestRule.getObserver();
-        mBottomSheet = mBottomSheetTestRule.getBottomSheet();
-        mBottomSheetContentController = mBottomSheetTestRule.getBottomSheetContentController();
-    }
-
-    @Test
-    @SmallTest
-    @CommandLineFlags.Add({
-            "disable-features=" + ChromeFeatureList.CHROME_HOME_DROP_ALL_BUT_FIRST_THUMBNAIL,
-            "enable-features=" + ChromeFeatureList.CHROME_HOME_DESTROY_SUGGESTIONS})
-    public void testSelectContent_DestroyContents() throws InterruptedException, TimeoutException {
-        int contentChangedCount = mObserver.mContentChangedCallbackHelper.getCallCount();
-        int openedCount = mObserver.mOpenedCallbackHelper.getCallCount();
-        int closedCount = mObserver.mClosedCallbackHelper.getCallCount();
-
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_HALF, false);
-        mObserver.mOpenedCallbackHelper.waitForCallback(openedCount++, 1);
-        mObserver.mContentChangedCallbackHelper.waitForCallback(contentChangedCount++, 1);
-        assertEquals(closedCount, mObserver.mClosedCallbackHelper.getCallCount());
-
-        mBottomSheetTestRule.selectBottomSheetContent(R.id.action_history);
-        mObserver.mContentChangedCallbackHelper.waitForCallback(contentChangedCount++, 1);
-        assertEquals(openedCount, mObserver.mOpenedCallbackHelper.getCallCount());
-        assertEquals(closedCount, mObserver.mClosedCallbackHelper.getCallCount());
-        assertTrue(mBottomSheet.getCurrentSheetContent() instanceof HistorySheetContent);
-        assertEquals(
-                R.id.action_history, mBottomSheetContentController.getSelectedItemIdForTests());
-        assertEquals(View.INVISIBLE, mBottomSheet.getDefaultToolbarView().getVisibility());
-
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-        mObserver.mClosedCallbackHelper.waitForCallback(closedCount, 1);
-        mObserver.mContentChangedCallbackHelper.waitForCallback(contentChangedCount++, 1);
-        assertEquals(openedCount, mObserver.mOpenedCallbackHelper.getCallCount());
-        assertEquals(null, mBottomSheet.getCurrentSheetContent());
-        assertEquals(0, mBottomSheetContentController.getSelectedItemIdForTests());
-        assertEquals(View.VISIBLE, mBottomSheet.getDefaultToolbarView().getVisibility());
-    }
-
-    @Test
-    @SmallTest
-    @CommandLineFlags.Add({
-            "enable-features=" + ChromeFeatureList.CHROME_HOME_DROP_ALL_BUT_FIRST_THUMBNAIL,
-            "disable-features=" + ChromeFeatureList.CHROME_HOME_DESTROY_SUGGESTIONS})
-    public void testSelectContent_DropAllButFirstThumbnail()
-            throws InterruptedException, TimeoutException {
-        int contentChangedCount = mObserver.mContentChangedCallbackHelper.getCallCount();
-        int openedCount = mObserver.mOpenedCallbackHelper.getCallCount();
-        int closedCount = mObserver.mClosedCallbackHelper.getCallCount();
-
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_HALF, false);
-        mObserver.mOpenedCallbackHelper.waitForCallback(openedCount++, 1);
-        assertEquals(closedCount, mObserver.mClosedCallbackHelper.getCallCount());
-
-        mBottomSheetTestRule.selectBottomSheetContent(R.id.action_history);
-        mObserver.mContentChangedCallbackHelper.waitForCallback(contentChangedCount++, 1);
-        assertEquals(openedCount, mObserver.mOpenedCallbackHelper.getCallCount());
-        assertEquals(closedCount, mObserver.mClosedCallbackHelper.getCallCount());
-        assertTrue(mBottomSheet.getCurrentSheetContent() instanceof HistorySheetContent);
-        assertEquals(
-                R.id.action_history, mBottomSheetContentController.getSelectedItemIdForTests());
-        assertEquals(View.INVISIBLE, mBottomSheet.getDefaultToolbarView().getVisibility());
-
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-        mObserver.mClosedCallbackHelper.waitForCallback(closedCount, 1);
-        mObserver.mContentChangedCallbackHelper.waitForCallback(contentChangedCount++, 1);
-        assertEquals(openedCount, mObserver.mOpenedCallbackHelper.getCallCount());
-        assertEquals(View.VISIBLE, mBottomSheet.getDefaultToolbarView().getVisibility());
-    }
-
-    @Test
-    @SmallTest
-    public void testShowContentAndOpenSheet_Bookmarks()
-            throws InterruptedException, TimeoutException {
-        int initialContentChangedCount = mObserver.mContentChangedCallbackHelper.getCallCount();
-        int initialOpenedCount = mObserver.mOpenedCallbackHelper.getCallCount();
-
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                BookmarkUtils.showBookmarkManager(mBottomSheetTestRule.getActivity());
-            }
-        });
-
-        mObserver.mContentChangedCallbackHelper.waitForCallback(initialContentChangedCount, 1);
-        mObserver.mOpenedCallbackHelper.waitForCallback(initialOpenedCount, 1);
-
-        assertTrue(mBottomSheet.getCurrentSheetContent() instanceof BookmarkSheetContent);
-        assertEquals(
-                R.id.action_bookmarks, mBottomSheetContentController.getSelectedItemIdForTests());
-    }
-
-    @Test
-    @SmallTest
-    public void testShowContentAndOpenSheet_Downloads()
-            throws InterruptedException, TimeoutException {
-        int initialContentChangedCount = mObserver.mContentChangedCallbackHelper.getCallCount();
-        int initialOpenedCount = mObserver.mOpenedCallbackHelper.getCallCount();
-
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                ChromeTabbedActivity activity = mBottomSheetTestRule.getActivity();
-                DownloadUtils.showDownloadManager(activity, activity.getActivityTab());
-            }
-        });
-
-        mObserver.mContentChangedCallbackHelper.waitForCallback(initialContentChangedCount, 1);
-        mObserver.mOpenedCallbackHelper.waitForCallback(initialOpenedCount, 1);
-
-        assertTrue(mBottomSheet.getCurrentSheetContent() instanceof DownloadSheetContent);
-        assertEquals(
-                R.id.action_downloads, mBottomSheetContentController.getSelectedItemIdForTests());
-    }
-
-    @Test
-    @SmallTest
-    public void testShowContentAndOpenSheet_History()
-            throws InterruptedException, TimeoutException {
-        int initialContentChangedCount = mObserver.mContentChangedCallbackHelper.getCallCount();
-        int initialOpenedCount = mObserver.mOpenedCallbackHelper.getCallCount();
-
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                ChromeTabbedActivity activity = mBottomSheetTestRule.getActivity();
-                HistoryManagerUtils.showHistoryManager(activity, activity.getActivityTab());
-            }
-        });
-
-        mObserver.mContentChangedCallbackHelper.waitForCallback(initialContentChangedCount, 1);
-        mObserver.mOpenedCallbackHelper.waitForCallback(initialOpenedCount, 1);
-
-        assertTrue(mBottomSheet.getCurrentSheetContent() instanceof HistorySheetContent);
-        assertEquals(
-                R.id.action_history, mBottomSheetContentController.getSelectedItemIdForTests());
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNavigateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNavigateTest.java
deleted file mode 100644
index 69e3f8d..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNavigateTest.java
+++ /dev/null
@@ -1,133 +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.
-
-package org.chromium.chrome.browser.widget.bottomsheet;
-
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
-import android.view.KeyEvent;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.DisabledTest;
-import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.Restriction;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.ChromeTabbedActivity;
-import org.chromium.chrome.browser.omnibox.LocationBarLayout;
-import org.chromium.chrome.browser.omnibox.UrlBar;
-import org.chromium.chrome.test.BottomSheetTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.OmniboxTestUtils;
-import org.chromium.chrome.test.util.browser.TabLoadObserver;
-import org.chromium.content.browser.test.util.Criteria;
-import org.chromium.content.browser.test.util.CriteriaHelper;
-import org.chromium.content.browser.test.util.KeyUtils;
-import org.chromium.net.test.EmbeddedTestServer;
-import org.chromium.ui.test.util.UiRestriction;
-
-/**
- * Navigate in UrlBar for BottomSheet tests.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
-public class BottomSheetNavigateTest {
-    @Rule
-    public BottomSheetTestRule mBottomSheetTestRule = new BottomSheetTestRule();
-
-    private static final String HTTP_SCHEME = "http://";
-    private static final String NEW_TAB_PAGE = "chrome-native://newtab/";
-
-    private BottomSheet mBottomSheet;
-    private ChromeTabbedActivity mActivity;
-    private EmbeddedTestServer mTestServer;
-
-    @Before
-    public void setUp() throws Exception {
-        mBottomSheetTestRule.startMainActivityOnBlankPage();
-        mBottomSheet = mBottomSheetTestRule.getBottomSheet();
-        mActivity = mBottomSheetTestRule.getActivity();
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-        mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mTestServer.stopAndDestroyServer();
-    }
-
-    /**
-     * Focuses the UrlBar to bring up the BottomSheet and types the passed text in the omnibox to
-     * trigger a navigation. You can pass a URL or a search term. This code triggers suggestions and
-     * prerendering; unless you are testing these features specifically, you should use loadUrl()
-     * which is less prone to flakyness.
-     *
-     * @param url The URL to navigate to.
-     * @param expectedTitle Title that the page is expected to have.  Shouldn't be set if the page
-     *                      load causes a redirect.
-     * @return the URL in the omnibox.
-     */
-    private String typeInOmniboxAndNavigate(final String url, final String expectedTitle)
-            throws Exception {
-        // Focus URL bar.
-        final UrlBar urlBar = (UrlBar) mActivity.findViewById(R.id.url_bar);
-        Assert.assertNotNull("urlBar is null", urlBar);
-        ThreadUtils.runOnUiThreadBlocking(() -> { urlBar.requestFocus(); });
-
-        // Verify BottomSheet is expanded.
-        CriteriaHelper.pollUiThread(
-                Criteria.equals(BottomSheet.SHEET_STATE_FULL, () -> mBottomSheet.getSheetState()));
-
-        // Navigate to the URL.
-        ThreadUtils.runOnUiThreadBlocking(() -> { urlBar.setText(url); });
-        final LocationBarLayout locationBar =
-                (LocationBarLayout) mActivity.findViewById(R.id.location_bar);
-        OmniboxTestUtils.waitForOmniboxSuggestions(locationBar);
-
-        TabLoadObserver observer =
-                new TabLoadObserver(mActivity.getActivityTab(), expectedTitle, null);
-        KeyUtils.singleKeyEventView(
-                InstrumentationRegistry.getInstrumentation(), urlBar, KeyEvent.KEYCODE_ENTER);
-        observer.assertLoaded();
-
-        // TODO(mdjones): Add polling to wait for sheet to be done animating, once it properly
-        // animates on close. crbug.com/764860.
-        Assert.assertEquals("The bottom sheet should be closed.", BottomSheet.SHEET_STATE_PEEK,
-                mBottomSheet.getSheetState());
-
-        // The URL has been set before the page notification was broadcast, so it is safe to access.
-        return urlBar.getText().toString();
-    }
-
-    /**
-     * @return the expected contents of the location bar after navigating to url.
-     */
-    private String expectedLocation(String url) {
-        Assert.assertTrue(url.startsWith(HTTP_SCHEME));
-        return url.replaceFirst(HTTP_SCHEME, "");
-    }
-
-    /**
-     * Perform navigation by typing into omnibox after bringing up BottomSheet.
-     */
-    @Test
-    @MediumTest
-    @Feature({"Navigation", "Main"})
-    //@RetryOnFailure
-    @DisabledTest(message = "crbug.com/793534")
-    public void testNavigate() throws Exception {
-        String url = mTestServer.getURL("/chrome/test/data/android/navigate/simple.html");
-        String result = typeInOmniboxAndNavigate(url, "Simple");
-        Assert.assertEquals(expectedLocation(url), result);
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java
deleted file mode 100644
index 174436b..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetNewTabControllerTest.java
+++ /dev/null
@@ -1,553 +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.
-
-package org.chromium.chrome.browser.widget.bottomsheet;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.CallbackHelper;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Restriction;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.ChromeTabbedActivity;
-import org.chromium.chrome.browser.LauncherShortcutActivity;
-import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver;
-import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
-import org.chromium.chrome.browser.tabmodel.TabModel;
-import org.chromium.chrome.browser.tabmodel.TabModelSelector;
-import org.chromium.chrome.browser.toolbar.ToolbarDataProvider;
-import org.chromium.chrome.browser.widget.FadingBackgroundView;
-import org.chromium.chrome.test.BottomSheetTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.ChromeTabUtils;
-import org.chromium.chrome.test.util.MenuUtils;
-import org.chromium.content_public.browser.LoadUrlParams;
-import org.chromium.ui.test.util.UiRestriction;
-
-import java.util.concurrent.TimeoutException;
-
-/**
- * Tests for the NTP UI displayed when Chrome Home is enabled.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
-public class BottomSheetNewTabControllerTest {
-    private FadingBackgroundView mFadingBackgroundView;
-    private BottomSheet mBottomSheet;
-    private ChromeTabbedActivity mActivity;
-    private TabModelSelector mTabModelSelector;
-    private TestTabModelObserver mNormalTabModelObserver;
-    private TestTabModelObserver mIncognitoTabModelObserver;
-    private TestTabModelSelectorObserver mTabModelSelectorObserver;
-
-    /** An observer used to detect changes in the tab model. */
-    private static class TestTabModelObserver extends EmptyTabModelObserver {
-        private final CallbackHelper mDidCloseTabCallbackHelper = new CallbackHelper();
-        private final CallbackHelper mPendingTabAddCallbackHelper = new CallbackHelper();
-
-        @Override
-        public void didCloseTab(int tabId, boolean incognito) {
-            mDidCloseTabCallbackHelper.notifyCalled();
-        }
-
-        @Override
-        public void pendingTabAdd(boolean isPendingTabAdd) {
-            mPendingTabAddCallbackHelper.notifyCalled();
-        }
-    }
-
-    private static class TestTabModelSelectorObserver extends EmptyTabModelSelectorObserver {
-        private final CallbackHelper mTabModelSelectedCallbackHelper = new CallbackHelper();
-
-        @Override
-        public void onTabModelSelected(TabModel newModel, TabModel oldModel) {
-            mTabModelSelectedCallbackHelper.notifyCalled();
-        }
-    }
-
-    @Rule
-    public BottomSheetTestRule mBottomSheetTestRule = new BottomSheetTestRule();
-
-    @Before
-    public void setUp() throws Exception {
-        mBottomSheetTestRule.startMainActivityOnBlankPage();
-        mBottomSheet = mBottomSheetTestRule.getBottomSheet();
-        mActivity = mBottomSheetTestRule.getActivity();
-        mTabModelSelector = mActivity.getTabModelSelector();
-        mFadingBackgroundView = mActivity.getFadingBackgroundView();
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-
-        mNormalTabModelObserver = new TestTabModelObserver();
-        mIncognitoTabModelObserver = new TestTabModelObserver();
-        mTabModelSelectorObserver = new TestTabModelSelectorObserver();
-        mTabModelSelector.getModel(false).addObserver(mNormalTabModelObserver);
-        mTabModelSelector.getModel(true).addObserver(mIncognitoTabModelObserver);
-        mTabModelSelector.addObserver(mTabModelSelectorObserver);
-    }
-
-    @Test
-    @SmallTest
-    public void testNTPOverTabSwitcher_Normal_FromTab() {
-        LayoutManagerChrome layoutManager = mActivity.getLayoutManager();
-        TabModel normalTabModel = mTabModelSelector.getModel(false);
-        ToolbarDataProvider toolbarDataProvider =
-                mActivity.getToolbarManager().getToolbarDataProviderForTests();
-
-        assertEquals("There should be 1 tab.", 1, mTabModelSelector.getTotalTabCount());
-        assertFalse("Overview mode should not be showing.", layoutManager.overviewVisible());
-        assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertFalse("Normal model should not be pending tab addition.",
-                normalTabModel.isPendingTabAdd());
-        assertEquals("ToolbarDataProvider has incorrect tab.", mActivity.getActivityTab(),
-                toolbarDataProvider.getTab());
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-        assertTrue("Normal model should not have INVALID_TAB_INDEX",
-                normalTabModel.index() != TabModel.INVALID_TAB_INDEX);
-
-        // Select "New tab" from the menu.
-        MenuUtils.invokeCustomMenuActionSync(
-                InstrumentationRegistry.getInstrumentation(), mActivity, R.id.new_tab_menu_id);
-
-        // The sheet should be opened at half height over the tab switcher and the tab count should
-        // remain unchanged.
-        validateState(false, BottomSheet.SHEET_STATE_FULL);
-        assertEquals("There should be 1 tab.", 1, mTabModelSelector.getTotalTabCount());
-        assertTrue("Overview mode should be showing.", layoutManager.overviewVisible());
-        assertTrue(
-                "Normal model should be pending tab addition.", normalTabModel.isPendingTabAdd());
-        assertEquals("ToolbarDataProvider has incorrect tab.", null, toolbarDataProvider.getTab());
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-        assertTrue("Normal model should have INVALID_TAB_INDEX",
-                normalTabModel.index() == TabModel.INVALID_TAB_INDEX);
-
-        // Load a URL in the bottom sheet.
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                mBottomSheet.loadUrlInNewTab(new LoadUrlParams("about:blank"));
-            }
-        });
-
-        // The sheet should now be closed and a regular tab should have been created
-        validateState(false, BottomSheet.SHEET_STATE_PEEK);
-        assertEquals("There should be 2 tabs.", 2, mTabModelSelector.getTotalTabCount());
-        assertFalse("Overview mode not should be showing.", layoutManager.overviewVisible());
-        assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertFalse("Normal model should not be pending tab addition.",
-                normalTabModel.isPendingTabAdd());
-        assertEquals("ToolbarDataProvider has incorrect tab.", mActivity.getActivityTab(),
-                toolbarDataProvider.getTab());
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-        assertTrue("Normal model should not have INVALID_TAB_INDEX",
-                normalTabModel.index() != TabModel.INVALID_TAB_INDEX);
-    }
-
-    @Test
-    @SmallTest
-    public void testNTPOverTabSwitcher_Incognito_FromTab_CloseSheet() {
-        LayoutManagerChrome layoutManager = mActivity.getLayoutManager();
-        TabModel incognitoTabModel = mTabModelSelector.getModel(true);
-        ToolbarDataProvider toolbarDataProvider =
-                mActivity.getToolbarManager().getToolbarDataProviderForTests();
-        Tab originalTab = mActivity.getActivityTab();
-
-        assertEquals("There should be 1 tab.", 1, mTabModelSelector.getTotalTabCount());
-        assertFalse("Overview mode should not be showing.", layoutManager.overviewVisible());
-        assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertFalse("Incognito model should not be pending tab addition.",
-                incognitoTabModel.isPendingTabAdd());
-        assertEquals("ToolbarDataProvider has incorrect tab.", mActivity.getActivityTab(),
-                toolbarDataProvider.getTab());
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-
-        // Select "New incognito tab" from the menu.
-        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
-                mActivity, R.id.new_incognito_tab_menu_id);
-        // The sheet should be opened at full height over the tab switcher and the tab count should
-        // remain unchanged. The incognito model should now be selected.
-        validateState(false, BottomSheet.SHEET_STATE_FULL);
-        assertEquals("There should be 1 tab.", 1, mTabModelSelector.getTotalTabCount());
-        assertTrue("Overview mode should be showing.", layoutManager.overviewVisible());
-        assertTrue("Incognito model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertTrue("Incognito model should be pending tab addition.",
-                incognitoTabModel.isPendingTabAdd());
-        assertEquals("ToolbarDataProvider has incorrect tab.", null, toolbarDataProvider.getTab());
-        assertTrue("Toolbar should be incognito.", toolbarDataProvider.isIncognito());
-
-        // Check that the previous tab is selected after the sheet is closed without a URL being
-        // loaded.
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-        assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertFalse("Incognito model should not be pending tab addition.",
-                incognitoTabModel.isPendingTabAdd());
-        assertFalse("Overview mode should not be showing.", layoutManager.overviewVisible());
-        assertEquals("Incorrect tab selected.", originalTab, mTabModelSelector.getCurrentTab());
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-    }
-
-    @Test
-    @SmallTest
-    public void testNTPOverTabSwitcher_Incognito_FromTab_LoadUrl() {
-        LayoutManagerChrome layoutManager = mActivity.getLayoutManager();
-        TabModel incognitoTabModel = mTabModelSelector.getModel(true);
-        ToolbarDataProvider toolbarDataProvider =
-                mActivity.getToolbarManager().getToolbarDataProviderForTests();
-
-        assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertFalse("Incognito model should not be pending tab addition.",
-                incognitoTabModel.isPendingTabAdd());
-
-        // Select "New incognito tab" from the menu.
-        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
-                mActivity, R.id.new_incognito_tab_menu_id);
-        validateState(false, BottomSheet.SHEET_STATE_FULL);
-        assertTrue("Incognito model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertTrue("Incognito model should be pending tab addition.",
-                incognitoTabModel.isPendingTabAdd());
-
-        // Load an URL in the incognito tab.
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                mBottomSheet.loadUrlInNewTab(new LoadUrlParams("about:blank"));
-            }
-        });
-
-        // The sheet should now be closed and an incognito tab should have been created
-        validateState(false, BottomSheet.SHEET_STATE_PEEK);
-        assertEquals("There should be 2 tabs.", 2, mTabModelSelector.getTotalTabCount());
-        assertTrue(
-                "The activity tab should be incognito.", mActivity.getActivityTab().isIncognito());
-        assertFalse("Overview mode not should be showing.", layoutManager.overviewVisible());
-        assertTrue("Incognito model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertFalse("Incognito model should not be pending tab addition.",
-                incognitoTabModel.isPendingTabAdd());
-        assertEquals("ToolbarDataProvider has incorrect tab.", mActivity.getActivityTab(),
-                toolbarDataProvider.getTab());
-        assertTrue("Toolbar should be incognito.", toolbarDataProvider.isIncognito());
-        assertTrue("Incognito model should not have INVALID_TAB_INDEX",
-                incognitoTabModel.index() != TabModel.INVALID_TAB_INDEX);
-
-        // Select "New incognito tab" from the menu again and assert state is as expected. This
-        // is designed to exercise IncognitoTabModel#index().
-        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
-                mActivity, R.id.new_incognito_tab_menu_id);
-        assertTrue("Incognito model should be pending tab addition.",
-                incognitoTabModel.isPendingTabAdd());
-        assertEquals("ToolbarDataProvider has incorrect tab.", null, toolbarDataProvider.getTab());
-        assertTrue("Toolbar should be incognito.", toolbarDataProvider.isIncognito());
-        assertTrue("Incognito model should have INVALID_TAB_INDEX",
-                incognitoTabModel.index() == TabModel.INVALID_TAB_INDEX);
-    }
-
-    @Test
-    @SmallTest
-    public void testNTPOverTabSwitcher_Incognito_FromTabSwitcher() {
-        final LayoutManagerChrome layoutManager = mActivity.getLayoutManager();
-        ToolbarDataProvider toolbarDataProvider =
-                mActivity.getToolbarManager().getToolbarDataProviderForTests();
-
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                layoutManager.showOverview(false);
-            }
-        });
-
-        assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertTrue("Overview mode should be showing.", layoutManager.overviewVisible());
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-
-        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
-                mActivity, R.id.new_incognito_tab_menu_id);
-
-        validateState(false, BottomSheet.SHEET_STATE_FULL);
-        assertTrue("Incognito model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertTrue("Overview mode should be showing.", layoutManager.overviewVisible());
-        assertTrue("Toolbar should be incognito.", toolbarDataProvider.isIncognito());
-
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-        assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertTrue("Overview mode should be showing.", layoutManager.overviewVisible());
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-    }
-
-    @Test
-    @SmallTest
-    public void testNTPOverTabSwitcher_Normal_FromTabSwitcher() {
-        final LayoutManagerChrome layoutManager = mActivity.getLayoutManager();
-        ToolbarDataProvider toolbarDataProvider =
-                mActivity.getToolbarManager().getToolbarDataProviderForTests();
-
-        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
-                mActivity, R.id.new_incognito_tab_menu_id);
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                mBottomSheet.loadUrlInNewTab(new LoadUrlParams("about:blank"));
-                layoutManager.showOverview(false);
-                mBottomSheet.endAnimations();
-            }
-        });
-
-        assertTrue("Incognito model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertTrue("Overview mode should be showing.", layoutManager.overviewVisible());
-        assertTrue("Toolbar should be incognito.", toolbarDataProvider.isIncognito());
-
-        MenuUtils.invokeCustomMenuActionSync(
-                InstrumentationRegistry.getInstrumentation(), mActivity, R.id.new_tab_menu_id);
-
-        validateState(false, BottomSheet.SHEET_STATE_FULL);
-        assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertTrue("Overview mode should be showing.", layoutManager.overviewVisible());
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-        assertTrue("Incognito model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertTrue("Overview mode should be showing.", layoutManager.overviewVisible());
-        assertTrue("Toolbar should be incognito.", toolbarDataProvider.isIncognito());
-    }
-
-    @Test
-    @SmallTest
-    public void testNTPOverTabSwitcher_NoTabs() throws InterruptedException {
-        // Close all tabs.
-        ChromeTabUtils.closeAllTabs(InstrumentationRegistry.getInstrumentation(), mActivity);
-        assertEquals(0, mTabModelSelector.getTotalTabCount());
-
-        // Select "New tab" from the menu.
-        MenuUtils.invokeCustomMenuActionSync(
-                InstrumentationRegistry.getInstrumentation(), mActivity, R.id.new_tab_menu_id);
-
-        // The sheet should be opened at full height.
-        validateState(false, BottomSheet.SHEET_STATE_FULL);
-        assertEquals(0, mTabModelSelector.getTotalTabCount());
-    }
-
-    @Test
-    @SmallTest
-    public void testNTPOverTabSwitcher_SwitchModels() {
-        TabModel normalTabModel = mTabModelSelector.getModel(false);
-        TabModel incognitoTabModel = mTabModelSelector.getModel(true);
-        ToolbarDataProvider toolbarDataProvider =
-                mActivity.getToolbarManager().getToolbarDataProviderForTests();
-
-        assertFalse("Incognito model should not be pending tab addition.",
-                incognitoTabModel.isPendingTabAdd());
-        assertFalse("Normal model should not be pending tab addition.",
-                normalTabModel.isPendingTabAdd());
-        assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-
-        // Select "New incognito tab" from the menu.
-        MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(),
-                mActivity, R.id.new_incognito_tab_menu_id);
-
-        assertTrue("Incognito model should be pending tab addition.",
-                incognitoTabModel.isPendingTabAdd());
-        assertFalse("Normal model should not be pending tab addition.",
-                normalTabModel.isPendingTabAdd());
-        assertTrue("Incognito model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertTrue("Toolbar should be incognito.", toolbarDataProvider.isIncognito());
-
-        // Select "New tab" from the menu.
-        MenuUtils.invokeCustomMenuActionSync(
-                InstrumentationRegistry.getInstrumentation(), mActivity, R.id.new_tab_menu_id);
-
-        assertFalse("Incognito model should not be pending tab addition.",
-                incognitoTabModel.isPendingTabAdd());
-        assertTrue(
-                "Normal model should be pending tab addition.", normalTabModel.isPendingTabAdd());
-        assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-    }
-
-    @Test
-    @SmallTest
-    public void testNTPOverTabSwitcher_LauncherShortcuts_NormalToIncognito()
-            throws InterruptedException, TimeoutException {
-        LayoutManagerChrome layoutManager = mActivity.getLayoutManager();
-        TabModel normalTabModel = mTabModelSelector.getModel(false);
-        TabModel incognitoTabModel = mTabModelSelector.getModel(true);
-        ToolbarDataProvider toolbarDataProvider =
-                mActivity.getToolbarManager().getToolbarDataProviderForTests();
-
-        assertFalse("Overview mode should not be showing.", layoutManager.overviewVisible());
-        assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertFalse("Normal model should not be pending tab addition.",
-                normalTabModel.isPendingTabAdd());
-        assertEquals("ToolbarDataProvider has incorrect tab.", mActivity.getActivityTab(),
-                toolbarDataProvider.getTab());
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-
-        // Create a new tab using a launcher shortcut intent.
-        int currentPendingTabCalls =
-                mIncognitoTabModelObserver.mPendingTabAddCallbackHelper.getCallCount();
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                mActivity.startActivity(LauncherShortcutActivity.getChromeLauncherActivityIntent(
-                        mActivity, LauncherShortcutActivity.ACTION_OPEN_NEW_TAB));
-            }
-        });
-        mNormalTabModelObserver.mPendingTabAddCallbackHelper.waitForCallback(
-                currentPendingTabCalls);
-
-        // The sheet should be opened at half height over the tab switcher.
-        validateState(false, BottomSheet.SHEET_STATE_FULL);
-        assertTrue("Overview mode should be showing.", layoutManager.overviewVisible());
-        assertTrue(
-                "Normal model should be pending tab addition.", normalTabModel.isPendingTabAdd());
-        assertEquals("ToolbarDataProvider has incorrect tab.", null, toolbarDataProvider.getTab());
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-
-        // Create a new incognito tab using an incognito launcher shortcut intent.
-        int currentIncognitoPendingTabCalls =
-                mIncognitoTabModelObserver.mPendingTabAddCallbackHelper.getCallCount();
-        currentPendingTabCalls =
-                mNormalTabModelObserver.mPendingTabAddCallbackHelper.getCallCount();
-        int currentTabModelSelectedCalls =
-                mTabModelSelectorObserver.mTabModelSelectedCallbackHelper.getCallCount();
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                mActivity.startActivity(LauncherShortcutActivity.getChromeLauncherActivityIntent(
-                        mActivity, LauncherShortcutActivity.ACTION_OPEN_NEW_INCOGNITO_TAB));
-            }
-        });
-
-        mIncognitoTabModelObserver.mPendingTabAddCallbackHelper.waitForCallback(
-                currentIncognitoPendingTabCalls, 1);
-        mNormalTabModelObserver.mPendingTabAddCallbackHelper.waitForCallback(
-                currentPendingTabCalls, 1);
-        mTabModelSelectorObserver.mTabModelSelectedCallbackHelper.waitForCallback(
-                currentTabModelSelectedCalls);
-
-        // Check that the state is correct.
-        validateState(false, BottomSheet.SHEET_STATE_FULL);
-        assertTrue("Overview mode should be showing.", layoutManager.overviewVisible());
-        assertTrue("Incognito model should be pending tab addition.",
-                incognitoTabModel.isPendingTabAdd());
-        assertFalse("Normal model should not be pending tab addition.",
-                normalTabModel.isPendingTabAdd());
-        assertTrue("Incognito model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertTrue("Toolbar should be incognito.", toolbarDataProvider.isIncognito());
-    }
-
-    @Test
-    @SmallTest
-    public void testNTPOverTabSwitcher_LauncherShortcuts_IncognitoToNormal()
-            throws InterruptedException, TimeoutException {
-        LayoutManagerChrome layoutManager = mActivity.getLayoutManager();
-        TabModel normalTabModel = mTabModelSelector.getModel(false);
-        TabModel incognitoTabModel = mTabModelSelector.getModel(true);
-        ToolbarDataProvider toolbarDataProvider =
-                mActivity.getToolbarManager().getToolbarDataProviderForTests();
-
-        // Create a new tab using an incognito launcher shortcut intent.
-        int currentIncognitoPendingTabCalls =
-                mIncognitoTabModelObserver.mPendingTabAddCallbackHelper.getCallCount();
-        int currentTabModelSelectedCalls =
-                mTabModelSelectorObserver.mTabModelSelectedCallbackHelper.getCallCount();
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                mActivity.startActivity(LauncherShortcutActivity.getChromeLauncherActivityIntent(
-                        mActivity, LauncherShortcutActivity.ACTION_OPEN_NEW_INCOGNITO_TAB));
-            }
-        });
-
-        mIncognitoTabModelObserver.mPendingTabAddCallbackHelper.waitForCallback(
-                currentIncognitoPendingTabCalls, 1);
-        mTabModelSelectorObserver.mTabModelSelectedCallbackHelper.waitForCallback(
-                currentTabModelSelectedCalls);
-
-        // Check that the state is correct.
-        validateState(false, BottomSheet.SHEET_STATE_FULL);
-        assertTrue("Overview mode should be showing.", layoutManager.overviewVisible());
-        assertTrue("Incognito model should be pending tab addition.",
-                incognitoTabModel.isPendingTabAdd());
-        assertFalse("Normal model should not be pending tab addition.",
-                normalTabModel.isPendingTabAdd());
-        assertTrue("Incognito model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertTrue("Toolbar should be incognito.", toolbarDataProvider.isIncognito());
-
-        // Create a new tab to ensure that there are no crashes when destroying the incognito
-        // profile.
-        currentIncognitoPendingTabCalls =
-                mIncognitoTabModelObserver.mPendingTabAddCallbackHelper.getCallCount();
-        int currentPendingTabCalls =
-                mNormalTabModelObserver.mPendingTabAddCallbackHelper.getCallCount();
-        currentTabModelSelectedCalls =
-                mTabModelSelectorObserver.mTabModelSelectedCallbackHelper.getCallCount();
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                mActivity.startActivity(LauncherShortcutActivity.getChromeLauncherActivityIntent(
-                        mActivity, LauncherShortcutActivity.ACTION_OPEN_NEW_TAB));
-            }
-        });
-
-        mIncognitoTabModelObserver.mPendingTabAddCallbackHelper.waitForCallback(
-                currentIncognitoPendingTabCalls, 1);
-        mNormalTabModelObserver.mPendingTabAddCallbackHelper.waitForCallback(
-                currentPendingTabCalls, 1);
-        mTabModelSelectorObserver.mTabModelSelectedCallbackHelper.waitForCallback(
-                currentTabModelSelectedCalls);
-        validateState(false, BottomSheet.SHEET_STATE_FULL);
-        assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected());
-        assertTrue(
-                "Normal model should be pending tab addition.", normalTabModel.isPendingTabAdd());
-        assertFalse("Incognito model should not be pending tab addition.",
-                incognitoTabModel.isPendingTabAdd());
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-
-        // Typically the BottomSheetNewTabController would select the previous model on close. In
-        // this case the previous model is incognito because the incognito NTP was showing when
-        // the regular new tab was created, but the incognito model has no tabs. Close the bottom
-        // sheet and ensure the normal model is still selected.
-        currentPendingTabCalls =
-                mNormalTabModelObserver.mPendingTabAddCallbackHelper.getCallCount();
-        mBottomSheetTestRule.setSheetState(BottomSheet.SHEET_STATE_PEEK, false);
-        assertFalse("Normal model should not be pending tab addition.",
-                normalTabModel.isPendingTabAdd());
-        mNormalTabModelObserver.mPendingTabAddCallbackHelper.waitForCallback(
-                currentPendingTabCalls, 1);
-        assertFalse("Toolbar should be normal.", toolbarDataProvider.isIncognito());
-        assertFalse("Normal model should be selected.", mTabModelSelector.isIncognitoSelected());
-    }
-
-    private void validateState(boolean chromeHomeTabPageSelected, int expectedEndState) {
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                mBottomSheet.endAnimations();
-            }
-        });
-
-        assertEquals("Sheet state incorrect", expectedEndState, mBottomSheet.getSheetState());
-
-        if (chromeHomeTabPageSelected) {
-            assertFalse(mFadingBackgroundView.isEnabled());
-            assertEquals(0f, mFadingBackgroundView.getAlpha(), 0);
-        } else {
-            assertTrue(mFadingBackgroundView.isEnabled());
-        }
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java
index 7ae9384..fb278fbd 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetObserverTest.java
@@ -15,6 +15,7 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.bookmarks.BookmarkSheetContent;
@@ -29,6 +30,7 @@
 import java.util.concurrent.TimeoutException;
 
 /** This class tests the functionality of the {@link BottomSheetObserver}. */
+@DisabledTest(message = "https://crbug.com/805160")
 @RunWith(ChromeJUnit4ClassRunner.class)
 @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
 public class BottomSheetObserverTest {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
index 27c5c95..26b12c8 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
@@ -33,6 +33,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestRule;
@@ -1015,6 +1016,7 @@
         assertEquals(0, preferenceManager.getNewTabPageSigninPromoSuppressionPeriodStart());
     }
 
+    @Ignore // Disabled for new Chrome Home, see: https://crbug.com/805160
     @Test
     @Feature({"Ntp"})
     @EnableFeatures(ChromeFeatureList.CHROME_HOME)
@@ -1182,6 +1184,7 @@
                 mAdapter.getFirstPositionForType(ItemViewType.ALL_DISMISSED));
     }
 
+    @Ignore // Disabled for new Chrome Home, see: https://crbug.com/805160
     @Test
     @Feature({"Ntp"})
     @EnableFeatures(ChromeFeatureList.CHROME_HOME)
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java
index 3d4564a..6570717c 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SectionListTest.java
@@ -38,7 +38,6 @@
 import org.chromium.base.Callback;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.DisableHistogramsRule;
 import org.chromium.chrome.browser.ntp.snippets.CategoryInt;
 import org.chromium.chrome.browser.ntp.snippets.CategoryStatus;
@@ -50,9 +49,7 @@
 import org.chromium.chrome.browser.suggestions.SuggestionsEventReporter;
 import org.chromium.chrome.browser.suggestions.SuggestionsRanker;
 import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate;
-import org.chromium.chrome.browser.util.FeatureUtilities;
 import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
 import org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.CategoryInfoBuilder;
 import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource;
 import org.chromium.net.NetworkChangeNotifier;
@@ -65,7 +62,6 @@
  */
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
-@EnableFeatures(ChromeFeatureList.CHROME_HOME)
 public class SectionListTest {
     @Rule
     public DisableHistogramsRule mDisableHistogramsRule = new DisableHistogramsRule();
@@ -87,8 +83,6 @@
 
     @Before
     public void setUp() {
-        FeatureUtilities.resetChromeHomeEnabledForTests();
-
         // Ensure that NetworkChangeNotifier is initialized.
         if (!NetworkChangeNotifier.isInitialized()) {
             NetworkChangeNotifier.init();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java
index af72433..302f7a1 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java
@@ -55,8 +55,6 @@
 import org.chromium.chrome.browser.suggestions.SuggestionsNavigationDelegate;
 import org.chromium.chrome.browser.suggestions.SuggestionsRanker;
 import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate;
-import org.chromium.chrome.browser.util.FeatureUtilities;
-import org.chromium.chrome.test.util.browser.ChromeHome;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.chrome.test.util.browser.offlinepages.FakeOfflinePageBridge;
 import org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.CategoryInfoBuilder;
@@ -76,8 +74,6 @@
  */
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
-// TODO(https://crbug.com/673092): Run as much as possible parameterized on ChromeHome state.
-@ChromeHome.Enable
 public class SuggestionsSectionTest {
     @Rule
     public DisableHistogramsRule mDisableHistogramsRule = new DisableHistogramsRule();
@@ -85,9 +81,6 @@
     @Rule
     public TestRule mFeatureProcessor = new Features.JUnitProcessor();
 
-    @Rule
-    public TestRule mChromeHomeRule = new ChromeHome.Processor();
-
     private static final int TEST_CATEGORY_ID = 42;
 
     private static final int REMOTE_TEST_CATEGORY =
@@ -112,7 +105,6 @@
     public void setUp() {
         RecordUserAction.setDisabledForTests(true);
         MockitoAnnotations.initMocks(this);
-        FeatureUtilities.resetChromeHomeEnabledForTests();
 
         mBridge = new FakeOfflinePageBridge();
 
@@ -130,12 +122,10 @@
     @After
     public void tearDown() {
         RecordUserAction.setDisabledForTests(false);
-        FeatureUtilities.resetChromeHomeEnabledForTests();
     }
 
     @Test
     @Feature({"Ntp"})
-    @ChromeHome.Disable // Sections can't be dismissed in ChromeHome
     public void testDismissSibling() {
         List<SnippetArticle> snippets = createDummySuggestions(3, TEST_CATEGORY_ID);
         SuggestionsSection section = createSectionWithFetchAction(true);
@@ -162,7 +152,6 @@
 
     @Test
     @Feature({"Ntp"})
-    @ChromeHome.Disable // Sections can't be dismissed in ChromeHome
     public void testGetDismissalGroupWithoutHeader() {
         SuggestionsSection section = createSectionWithFetchAction(true);
         section.setHeaderVisibility(false);
@@ -176,7 +165,6 @@
 
     @Test
     @Feature({"Ntp"})
-    @ChromeHome.Disable // Sections can't be dismissed in ChromeHome
     public void testGetDismissalGroupWithoutAction() {
         SuggestionsSection section = createSectionWithFetchAction(false);
 
@@ -186,7 +174,6 @@
 
     @Test
     @Feature({"Ntp"})
-    @ChromeHome.Disable // Sections can't be dismissed in ChromeHome
     public void testGetDismissalGroupActionAndHeader() {
         SuggestionsSection section = createSectionWithFetchAction(false);
         section.setHeaderVisibility(false);
@@ -197,7 +184,6 @@
 
     @Test
     @Feature({"Ntp"})
-    @ChromeHome.Disable // Assumes status card on empty state, irrelevant in ChromeHome.
     public void testAddSuggestionsNotification() {
         final int suggestionCount = 5;
         List<SnippetArticle> snippets = createDummySuggestions(suggestionCount,
@@ -220,7 +206,6 @@
 
     @Test
     @Feature({"Ntp"})
-    @ChromeHome.Disable // Assumes status card on empty state, irrelevant in ChromeHome.
     public void testSetStatusNotification() {
         final int suggestionCount = 5;
         List<SnippetArticle> snippets = createDummySuggestions(suggestionCount,
@@ -261,7 +246,6 @@
 
     @Test
     @Feature({"Ntp"})
-    @ChromeHome.Disable // Assumes status card on empty state, irrelevant in ChromeHome.
     public void testRemoveSuggestionNotification() {
         final int suggestionCount = 2;
         List<SnippetArticle> snippets = createDummySuggestions(suggestionCount,
@@ -287,7 +271,6 @@
 
     @Test
     @Feature({"Ntp"})
-    @ChromeHome.Disable // Assumes status card on empty state, irrelevant in ChromeHome.
     public void testRemoveSuggestionNotificationWithButton() {
         final int suggestionCount = 2;
         List<SnippetArticle> snippets = createDummySuggestions(suggestionCount,
@@ -319,7 +302,6 @@
 
     @Test
     @Feature({"Ntp"})
-    @ChromeHome.Disable // Sections can't be dismissed in ChromeHome
     public void testDismissSection() {
         SuggestionsSection section = createSectionWithFetchAction(false);
         section.setStatus(CategoryStatus.AVAILABLE);
@@ -887,7 +869,6 @@
 
     @Test
     @Feature({"Ntp"})
-    @ChromeHome.Disable // Assumes paired status card and action item, irrelevant in ChromeHome.
     public void testGetItemDismissalGroupWithActionItem() {
         SuggestionsSection section = createSectionWithFetchAction(true);
         assertThat(section.getItemDismissalGroup(1).size(), is(2));
@@ -896,7 +877,6 @@
 
     @Test
     @Feature({"Ntp"})
-    @ChromeHome.Disable // Sections can't be dismissed in ChromeHome
     public void testGetItemDismissalGroupWithoutActionItem() {
         SuggestionsSection section = createSectionWithFetchAction(false);
         assertThat(section.getItemDismissalGroup(1).size(), is(1));
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/TileGroupUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/TileGroupUnitTest.java
index daa4d4f..a450661a 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/TileGroupUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/TileGroupUnitTest.java
@@ -49,7 +49,6 @@
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
 import org.chromium.chrome.browser.suggestions.TileView.Style;
 import org.chromium.chrome.browser.widget.displaystyle.UiConfig;
-import org.chromium.chrome.test.util.browser.ChromeHome;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.chrome.test.util.browser.suggestions.FakeMostVisitedSites;
@@ -63,8 +62,7 @@
  */
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
-@DisableFeatures({ChromeFeatureList.NTP_MODERN_LAYOUT})
-@ChromeHome.Enable
+@DisableFeatures({ChromeFeatureList.NTP_MODERN_LAYOUT, ChromeFeatureList.CHROME_MODERN_DESIGN})
 public class TileGroupUnitTest {
     private static final int MAX_TILES_TO_FETCH = 4;
     private static final int TILE_TITLE_LINES = 1;
@@ -72,8 +70,6 @@
 
     @Rule
     public TestRule mFeaturesProcessor = new Features.JUnitProcessor();
-    @Rule
-    public TestRule mChromeHomeProcessor = new ChromeHome.Processor();
 
     @Mock
     private TileGroup.Observer mTileGroupObserver;
@@ -84,10 +80,6 @@
     private FakeImageFetcher mImageFetcher;
     private TileRenderer mTileRenderer;
 
-    public TileGroupUnitTest() {
-        // The ChromeHome.Processor rule needs an available context when it is applied.
-    }
-
     @Before
     public void setUp() {
         CardsVariationParameters.setTestVariationParams(new HashMap<>());
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index bc47be8..d4e058ab 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -1046,15 +1046,22 @@
       </if>
 
       <!-- Upgrade recovery bubble -->
-      <message name="IDS_RUN_RECOVERY" desc="Text for the button the user clicks to recover chromium and its updater.">
-        Update Chromium
-      </message>
-      <message name="IDS_DECLINE_RECOVERY" desc="Text for the button the user clicks to decline recovery request.">
-        No, thanks
-      </message>
-      <message name="IDS_RECOVERY_BUBBLE_TITLE" desc="Text for the title of the chrome recovery bubble view.">
-        Chromium is out of date
-      </message>
+      <if expr="use_titlecase">
+        <message name="IDS_RUN_RECOVERY" desc="In Title Case: Text for the button the user clicks to recover chromium and its updater.">
+          Update Chromium
+        </message>
+        <message name="IDS_RECOVERY_BUBBLE_TITLE" desc="In Title Case: Text for the title of the chrome recovery bubble view.">
+          Chromium is Out of Date
+        </message>
+      </if>
+      <if expr="not use_titlecase">
+        <message name="IDS_RUN_RECOVERY" desc="Text for the button the user clicks to recover chromium and its updater.">
+          Update Chromium
+        </message>
+        <message name="IDS_RECOVERY_BUBBLE_TITLE" desc="Text for the title of the chrome recovery bubble view.">
+          Chromium is out of date
+        </message>
+      </if>
       <message name="IDS_RECOVERY_BUBBLE_TEXT" desc="Text for the chrome recovery bubble view full description.">
         Important security improvements and new features are available in the latest version.
       </message>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index a308e38..6aca2c0 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -8208,6 +8208,18 @@
         Created new window in existing browser session.
       </message>
 
+      <!-- Upgrade recovery bubble -->
+      <if expr="use_titlecase">
+        <message name="IDS_DECLINE_RECOVERY" desc="In Title Case: Text for the button the user clicks to decline recovery request.">
+          No, Thanks
+        </message>
+      </if>
+      <if expr="not use_titlecase">
+        <message name="IDS_DECLINE_RECOVERY" desc="Text for the button the user clicks to decline recovery request.">
+          No, thanks
+        </message>
+      </if>
+
       <!-- Sync strings -->
 
       <!-- Shared between all the plaforms -->
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index e0f4a5a8..1c473589 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -1063,15 +1063,22 @@
       </if>
 
       <!-- Upgrade recovery bubble -->
-      <message name="IDS_RUN_RECOVERY" desc="Text for the button the user clicks to recover Chrome and its updater.">
-        Update Chrome
-      </message>
-      <message name="IDS_DECLINE_RECOVERY" desc="Text for the button the user clicks to decline recovery request.">
-        No, thanks
-      </message>
-      <message name="IDS_RECOVERY_BUBBLE_TITLE" desc="Text for the title of the chrome recovery bubble view.">
-        Chrome is out of date
-      </message>
+      <if expr="use_titlecase">
+        <message name="IDS_RUN_RECOVERY" desc="In Title Case: Text for the button the user clicks to recover Chrome and its updater.">
+          Update Chrome
+        </message>
+        <message name="IDS_RECOVERY_BUBBLE_TITLE" desc="In Title Case: Text for the title of the chrome recovery bubble view.">
+          Chrome is Out of Date
+        </message>
+      </if>
+      <if expr="not use_titlecase">
+        <message name="IDS_RUN_RECOVERY" desc="Text for the button the user clicks to recover Chrome and its updater.">
+          Update Chrome
+        </message>
+        <message name="IDS_RECOVERY_BUBBLE_TITLE" desc="Text for the title of the chrome recovery bubble view.">
+          Chrome is out of date
+        </message>
+      </if>
       <message name="IDS_RECOVERY_BUBBLE_TEXT" desc="Text for the chrome recovery bubble view full description.">
         Important security improvements and new features are available in the latest version.
       </message>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 0643b2d..17517d9 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -2217,8 +2217,8 @@
   </message>
 
   <!-- Reset Settings Page -->
-  <message name="IDS_SETTINGS_RESET" desc="Name of the settings page where settings may be reset.">
-    Reset
+  <message name="IDS_SETTINGS_RESET" desc="Title for an item in the 'Reset and clean up' section of Chrome Settings. If the user clicks this option, browser settings will be returned to their default values, after a confirmation by the user." meaning="Chrome Cleanup feature. Try to use the same translation for 'Reset' in 'Reset and cleanup' string.">
+    Reset settings
   </message>
   <message name="IDS_SETTINGS_RESET_AUTOMATED_DIALOG_TITLE" desc="The title of the dialog informing the user that automated resetting of some settings occurred.">
     Some settings were reset
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index bebaee3b..2177304c 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -329,6 +329,8 @@
     "conflicts/module_list_manager_win.h",
     "conflicts/msi_util_win.cc",
     "conflicts/msi_util_win.h",
+    "conflicts/problematic_programs_updater_win.cc",
+    "conflicts/problematic_programs_updater_win.h",
     "conflicts/third_party_metrics_recorder_win.cc",
     "conflicts/third_party_metrics_recorder_win.h",
     "consent_auditor/consent_auditor_factory.cc",
@@ -857,6 +859,8 @@
     "notifications/persistent_notification_handler.h",
     "notifications/platform_notification_service_impl.cc",
     "notifications/platform_notification_service_impl.h",
+    "notifications/system_notification_helper.cc",
+    "notifications/system_notification_helper.h",
     "ntp_snippets/bookmark_last_visit_updater.cc",
     "ntp_snippets/bookmark_last_visit_updater.h",
     "ntp_snippets/content_suggestions_notifier_service_factory.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 9690047..0b07998 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1874,9 +1874,9 @@
      MULTI_VALUE_TYPE(kReaderModeHeuristicsChoices)},
 #endif  // OS_ANDROID
 #if defined(OS_ANDROID)
-    {"enable-chrome-home", flag_descriptions::kChromeHomeName,
-     flag_descriptions::kChromeHomeDescription, kOsAndroid,
-     FEATURE_VALUE_TYPE(chrome::android::kChromeHomeFeature)},
+    {"enable-chrome-duplex", flag_descriptions::kChromeDuplexName,
+     flag_descriptions::kChromeDuplexDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(chrome::android::kChromeDuplexFeature)},
     {"enable-chrome-home-bottom-nav-labels",
      flag_descriptions::kChromeHomeBottomNavLabelsName,
      flag_descriptions::kChromeHomeBottomNavLabelsDescription, kOsAndroid,
@@ -2072,6 +2072,9 @@
      flag_descriptions::kHarfbuzzRendertextDescription, kOsMac,
      SINGLE_VALUE_TYPE(switches::kEnableHarfBuzzRenderText)},
 #endif  // OS_MACOSX
+    {"allow-previews", flag_descriptions::kPreviewsAllowedName,
+     flag_descriptions::kPreviewsAllowedDescription, kOsAll,
+     FEATURE_VALUE_TYPE(previews::features::kPreviews)},
     {"data-saver-server-previews",
      flag_descriptions::kDataSaverServerPreviewsName,
      flag_descriptions::kDataSaverServerPreviewsDescription, kOsAll,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index a2408e6..1eceeb3 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -62,7 +62,7 @@
     &kCCTExternalLinkHandling,
     &kCCTPostMessageAPI,
     &kCCTRedirectPreconnect,
-    &kChromeHomeFeature,
+    &kChromeDuplexFeature,
     &kChromeHomeBottomNavLabels,
     &kChromeHomeClearUrlOnOpen,
     &kChromeHomeDestroySuggestions,
@@ -186,8 +186,8 @@
 const base::Feature kCCTRedirectPreconnect{"CCTRedirectPreconnect",
                                            base::FEATURE_ENABLED_BY_DEFAULT};
 
-const base::Feature kChromeHomeFeature{"ChromeHome",
-                                       base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kChromeDuplexFeature{"ChromeDuplex",
+                                         base::FEATURE_DISABLED_BY_DEFAULT};
 
 const base::Feature kChromeHomeBottomNavLabels{
     "ChromeHomeBottomNavLabels", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h
index 3b60c2a..b91bcbc 100644
--- a/chrome/browser/android/chrome_feature_list.h
+++ b/chrome/browser/android/chrome_feature_list.h
@@ -22,7 +22,7 @@
 extern const base::Feature kCCTExternalLinkHandling;
 extern const base::Feature kCCTPostMessageAPI;
 extern const base::Feature kCCTRedirectPreconnect;
-extern const base::Feature kChromeHomeFeature;
+extern const base::Feature kChromeDuplexFeature;
 extern const base::Feature kChromeHomeBottomNavLabels;
 extern const base::Feature kChromeHomeClearUrlOnOpen;
 extern const base::Feature kChromeHomeDestroySuggestions;
diff --git a/chrome/browser/android/metrics/uma_session_stats.cc b/chrome/browser/android/metrics/uma_session_stats.cc
index ab9f95ed..74e0596b 100644
--- a/chrome/browser/android/metrics/uma_session_stats.cc
+++ b/chrome/browser/android/metrics/uma_session_stats.cc
@@ -21,7 +21,7 @@
 #include "components/metrics_services_manager/metrics_services_manager.h"
 #include "components/prefs/pref_service.h"
 #include "components/ukm/ukm_service.h"
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 #include "components/variations/variations_associated_data.h"
 #include "content/public/browser/browser_thread.h"
 #include "jni/UmaSessionStats_jni.h"
@@ -109,9 +109,7 @@
     JNIEnv*,
     const JavaParamRef<jclass>&,
     jboolean consent) {
-  UpdateMetricsPrefsOnPermissionChange(g_browser_process->local_state(),
-                                       g_browser_process->metrics_service(),
-                                       consent);
+  UpdateMetricsPrefsOnPermissionChange(consent);
 
   // This function ensures a consent file in the data directory is either
   // created, or deleted, depending on consent. Starting up metrics services
@@ -166,9 +164,9 @@
   group_name_hashes.reserve(experiment_ids.size());
 
   variations::ActiveGroupId active_group;
-  active_group.name = metrics::HashName(trial_name_utf8);
+  active_group.name = variations::HashName(trial_name_utf8);
   for (int experiment_id : experiment_ids) {
-    active_group.group = metrics::HashName(base::IntToString(experiment_id));
+    active_group.group = variations::HashName(base::IntToString(experiment_id));
     // Since external experiments are not based on Chrome's low entropy source,
     // they are only sent to Google web properties for signed in users to make
     // sure that this couldn't be used to identify a user that's not signed in.
diff --git a/chrome/browser/android/resource_id.h b/chrome/browser/android/resource_id.h
index 08cec7c..7483edb 100644
--- a/chrome/browser/android/resource_id.h
+++ b/chrome/browser/android/resource_id.h
@@ -26,6 +26,8 @@
 // Android only infobars.
 DECLARE_RESOURCE_ID(IDR_ANDROID_INFOBAR_ACCESSIBILITY_EVENTS,
                     R.drawable.infobar_accessibility_events)
+DECLARE_RESOURCE_ID(IDR_ANDROID_INFOBAR_CLIPBOARD,
+                    R.drawable.infobar_clipboard)
 DECLARE_RESOURCE_ID(IDR_ANDROID_INFOBAR_FOLDER, R.drawable.ic_folder_blue_24dp)
 DECLARE_RESOURCE_ID(IDR_ANDROID_INFOBAR_FROZEN_TAB, R.drawable.infobar_restore)
 DECLARE_RESOURCE_ID(IDR_ANDROID_INFOBAR_GEOLOCATION,
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc
index 4624eda..ad20e544 100644
--- a/chrome/browser/android/vr_shell/vr_shell_gl.cc
+++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -1086,11 +1086,16 @@
     acquired_frame_.Unbind();
   }
 
-  // GVR submit needs the saved head pose that was used for JS rendering. Don't
-  // use render_info_primary_.head_pose here, that may have been overwritten by
-  // OnVSync's controller handling.
-  gfx::Transform webvr_head_pose =
-      webvr_head_pose_[frame_index % kPoseRingBufferSize];
+  // GVR submit needs the exact head pose that was used for rendering.
+  gfx::Transform submit_head_pose;
+  if (ShouldDrawWebVr()) {
+    // Don't use render_info_primary_.head_pose here, that may have been
+    // overwritten by OnVSync's controller handling. We need the pose that was
+    // sent to JS.
+    submit_head_pose = webvr_head_pose_[frame_index % kPoseRingBufferSize];
+  } else {
+    submit_head_pose = render_info_primary_.head_pose;
+  }
   if (ShouldDrawWebVr() && surfaceless_rendering_ && !webvr_use_gpu_fence_) {
     // Continue with submit once a GL fence signals that current drawing
     // operations have completed.
@@ -1101,10 +1106,10 @@
     task_runner_->PostTask(
         FROM_HERE,
         base::BindOnce(webvr_delayed_frame_submit_.callback(), frame_index,
-                       webvr_head_pose, base::Passed(&fence)));
+                       submit_head_pose, base::Passed(&fence)));
   } else {
     // Continue with submit immediately.
-    DrawFrameSubmitNow(frame_index, webvr_head_pose);
+    DrawFrameSubmitNow(frame_index, submit_head_pose);
   }
 }
 
diff --git a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
index cd4bfbb5..f73132e 100644
--- a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
@@ -1186,63 +1186,6 @@
   ASSERT_EQ(20, menu_observer.params().y);
 }
 
-// Tests whether <webview> context menu sees <webview> local coordinates in its
-// RenderViewContextMenu params, when it is subject to CSS transforms.
-//
-// This test doesn't makes sense in --use-cross-process-frames-for-guests, since
-// it tests that events forwarded from the embedder are properly transformed,
-// and in oopif-mode the events are sent directly to the child process without
-// the forwarding code path (relying on surface-based hittesting).
-
-// Flaky.  http://crbug.com/613258
-IN_PROC_BROWSER_TEST_F(WebViewContextMenuInteractiveTest,
-                       DISABLED_ContextMenuParamsAfterCSSTransforms) {
-  LoadAndLaunchPlatformApp("web_view/context_menus/coordinates_with_transforms",
-                           "Launched");
-
-  if (!embedder_web_contents_)
-    embedder_web_contents_ = GetFirstAppWindowWebContents();
-  EXPECT_TRUE(embedder_web_contents());
-
-  if (!guest_web_contents_)
-    guest_web_contents_ = GetGuestViewManager()->WaitForSingleGuestCreated();
-  EXPECT_TRUE(guest_web_contents());
-
-  // We will send the input event to the embedder rather than the guest; which
-  // is more realistic. We need to do this to make sure that the MouseDown event
-  // is received forwarded by the BrowserPlugin to the RWHVG and eventually back
-  // to the guest. The RWHVG will in turn notify the ChromeWVGDelegate of the
-  // newly observed mouse down (potentially a context menu).
-  const std::string transforms[] = {"rotate(20deg)", "scale(1.5, 2.0)",
-                                    "translate(20px, 30px)", "NONE"};
-  for (size_t index = 0; index < 4; ++index) {
-    std::string command =
-        base::StringPrintf("setTransform('%s')", transforms[index].c_str());
-    ExtensionTestMessageListener transform_set_listener("TRANSFORM_SET", false);
-    EXPECT_TRUE(content::ExecuteScript(embedder_web_contents(), command));
-    ASSERT_TRUE(transform_set_listener.WaitUntilSatisfied());
-
-    gfx::Rect embedder_view_bounds =
-        embedder_web_contents()->GetRenderWidgetHostView()->GetViewBounds();
-    gfx::Rect guest_view_bounds =
-        guest_web_contents()->GetRenderWidgetHostView()->GetViewBounds();
-    ContextMenuWaiter menu_observer(content::NotificationService::AllSources());
-    gfx::Point guest_window_point(150, 150);
-    gfx::Point embedder_window_point = guest_window_point;
-    embedder_window_point += guest_view_bounds.OffsetFromOrigin();
-    embedder_window_point -= embedder_view_bounds.OffsetFromOrigin();
-    SimulateRWHMouseClick(
-        embedder_web_contents()->GetRenderViewHost()->GetWidget(),
-        blink::WebMouseEvent::Button::kRight,
-        /* Using window coordinates for the embedder */
-        embedder_window_point.x(), embedder_window_point.y());
-
-    menu_observer.WaitForMenuOpenAndClose();
-    EXPECT_EQ(menu_observer.params().x, guest_window_point.x());
-    EXPECT_EQ(menu_observer.params().y, guest_window_point.y());
-  }
-}
-
 // https://crbug.com/754890: The embedder could become out of sync and think
 // that the guest is not focused when the guest actually was.
 // TODO(crbug.com/807116): Flaky on the Linux MSAN bot.
@@ -1317,7 +1260,9 @@
 
 // Flaky on ChromeOS and Linux: http://crbug.com/526886
 // TODO(crbug.com/807446): Flaky on Mac.
-#if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_MACOSX)
+// TODO(crbug.com/809383): Flaky on Windows.
+#if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_MACOSX) || \
+    defined(OS_WIN)
 #define MAYBE_PopupPositioningMoved DISABLED_PopupPositioningMoved
 #else
 #define MAYBE_PopupPositioningMoved PopupPositioningMoved
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc
index a9b23d6..754d777 100644
--- a/chrome/browser/autocomplete/search_provider_unittest.cc
+++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -505,7 +505,7 @@
   // a DCHECK.
   field_trial_list_.reset();
   field_trial_list_.reset(new base::FieldTrialList(
-      base::MakeUnique<metrics::SHA1EntropyProvider>("foo")));
+      base::MakeUnique<variations::SHA1EntropyProvider>("foo")));
   variations::testing::ClearAllVariationParams();
 }
 
diff --git a/chrome/browser/background/background_mode_manager_unittest.cc b/chrome/browser/background/background_mode_manager_unittest.cc
index c68ef11..a0d23a2 100644
--- a/chrome/browser/background/background_mode_manager_unittest.cc
+++ b/chrome/browser/background/background_mode_manager_unittest.cc
@@ -41,7 +41,6 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/image/image.h"
-#include "ui/message_center/message_center.h"
 #include "ui/message_center/public/cpp/notifier_id.h"
 
 #if defined(OS_CHROMEOS)
@@ -228,9 +227,6 @@
     profile_manager_ = CreateTestingProfileManager();
     profile_ = profile_manager_->CreateTestingProfile("p1");
 
-    // Aura clears notifications from the message center at shutdown.
-    message_center::MessageCenter::Initialize();
-
     test_keep_alive_.reset(
         new ScopedKeepAlive(KeepAliveOrigin::BACKGROUND_MODE_MANAGER,
                             KeepAliveRestartOption::DISABLED));
@@ -276,10 +272,6 @@
     // before tearing down the Message Center.
     profile_manager_.reset();
 
-    // Message Center shutdown must occur after the KeepAlive is released
-    // because clearing it will end up referencing the message center.
-    message_center::MessageCenter::Shutdown();
-
     // Clear the shutdown flag to isolate the remaining effect of this test.
     browser_shutdown::SetTryingToQuit(false);
   }
diff --git a/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc b/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc
index c20a0f4..1fbc2125 100644
--- a/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc
+++ b/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc
@@ -31,13 +31,13 @@
   resource_request->referrer = GURL(referrer);
   resource_request->referrer_policy = referrer_policy;
   resource_request->load_flags = load_flags;
-  simple_loader_ = content::SimpleURLLoader::Create(std::move(resource_request),
+  simple_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
                                                     traffic_annotation_);
 }
 
 void BitmapFetcher::Start(network::mojom::URLLoaderFactory* loader_factory) {
   if (simple_loader_) {
-    content::SimpleURLLoader::BodyAsStringCallback callback = base::BindOnce(
+    network::SimpleURLLoader::BodyAsStringCallback callback = base::BindOnce(
         &BitmapFetcher::OnSimpleLoaderComplete, base::Unretained(this));
     simple_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
         loader_factory, std::move(callback));
diff --git a/chrome/browser/bitmap_fetcher/bitmap_fetcher.h b/chrome/browser/bitmap_fetcher/bitmap_fetcher.h
index edc7495..6b2a52c 100644
--- a/chrome/browser/bitmap_fetcher/bitmap_fetcher.h
+++ b/chrome/browser/bitmap_fetcher/bitmap_fetcher.h
@@ -11,9 +11,9 @@
 #include "base/macros.h"
 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher_delegate.h"
 #include "chrome/browser/image_decoder.h"
-#include "content/public/common/simple_url_loader.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/url_request/url_request.h"
+#include "services/network/public/cpp/simple_url_loader.h"
 #include "services/network/public/interfaces/url_loader_factory.mojom.h"
 #include "url/gurl.h"
 
@@ -62,7 +62,7 @@
   // Alerts the delegate that a failure occurred.
   void ReportFailure();
 
-  std::unique_ptr<content::SimpleURLLoader> simple_loader_;
+  std::unique_ptr<network::SimpleURLLoader> simple_loader_;
 
   const GURL url_;
   BitmapFetcherDelegate* const delegate_;
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 72882965..946df8a 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -1360,8 +1360,7 @@
       FROM_HERE,
       base::BindOnce(
           base::IgnoreResult(&GoogleUpdateSettings::SetCollectStatsConsent),
-          ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-              local_state())));
+          ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled()));
 }
 #endif
 
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc
index e2a2e12..99a57ca 100644
--- a/chrome/browser/chrome_content_browser_client_unittest.cc
+++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -305,7 +305,7 @@
   void SetUp() override {
     BrowserWithTestWindowTest::SetUp();
     field_trial_list_.reset(new base::FieldTrialList(
-        base::MakeUnique<metrics::SHA1EntropyProvider>("42")));
+        base::MakeUnique<variations::SHA1EntropyProvider>("42")));
   }
 
   void InstallTemplateURLWithNewTabPage(GURL new_tab_page_url) {
diff --git a/chrome/browser/chrome_navigation_browsertest.cc b/chrome/browser/chrome_navigation_browsertest.cc
index e8c933d5..5a986b2c 100644
--- a/chrome/browser/chrome_navigation_browsertest.cc
+++ b/chrome/browser/chrome_navigation_browsertest.cc
@@ -18,7 +18,7 @@
 #include "components/network_session_configurator/common/network_switches.h"
 #include "components/url_formatter/url_formatter.h"
 #include "components/variations/active_field_trials.h"
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 #include "components/variations/variations_switches.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/navigation_handle.h"
@@ -670,7 +670,7 @@
     std::vector<std::string> synthetic_trials;
     variations::GetSyntheticTrialGroupIdsAsString(&synthetic_trials);
     std::string trial_hash =
-        base::StringPrintf("%x", metrics::HashName(trial_name));
+        base::StringPrintf("%x", variations::HashName(trial_name));
 
     for (auto entry : synthetic_trials) {
       if (base::StartsWith(entry, trial_hash, base::CompareCase::SENSITIVE))
@@ -684,8 +684,9 @@
                                const std::string& trial_group) {
     std::vector<std::string> synthetic_trials;
     variations::GetSyntheticTrialGroupIdsAsString(&synthetic_trials);
-    std::string expected_entry = base::StringPrintf(
-        "%x-%x", metrics::HashName(trial_name), metrics::HashName(trial_group));
+    std::string expected_entry =
+        base::StringPrintf("%x-%x", variations::HashName(trial_name),
+                           variations::HashName(trial_group));
 
     for (auto entry : synthetic_trials) {
       if (entry == expected_entry)
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index bd93596..b52428e 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -526,6 +526,8 @@
     "display/output_protection_delegate.h",
     "display/quirks_manager_delegate_impl.cc",
     "display/quirks_manager_delegate_impl.h",
+    "docked_magnifier/docked_magnifier_client.cc",
+    "docked_magnifier/docked_magnifier_client.h",
     "drive/debug_info_collector.cc",
     "drive/debug_info_collector.h",
     "drive/download_handler.cc",
@@ -1096,6 +1098,8 @@
     "login/ui/login_display.h",
     "login/ui/login_display_host.cc",
     "login/ui/login_display_host.h",
+    "login/ui/login_display_host_common.cc",
+    "login/ui/login_display_host_common.h",
     "login/ui/login_display_host_views.cc",
     "login/ui/login_display_host_views.h",
     "login/ui/login_display_host_webui.cc",
diff --git a/chrome/browser/chromeos/accessibility/dictation_chromeos.cc b/chrome/browser/chromeos/accessibility/dictation_chromeos.cc
index 15077f8..fce4cd3 100644
--- a/chrome/browser/chromeos/accessibility/dictation_chromeos.cc
+++ b/chrome/browser/chromeos/accessibility/dictation_chromeos.cc
@@ -61,7 +61,7 @@
 void DictationChromeos::OnSpeechSoundLevelChanged(int16_t level) {}
 
 void DictationChromeos::OnSpeechRecognitionStateChanged(
-    SpeechRecognizerState new_state) {
+    SpeechRecognizerStatus new_state) {
   if (new_state == SPEECH_RECOGNIZER_RECOGNIZING)
     media::SoundsManager::Get()->Play(chromeos::SOUND_ENTER_SCREEN);
 }
diff --git a/chrome/browser/chromeos/accessibility/dictation_chromeos.h b/chrome/browser/chromeos/accessibility/dictation_chromeos.h
index 2613756..75594ab 100644
--- a/chrome/browser/chromeos/accessibility/dictation_chromeos.h
+++ b/chrome/browser/chromeos/accessibility/dictation_chromeos.h
@@ -29,7 +29,7 @@
   void OnSpeechResult(const base::string16& query, bool is_final) override;
   void OnSpeechSoundLevelChanged(int16_t level) override;
   void OnSpeechRecognitionStateChanged(
-      SpeechRecognizerState new_state) override;
+      SpeechRecognizerStatus new_state) override;
   void GetSpeechAuthParameters(std::string* auth_scope,
                                std::string* auth_token) override;
 
diff --git a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
index 8fddb4d..94e54d4 100644
--- a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
+++ b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
@@ -114,17 +114,32 @@
   chromeos::WizardController* GetWizardController() override {
     return wizard_controller_.get();
   }
+  chromeos::AppLaunchController* GetAppLaunchController() override {
+    return nullptr;
+  }
   void StartUserAdding(base::OnceClosure completion_callback) override {}
   void CancelUserAdding() override {}
-  void OnStartSignInScreen(
-      const chromeos::LoginScreenContext& context) override {}
+  void StartSignInScreen(const chromeos::LoginScreenContext& context) override {
+  }
   void OnPreferencesChanged() override {}
-  void OnStartAppLaunch() override {}
-  void OnStartArcKiosk() override {}
+  void PrewarmAuthentication() override {}
+  void StartAppLaunch(const std::string& app_id,
+                      bool diagnostic_mode,
+                      bool is_auto_launch) override {}
+  void StartDemoAppLaunch() override {}
+  void StartArcKiosk(const AccountId& account_id) override {}
   void StartVoiceInteractionOobe() override {
     is_voice_interaction_oobe_ = true;
   }
   bool IsVoiceInteractionOobe() override { return is_voice_interaction_oobe_; }
+  void CompleteLogin(const chromeos::UserContext& user_context) override {}
+  void OnGaiaScreenReady() override {}
+  void SetDisplayEmail(const std::string& email) override {}
+  void SetDisplayAndGivenName(const std::string& display_name,
+                              const std::string& given_name) override {}
+  void LoadWallpaper(const AccountId& account_id) override {}
+  void LoadSigninWallpaper() override {}
+  bool IsUserWhitelisted(const AccountId& account_id) override { return false; }
 
  private:
   bool is_voice_interaction_oobe_ = false;
diff --git a/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.cc b/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.cc
index 4e19e70..c0871080 100644
--- a/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.cc
+++ b/chrome/browser/chromeos/arc/optin/arc_optin_preference_handler.cc
@@ -67,9 +67,7 @@
     const bool exists = chromeos::CrosSettings::Get()->GetBoolean(
         chromeos::kStatsReportingPref, &enabled);
     DCHECK(exists);
-    observer_->OnMetricsModeChanged(
-        enabled,
-        IsMetricsReportingPolicyManaged(g_browser_process->local_state()));
+    observer_->OnMetricsModeChanged(enabled, IsMetricsReportingPolicyManaged());
   }
 }
 
diff --git a/chrome/browser/chromeos/display/display_prefs_unittest.cc b/chrome/browser/chromeos/display/display_prefs_unittest.cc
index f365d46..4b809dd9 100644
--- a/chrome/browser/chromeos/display/display_prefs_unittest.cc
+++ b/chrome/browser/chromeos/display/display_prefs_unittest.cc
@@ -41,7 +41,6 @@
 #include "ui/display/screen.h"
 #include "ui/display/test/display_manager_test_api.h"
 #include "ui/gfx/geometry/vector3d_f.h"
-#include "ui/message_center/message_center.h"
 
 using ash::ResolutionNotificationController;
 
@@ -611,16 +610,11 @@
   EXPECT_FALSE(property->GetInteger("width", &width));
   EXPECT_FALSE(property->GetInteger("height", &height));
 
-  // Revert the change. When timeout, 2nd button is revert.
-  message_center::MessageCenter::Get()->ClickOnNotificationButton(
-      ResolutionNotificationController::kNotificationId, 1);
+  // Revert the change.
+  shell->resolution_notification_controller()->RevertResolutionChange(false);
   RunAllPendingInMessageLoop();
-  EXPECT_FALSE(
-      message_center::MessageCenter::Get()->FindVisibleNotificationById(
-          ResolutionNotificationController::kNotificationId));
 
-  // Once the notification is removed, the specified resolution will be stored
-  // by SetDisplayMode.
+  // The specified resolution will be stored by SetDisplayMode.
   ash::Shell::Get()->display_manager()->SetDisplayMode(
       id, display::ManagedDisplayMode(gfx::Size(300, 200), 60.0f, false, true));
   UpdateDisplay("300x200#500x400|400x300|300x200");
diff --git a/chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.cc b/chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.cc
new file mode 100644
index 0000000..743f697
--- /dev/null
+++ b/chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.cc
@@ -0,0 +1,64 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.h"
+
+#include "ash/public/interfaces/constants.mojom.h"
+#include "content/public/browser/focused_node_details.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_source.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/common/service_manager_connection.h"
+#include "services/service_manager/public/cpp/connector.h"
+
+DockedMagnifierClient::DockedMagnifierClient() : binding_(this) {}
+
+DockedMagnifierClient::~DockedMagnifierClient() {}
+
+void DockedMagnifierClient::Start() {
+  if (!docked_magnifier_controller_) {
+    service_manager::Connector* connector =
+        content::ServiceManagerConnection::GetForProcess()->GetConnector();
+    connector->BindInterface(ash::mojom::kServiceName,
+                             &docked_magnifier_controller_);
+  }
+  ash::mojom::DockedMagnifierClientPtr client;
+  binding_.Bind(mojo::MakeRequest(&client));
+  docked_magnifier_controller_->SetClient(std::move(client));
+}
+
+void DockedMagnifierClient::OnEnabledStatusChanged(bool enabled) {
+  if (enabled == observing_focus_changes_)
+    return;
+
+  observing_focus_changes_ = enabled;
+  if (enabled) {
+    registrar_.Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
+                   content::NotificationService::AllSources());
+  } else {
+    registrar_.Remove(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
+                      content::NotificationService::AllSources());
+  }
+}
+
+void DockedMagnifierClient::Observe(
+    int type,
+    const content::NotificationSource& source,
+    const content::NotificationDetails& details) {
+  DCHECK_EQ(type, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE);
+
+  content::FocusedNodeDetails* node_details =
+      content::Details<content::FocusedNodeDetails>(details).ptr();
+  // Ash uses the InputMethod of the window tree host to observe text input
+  // caret bounds changes, which works for both the native UI as well as
+  // webpages. We don't need to notify it of editable nodes in this case.
+  if (node_details->is_editable_node)
+    return;
+
+  const gfx::Rect& bounds_in_screen = node_details->node_bounds_in_screen;
+  if (bounds_in_screen.IsEmpty())
+    return;
+
+  docked_magnifier_controller_->CenterOnPoint(bounds_in_screen.CenterPoint());
+}
diff --git a/chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.h b/chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.h
new file mode 100644
index 0000000..f8cfb053
--- /dev/null
+++ b/chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.h
@@ -0,0 +1,44 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DOCKED_MAGNIFIER_DOCKED_MAGNIFIER_CLIENT_H_
+#define CHROME_BROWSER_CHROMEOS_DOCKED_MAGNIFIER_DOCKED_MAGNIFIER_CLIENT_H_
+
+#include <memory>
+
+#include "ash/public/interfaces/docked_magnifier_controller.mojom.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "mojo/public/cpp/bindings/binding.h"
+
+// Observes focus change events for nodes in webpages and notifies the Docked
+// Magnifier with these events.
+class DockedMagnifierClient : public ash::mojom::DockedMagnifierClient,
+                              public content::NotificationObserver {
+ public:
+  DockedMagnifierClient();
+  ~DockedMagnifierClient() override;
+
+  void Start();
+
+  // ash::mojom::DockedMagnifierClient:
+  void OnEnabledStatusChanged(bool enabled) override;
+
+  // content::NotificationObserver:
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
+
+ private:
+  ash::mojom::DockedMagnifierControllerPtr docked_magnifier_controller_;
+  mojo::Binding<ash::mojom::DockedMagnifierClient> binding_;
+
+  content::NotificationRegistrar registrar_;
+
+  bool observing_focus_changes_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(DockedMagnifierClient);
+};
+
+#endif  // CHROME_BROWSER_CHROMEOS_DOCKED_MAGNIFIER_DOCKED_MAGNIFIER_CLIENT_H_
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
index 9531e47..e70bb8af 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
@@ -973,8 +973,7 @@
 ExtensionFunction::ResponseAction
 FileManagerPrivateIsUMAEnabledFunction::Run() {
   return RespondNow(OneArgument(std::make_unique<base::Value>(
-      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-          g_browser_process->local_state()))));
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled())));
 }
 
 FileManagerPrivateInternalSetEntryTagFunction::
diff --git a/chrome/browser/chromeos/login/screens/terms_of_service_screen.cc b/chrome/browser/chromeos/login/screens/terms_of_service_screen.cc
index 4685afb..dedc55b7 100644
--- a/chrome/browser/chromeos/login/screens/terms_of_service_screen.cc
+++ b/chrome/browser/chromeos/login/screens/terms_of_service_screen.cc
@@ -20,9 +20,9 @@
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/storage_partition.h"
-#include "content/public/common/simple_url_loader.h"
 #include "net/http/http_response_headers.h"
 #include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/simple_url_loader.h"
 #include "services/network/public/interfaces/url_loader_factory.mojom.h"
 #include "url/gurl.h"
 
@@ -118,12 +118,12 @@
   // Request a text/plain MIME type as only plain-text Terms of Service are
   // accepted.
   resource_request->headers.SetHeader("Accept", "text/plain");
-  terms_of_service_loader_ = content::SimpleURLLoader::Create(
+  terms_of_service_loader_ = network::SimpleURLLoader::Create(
       std::move(resource_request), traffic_annotation);
   // Retry up to three times if network changes are detected during the
   // download.
   terms_of_service_loader_->SetRetryOptions(
-      3, content::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE);
+      3, network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE);
   network::mojom::URLLoaderFactory* loader_factory =
       g_browser_process->system_network_context_manager()
           ->GetURLLoaderFactory();
@@ -150,7 +150,7 @@
   download_timer_.Stop();
 
   // Destroy the fetcher when this method returns.
-  std::unique_ptr<content::SimpleURLLoader> loader(
+  std::unique_ptr<network::SimpleURLLoader> loader(
       std::move(terms_of_service_loader_));
   if (!view_)
     return;
diff --git a/chrome/browser/chromeos/login/screens/terms_of_service_screen.h b/chrome/browser/chromeos/login/screens/terms_of_service_screen.h
index 700a372..1eeadf7 100644
--- a/chrome/browser/chromeos/login/screens/terms_of_service_screen.h
+++ b/chrome/browser/chromeos/login/screens/terms_of_service_screen.h
@@ -13,7 +13,7 @@
 #include "chrome/browser/chromeos/login/screens/base_screen.h"
 #include "chrome/browser/chromeos/login/screens/terms_of_service_screen_view.h"
 
-namespace content {
+namespace network {
 class SimpleURLLoader;
 }
 
@@ -53,7 +53,7 @@
 
   TermsOfServiceScreenView* view_;
 
-  std::unique_ptr<content::SimpleURLLoader> terms_of_service_loader_;
+  std::unique_ptr<network::SimpleURLLoader> terms_of_service_loader_;
 
   // Timer that enforces a custom (shorter) timeout on the attempt to download
   // the Terms of Service.
diff --git a/chrome/browser/chromeos/login/ui/login_display_host.cc b/chrome/browser/chromeos/login/ui/login_display_host.cc
index 909c7f0..8dd5479 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host.cc
@@ -16,19 +16,11 @@
 #include "chrome/browser/ui/ash/wallpaper_controller_client.h"
 
 namespace chromeos {
-namespace {
-
-// The delay of triggering initialization of the device policy subsystem
-// after the login screen is initialized. This makes sure that device policy
-// network requests are made while the system is idle waiting for user input.
-constexpr int64_t kPolicyServiceInitializationDelayMilliseconds = 100;
-
-}  // namespace
 
 // static
 LoginDisplayHost* LoginDisplayHost::default_host_ = nullptr;
 
-LoginDisplayHost::LoginDisplayHost() : weak_factory_(this) {
+LoginDisplayHost::LoginDisplayHost() {
   DCHECK(default_host() == nullptr);
   default_host_ = this;
 }
@@ -37,150 +29,4 @@
   default_host_ = nullptr;
 }
 
-AppLaunchController* LoginDisplayHost::GetAppLaunchController() {
-  return app_launch_controller_.get();
-}
-
-void LoginDisplayHost::StartSignInScreen(const LoginScreenContext& context) {
-  PrewarmAuthentication();
-
-  const user_manager::UserList& users =
-      user_manager::UserManager::Get()->GetUsers();
-
-  // Fix for users who updated device and thus never passed register screen.
-  // If we already have users, we assume that it is not a second part of
-  // OOBE. See http://crosbug.com/6289
-  if (!StartupUtils::IsDeviceRegistered() && !users.empty()) {
-    VLOG(1) << "Mark device registered because there are remembered users: "
-            << users.size();
-    StartupUtils::MarkDeviceRegistered(base::OnceClosure());
-  }
-
-  // Initiate mobile config load.
-  MobileConfig::GetInstance();
-
-  // Initiate device policy fetching.
-  policy::BrowserPolicyConnectorChromeOS* connector =
-      g_browser_process->platform_part()->browser_policy_connector_chromeos();
-  connector->ScheduleServiceInitialization(
-      kPolicyServiceInitializationDelayMilliseconds);
-
-  // Run UI-specific logic.
-  OnStartSignInScreen(context);
-
-  // Enable status area after starting sign-in screen, as it may depend on the
-  // UI being visible.
-  SetStatusAreaVisible(true);
-}
-
-void LoginDisplayHost::PrewarmAuthentication() {
-  auth_prewarmer_ = std::make_unique<AuthPrewarmer>();
-  auth_prewarmer_->PrewarmAuthentication(base::BindOnce(
-      &LoginDisplayHost::OnAuthPrewarmDone, weak_factory_.GetWeakPtr()));
-}
-
-void LoginDisplayHost::StartAppLaunch(const std::string& app_id,
-                                      bool diagnostic_mode,
-                                      bool is_auto_launch) {
-  VLOG(1) << "Login >> start app launch.";
-  SetStatusAreaVisible(false);
-
-  // Wait for the |CrosSettings| to become either trusted or permanently
-  // untrusted.
-  const CrosSettingsProvider::TrustedStatus status =
-      CrosSettings::Get()->PrepareTrustedValues(base::Bind(
-          &LoginDisplayHost::StartAppLaunch, weak_factory_.GetWeakPtr(), app_id,
-          diagnostic_mode, is_auto_launch));
-  if (status == CrosSettingsProvider::TEMPORARILY_UNTRUSTED)
-    return;
-
-  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
-    // If the |CrosSettings| are permanently untrusted, refuse to launch a
-    // single-app kiosk mode session.
-    LOG(ERROR) << "Login >> Refusing to launch single-app kiosk mode.";
-    SetStatusAreaVisible(true);
-    return;
-  }
-
-  if (system::DeviceDisablingManager::IsDeviceDisabledDuringNormalOperation()) {
-    // If the device is disabled, bail out. A device disabled screen will be
-    // shown by the DeviceDisablingManager.
-    return;
-  }
-
-  OnStartAppLaunch();
-
-  app_launch_controller_ = std::make_unique<AppLaunchController>(
-      app_id, diagnostic_mode, this, GetOobeUI());
-
-  app_launch_controller_->StartAppLaunch(is_auto_launch);
-}
-
-void LoginDisplayHost::StartDemoAppLaunch() {
-  VLOG(1) << "Login >> starting demo app.";
-  SetStatusAreaVisible(false);
-
-  demo_app_launcher_ = std::make_unique<DemoAppLauncher>();
-  demo_app_launcher_->StartDemoAppLaunch();
-}
-
-void LoginDisplayHost::StartArcKiosk(const AccountId& account_id) {
-  VLOG(1) << "Login >> start ARC kiosk.";
-  SetStatusAreaVisible(false);
-  arc_kiosk_controller_ =
-      std::make_unique<ArcKioskController>(this, GetOobeUI());
-  arc_kiosk_controller_->StartArcKiosk(account_id);
-
-  OnStartArcKiosk();
-}
-
-void LoginDisplayHost::OnAuthPrewarmDone() {
-  auth_prewarmer_.reset();
-}
-
-void LoginDisplayHost::CompleteLogin(const UserContext& user_context) {
-  ExistingUserController* controller =
-      ExistingUserController::current_controller();
-  if (controller)
-    controller->CompleteLogin(user_context);
-}
-
-void LoginDisplayHost::OnGaiaScreenReady() {
-  ExistingUserController* controller =
-      ExistingUserController::current_controller();
-  if (controller)
-    controller->OnGaiaScreenReady();
-}
-
-void LoginDisplayHost::SetDisplayEmail(const std::string& email) {
-  ExistingUserController* controller =
-      ExistingUserController::current_controller();
-  if (controller)
-    controller->SetDisplayEmail(email);
-}
-
-void LoginDisplayHost::SetDisplayAndGivenName(const std::string& display_name,
-                                              const std::string& given_name) {
-  ExistingUserController* controller =
-      ExistingUserController::current_controller();
-  if (controller)
-    controller->SetDisplayAndGivenName(display_name, given_name);
-}
-
-void LoginDisplayHost::LoadWallpaper(const AccountId& account_id) {
-  WallpaperControllerClient::Get()->ShowUserWallpaper(account_id);
-}
-
-void LoginDisplayHost::LoadSigninWallpaper() {
-  WallpaperControllerClient::Get()->ShowSigninWallpaper();
-}
-
-bool LoginDisplayHost::IsUserWhitelisted(const AccountId& account_id) {
-  ExistingUserController* controller =
-      ExistingUserController::current_controller();
-  if (!controller)
-    return true;
-  return controller->IsUserWhitelisted(account_id);
-}
-
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/login_display_host.h b/chrome/browser/chromeos/login/ui/login_display_host.h
index 154655d..98446cb 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host.h
@@ -20,25 +20,35 @@
 
 namespace chromeos {
 
-class ArcKioskController;
 class AppLaunchController;
-class DemoAppLauncher;
 class LoginScreenContext;
 class OobeUI;
 class WebUILoginView;
 class WizardController;
 
-// An interface that defines OOBE/login screen host.
-// Host encapsulates WebUI window OOBE/login controllers,
-// UI implementation (such as LoginDisplay).
+// An interface that defines an out-of-box-experience (OOBE) or login screen
+// host. It contains code specific to the login UI implementation.
+//
+// The inheritance graph is as folllows:
+//
+//                               LoginDisplayHost
+//                                   /       |
+//                LoginDisplayHostCommon   MockLoginDisplayHost
+//                      /      |
+//   LoginDisplayHostViews   LoginDisplayHostWebUI
+//
+//
+// - LoginDisplayHost defines the generic interface.
+// - LoginDisplayHostCommon is UI-agnostic code shared between the views and
+//   webui hosts.
+// - MockLoginDisplayHost is for tests.
+// - LoginDisplayHostViews is for the login screen, which is written in views.
+// - LoginDisplayHostWebUI is for OOBE, which is written in HTML/JS/CSS.
 class LoginDisplayHost {
  public:
   // Returns the default LoginDisplayHost instance if it has been created.
   static LoginDisplayHost* default_host() { return default_host_; }
 
-  LoginDisplayHost();
-  virtual ~LoginDisplayHost();
-
   // Creates UI implementation specific login display instance (views/WebUI).
   // The caller takes ownership of the returned value.
   virtual LoginDisplay* CreateLoginDisplay(
@@ -75,7 +85,7 @@
 
   // Returns current AppLaunchController, if it exists.
   // Result should not be stored.
-  AppLaunchController* GetAppLaunchController();
+  virtual AppLaunchController* GetAppLaunchController() = 0;
 
   // Starts screen for adding user into session.
   // |completion_callback| is invoked after login display host shutdown.
@@ -86,25 +96,25 @@
   virtual void CancelUserAdding() = 0;
 
   // Starts sign in screen.
-  void StartSignInScreen(const LoginScreenContext& context);
+  virtual void StartSignInScreen(const LoginScreenContext& context) = 0;
 
   // Invoked when system preferences that affect the signin screen have changed.
   virtual void OnPreferencesChanged() = 0;
 
   // Initiates authentication network prewarming.
-  void PrewarmAuthentication();
+  virtual void PrewarmAuthentication() = 0;
 
   // Starts app launch splash screen. If |is_auto_launch| is true, the app is
   // being auto-launched with no delay.
-  void StartAppLaunch(const std::string& app_id,
-                      bool diagnostic_mode,
-                      bool is_auto_launch);
+  virtual void StartAppLaunch(const std::string& app_id,
+                              bool diagnostic_mode,
+                              bool is_auto_launch) = 0;
 
   // Starts the demo app launch.
-  void StartDemoAppLaunch();
+  virtual void StartDemoAppLaunch() = 0;
 
   // Starts ARC kiosk splash screen.
-  void StartArcKiosk(const AccountId& account_id);
+  virtual void StartArcKiosk(const AccountId& account_id) = 0;
 
   // Start voice interaction OOBE.
   virtual void StartVoiceInteractionOobe() = 0;
@@ -114,56 +124,38 @@
 
   // Confirms sign in by provided credentials in |user_context|.
   // Used for new user login via GAIA extension.
-  void CompleteLogin(const UserContext& user_context);
+  virtual void CompleteLogin(const UserContext& user_context) = 0;
 
   // Notify the backend controller when the GAIA UI is finished loading.
-  void OnGaiaScreenReady();
+  virtual void OnGaiaScreenReady() = 0;
 
   // Sets the displayed email for the next login attempt. If it succeeds,
   // user's displayed email value will be updated to |email|.
-  void SetDisplayEmail(const std::string& email);
+  virtual void SetDisplayEmail(const std::string& email) = 0;
 
   // Sets the displayed name and given name for the next login attempt. If it
   // succeeds, user's displayed name and give name values will be updated to
   // |display_name| and |given_name|.
-  void SetDisplayAndGivenName(const std::string& display_name,
-                              const std::string& given_name);
+  virtual void SetDisplayAndGivenName(const std::string& display_name,
+                                      const std::string& given_name) = 0;
 
   // Load wallpaper for given |account_id|.
-  void LoadWallpaper(const AccountId& account_id);
+  virtual void LoadWallpaper(const AccountId& account_id) = 0;
 
   // Loads the default sign-in wallpaper.
-  void LoadSigninWallpaper();
+  virtual void LoadSigninWallpaper() = 0;
 
   // Returns true if user is allowed to log in by domain policy.
-  bool IsUserWhitelisted(const AccountId& account_id);
+  virtual bool IsUserWhitelisted(const AccountId& account_id) = 0;
 
  protected:
-  virtual void OnStartSignInScreen(const LoginScreenContext& context) = 0;
-  virtual void OnStartAppLaunch() = 0;
-  virtual void OnStartArcKiosk() = 0;
-
-  // Deletes |auth_prewarmer_|.
-  void OnAuthPrewarmDone();
-
-  // Active instance of authentication prewarmer.
-  std::unique_ptr<AuthPrewarmer> auth_prewarmer_;
-
-  // App launch controller.
-  std::unique_ptr<AppLaunchController> app_launch_controller_;
-
-  // Demo app launcher.
-  std::unique_ptr<DemoAppLauncher> demo_app_launcher_;
-
-  // ARC kiosk controller.
-  std::unique_ptr<ArcKioskController> arc_kiosk_controller_;
+  LoginDisplayHost();
+  virtual ~LoginDisplayHost();
 
  private:
   // Global LoginDisplayHost instance.
   static LoginDisplayHost* default_host_;
 
-  base::WeakPtrFactory<LoginDisplayHost> weak_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(LoginDisplayHost);
 };
 
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_common.cc b/chrome/browser/chromeos/login/ui/login_display_host_common.cc
new file mode 100644
index 0000000..e32e878
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/login_display_host_common.cc
@@ -0,0 +1,180 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/login/ui/login_display_host_common.h"
+
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/login/app_launch_controller.h"
+#include "chrome/browser/chromeos/login/arc_kiosk_controller.h"
+#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
+#include "chrome/browser/chromeos/login/existing_user_controller.h"
+#include "chrome/browser/chromeos/login/startup_utils.h"
+#include "chrome/browser/chromeos/mobile_config.h"
+#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/chromeos/system/device_disabling_manager.h"
+#include "chrome/browser/ui/ash/wallpaper_controller_client.h"
+
+namespace chromeos {
+namespace {
+
+// The delay of triggering initialization of the device policy subsystem
+// after the login screen is initialized. This makes sure that device policy
+// network requests are made while the system is idle waiting for user input.
+constexpr int64_t kPolicyServiceInitializationDelayMilliseconds = 100;
+
+}  // namespace
+
+LoginDisplayHostCommon::LoginDisplayHostCommon() : weak_factory_(this) {}
+
+LoginDisplayHostCommon::~LoginDisplayHostCommon() {}
+
+AppLaunchController* LoginDisplayHostCommon::GetAppLaunchController() {
+  return app_launch_controller_.get();
+}
+
+void LoginDisplayHostCommon::StartSignInScreen(
+    const LoginScreenContext& context) {
+  PrewarmAuthentication();
+
+  const user_manager::UserList& users =
+      user_manager::UserManager::Get()->GetUsers();
+
+  // Fix for users who updated device and thus never passed register screen.
+  // If we already have users, we assume that it is not a second part of
+  // OOBE. See http://crosbug.com/6289
+  if (!StartupUtils::IsDeviceRegistered() && !users.empty()) {
+    VLOG(1) << "Mark device registered because there are remembered users: "
+            << users.size();
+    StartupUtils::MarkDeviceRegistered(base::OnceClosure());
+  }
+
+  // Initiate mobile config load.
+  MobileConfig::GetInstance();
+
+  // Initiate device policy fetching.
+  policy::BrowserPolicyConnectorChromeOS* connector =
+      g_browser_process->platform_part()->browser_policy_connector_chromeos();
+  connector->ScheduleServiceInitialization(
+      kPolicyServiceInitializationDelayMilliseconds);
+
+  // Run UI-specific logic.
+  OnStartSignInScreen(context);
+
+  // Enable status area after starting sign-in screen, as it may depend on the
+  // UI being visible.
+  SetStatusAreaVisible(true);
+}
+
+void LoginDisplayHostCommon::PrewarmAuthentication() {
+  auth_prewarmer_ = std::make_unique<AuthPrewarmer>();
+  auth_prewarmer_->PrewarmAuthentication(base::BindOnce(
+      &LoginDisplayHostCommon::OnAuthPrewarmDone, weak_factory_.GetWeakPtr()));
+}
+
+void LoginDisplayHostCommon::StartAppLaunch(const std::string& app_id,
+                                            bool diagnostic_mode,
+                                            bool is_auto_launch) {
+  VLOG(1) << "Login >> start app launch.";
+  SetStatusAreaVisible(false);
+
+  // Wait for the |CrosSettings| to become either trusted or permanently
+  // untrusted.
+  const CrosSettingsProvider::TrustedStatus status =
+      CrosSettings::Get()->PrepareTrustedValues(base::Bind(
+          &LoginDisplayHostCommon::StartAppLaunch, weak_factory_.GetWeakPtr(),
+          app_id, diagnostic_mode, is_auto_launch));
+  if (status == CrosSettingsProvider::TEMPORARILY_UNTRUSTED)
+    return;
+
+  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
+    // If the |CrosSettings| are permanently untrusted, refuse to launch a
+    // single-app kiosk mode session.
+    LOG(ERROR) << "Login >> Refusing to launch single-app kiosk mode.";
+    SetStatusAreaVisible(true);
+    return;
+  }
+
+  if (system::DeviceDisablingManager::IsDeviceDisabledDuringNormalOperation()) {
+    // If the device is disabled, bail out. A device disabled screen will be
+    // shown by the DeviceDisablingManager.
+    return;
+  }
+
+  OnStartAppLaunch();
+
+  app_launch_controller_ = std::make_unique<AppLaunchController>(
+      app_id, diagnostic_mode, this, GetOobeUI());
+
+  app_launch_controller_->StartAppLaunch(is_auto_launch);
+}
+
+void LoginDisplayHostCommon::StartDemoAppLaunch() {
+  VLOG(1) << "Login >> starting demo app.";
+  SetStatusAreaVisible(false);
+
+  demo_app_launcher_ = std::make_unique<DemoAppLauncher>();
+  demo_app_launcher_->StartDemoAppLaunch();
+}
+
+void LoginDisplayHostCommon::StartArcKiosk(const AccountId& account_id) {
+  VLOG(1) << "Login >> start ARC kiosk.";
+  SetStatusAreaVisible(false);
+  arc_kiosk_controller_ =
+      std::make_unique<ArcKioskController>(this, GetOobeUI());
+  arc_kiosk_controller_->StartArcKiosk(account_id);
+
+  OnStartArcKiosk();
+}
+
+void LoginDisplayHostCommon::OnAuthPrewarmDone() {
+  auth_prewarmer_.reset();
+}
+
+void LoginDisplayHostCommon::CompleteLogin(const UserContext& user_context) {
+  ExistingUserController* controller =
+      ExistingUserController::current_controller();
+  if (controller)
+    controller->CompleteLogin(user_context);
+}
+
+void LoginDisplayHostCommon::OnGaiaScreenReady() {
+  ExistingUserController* controller =
+      ExistingUserController::current_controller();
+  if (controller)
+    controller->OnGaiaScreenReady();
+}
+
+void LoginDisplayHostCommon::SetDisplayEmail(const std::string& email) {
+  ExistingUserController* controller =
+      ExistingUserController::current_controller();
+  if (controller)
+    controller->SetDisplayEmail(email);
+}
+
+void LoginDisplayHostCommon::SetDisplayAndGivenName(
+    const std::string& display_name,
+    const std::string& given_name) {
+  ExistingUserController* controller =
+      ExistingUserController::current_controller();
+  if (controller)
+    controller->SetDisplayAndGivenName(display_name, given_name);
+}
+
+void LoginDisplayHostCommon::LoadWallpaper(const AccountId& account_id) {
+  WallpaperControllerClient::Get()->ShowUserWallpaper(account_id);
+}
+
+void LoginDisplayHostCommon::LoadSigninWallpaper() {
+  WallpaperControllerClient::Get()->ShowSigninWallpaper();
+}
+
+bool LoginDisplayHostCommon::IsUserWhitelisted(const AccountId& account_id) {
+  ExistingUserController* controller =
+      ExistingUserController::current_controller();
+  if (!controller)
+    return true;
+  return controller->IsUserWhitelisted(account_id);
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_common.h b/chrome/browser/chromeos/login/ui/login_display_host_common.h
new file mode 100644
index 0000000..6a27a6e
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/login_display_host_common.h
@@ -0,0 +1,75 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_DISPLAY_HOST_COMMON_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_DISPLAY_HOST_COMMON_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "chrome/browser/chromeos/login/ui/login_display_host.h"
+
+class AccountId;
+
+namespace chromeos {
+
+class ArcKioskController;
+class DemoAppLauncher;
+
+// LoginDisplayHostCommon contains code which is not specific to a particular UI
+// implementation - the goal is to reduce code duplication between
+// LoginDisplayHostViews and LoginDisplayHostWebUI.
+class LoginDisplayHostCommon : public LoginDisplayHost {
+ public:
+  LoginDisplayHostCommon();
+  ~LoginDisplayHostCommon() override;
+
+  // LoginDisplayHost:
+  AppLaunchController* GetAppLaunchController() final;
+  void StartSignInScreen(const LoginScreenContext& context) final;
+  void PrewarmAuthentication() final;
+  void StartAppLaunch(const std::string& app_id,
+                      bool diagnostic_mode,
+                      bool is_auto_launch) final;
+  void StartDemoAppLaunch() final;
+  void StartArcKiosk(const AccountId& account_id) final;
+  void CompleteLogin(const UserContext& user_context) final;
+  void OnGaiaScreenReady() final;
+  void SetDisplayEmail(const std::string& email) final;
+  void SetDisplayAndGivenName(const std::string& display_name,
+                              const std::string& given_name) final;
+  void LoadWallpaper(const AccountId& account_id) final;
+  void LoadSigninWallpaper() final;
+  bool IsUserWhitelisted(const AccountId& account_id) final;
+
+ protected:
+  virtual void OnStartSignInScreen(const LoginScreenContext& context) = 0;
+  virtual void OnStartAppLaunch() = 0;
+  virtual void OnStartArcKiosk() = 0;
+
+  // Deletes |auth_prewarmer_|.
+  void OnAuthPrewarmDone();
+
+  // Active instance of authentication prewarmer.
+  std::unique_ptr<AuthPrewarmer> auth_prewarmer_;
+
+  // App launch controller.
+  std::unique_ptr<AppLaunchController> app_launch_controller_;
+
+  // Demo app launcher.
+  std::unique_ptr<DemoAppLauncher> demo_app_launcher_;
+
+  // ARC kiosk controller.
+  std::unique_ptr<ArcKioskController> arc_kiosk_controller_;
+
+ private:
+  base::WeakPtrFactory<LoginDisplayHostCommon> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(LoginDisplayHostCommon);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_DISPLAY_HOST_COMMON_H_
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_views.h b/chrome/browser/chromeos/login/ui/login_display_host_views.h
index 5518867..df1b6b62 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_views.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_views.h
@@ -7,10 +7,11 @@
 
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "chrome/browser/chromeos/login/ui/login_display_host.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host_common.h"
 #include "chrome/browser/ui/ash/login_screen_client.h"
 #include "chromeos/login/auth/auth_status_consumer.h"
 
@@ -20,7 +21,7 @@
 
 // A LoginDisplayHost instance that sends requests to the views-based signin
 // screen.
-class LoginDisplayHostViews : public LoginDisplayHost,
+class LoginDisplayHostViews : public LoginDisplayHostCommon,
                               public LoginScreenClient::Delegate,
                               public AuthStatusConsumer {
  public:
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.h b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
index 4fa54d95..bcd0a3a 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_webui.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
@@ -16,7 +16,7 @@
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/signin_screen_controller.h"
 #include "chrome/browser/chromeos/login/ui/login_display.h"
-#include "chrome/browser/chromeos/login/ui/login_display_host.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host_common.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
@@ -44,7 +44,7 @@
 
 // An implementation class for OOBE/login WebUI screen host.
 // It encapsulates controllers, wallpaper integration and flow.
-class LoginDisplayHostWebUI : public LoginDisplayHost,
+class LoginDisplayHostWebUI : public LoginDisplayHostCommon,
                               public content::NotificationObserver,
                               public content::WebContentsObserver,
                               public chromeos::SessionManagerClient::Observer,
@@ -57,7 +57,7 @@
   explicit LoginDisplayHostWebUI(const gfx::Rect& wallpaper_bounds);
   ~LoginDisplayHostWebUI() override;
 
-  // LoginDisplayHost implementation:
+  // LoginDisplayHost:
   LoginDisplay* CreateLoginDisplay(LoginDisplay::Delegate* delegate) override;
   gfx::NativeWindow GetNativeWindow() const override;
   OobeUI* GetOobeUI() const override;
diff --git a/chrome/browser/chromeos/login/ui/mock_login_display_host.h b/chrome/browser/chromeos/login/ui/mock_login_display_host.h
index e161644..ceea6c3 100644
--- a/chrome/browser/chromeos/login/ui/mock_login_display_host.h
+++ b/chrome/browser/chromeos/login/ui/mock_login_display_host.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_UI_MOCK_LOGIN_DISPLAY_HOST_H_
 #define CHROME_BROWSER_CHROMEOS_LOGIN_UI_MOCK_LOGIN_DISPLAY_HOST_H_
 
+#include <string>
+
 #include "base/macros.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
@@ -30,9 +32,9 @@
   }
 
   MOCK_METHOD1(SetStatusAreaVisible, void(bool));
-  MOCK_METHOD0(ShowBackground, void(void));
   MOCK_METHOD1(StartWizard, void(OobeScreen));
   MOCK_METHOD0(GetWizardController, WizardController*(void));
+  MOCK_METHOD0(GetAppLaunchController, AppLaunchController*(void));
 
   // Workaround for move-only args in GMock.
   MOCK_METHOD1(MockStartUserAdding, void(base::OnceClosure*));
@@ -41,16 +43,24 @@
   }
 
   MOCK_METHOD0(CancelUserAdding, void(void));
-  MOCK_METHOD1(OnStartSignInScreen, void(const LoginScreenContext&));
-  MOCK_METHOD0(ResumeSignInScreen, void(void));
+  MOCK_METHOD1(StartSignInScreen, void(const LoginScreenContext&));
   MOCK_METHOD0(OnPreferencesChanged, void(void));
   MOCK_METHOD0(PrewarmAuthentication, void(void));
-  MOCK_METHOD0(OnStartAppLaunch, void());
+  MOCK_METHOD3(StartAppLaunch, void(const std::string&, bool, bool));
   MOCK_METHOD0(StartDemoAppLaunch, void(void));
-  MOCK_METHOD0(OnStartArcKiosk, void());
+  MOCK_METHOD1(StartArcKiosk, void(const AccountId&));
   MOCK_METHOD0(StartVoiceInteractionOobe, void(void));
   MOCK_METHOD0(IsVoiceInteractionOobe, bool(void));
 
+  MOCK_METHOD1(CompleteLogin, void(const UserContext&));
+  MOCK_METHOD0(OnGaiaScreenReady, void());
+  MOCK_METHOD1(SetDisplayEmail, void(const std::string&));
+  MOCK_METHOD2(SetDisplayAndGivenName,
+               void(const std::string&, const std::string&));
+  MOCK_METHOD1(LoadWallpaper, void(const AccountId&));
+  MOCK_METHOD0(LoadSigninWallpaper, void());
+  MOCK_METHOD1(IsUserWhitelisted, bool(const AccountId&));
+
  private:
   DISALLOW_COPY_AND_ASSIGN(MockLoginDisplayHost);
 };
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index 9cd3ab0..167a64f 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -774,8 +774,6 @@
   time_eula_accepted_ = base::Time::Now();
   StartupUtils::MarkEulaAccepted();
   ChangeMetricsReportingStateWithReply(
-      g_browser_process->local_state(),
-      g_browser_process->GetMetricsServicesManager(),
       usage_statistics_reporting_,
       base::Bind(&WizardController::OnChangedMetricsReportingState,
                  weak_factory_.GetWeakPtr()));
diff --git a/chrome/browser/chromeos/net/network_portal_notification_controller.cc b/chrome/browser/chromeos/net/network_portal_notification_controller.cc
index 17799ed..23a38c9 100644
--- a/chrome/browser/chromeos/net/network_portal_notification_controller.cc
+++ b/chrome/browser/chromeos/net/network_portal_notification_controller.cc
@@ -27,8 +27,8 @@
 #include "chrome/browser/chromeos/net/network_portal_web_dialog.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
-#include "chrome/browser/notifications/notification_display_service.h"
 #include "chrome/browser/notifications/notification_handler.h"
+#include "chrome/browser/notifications/system_notification_helper.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
@@ -73,8 +73,7 @@
 }
 
 void CloseNotification() {
-  NotificationDisplayService::GetForSystemNotifications()->Close(
-      NotificationHandler::Type::TRANSIENT,
+  SystemNotificationHelper::GetInstance()->Close(
       NetworkPortalNotificationController::kNotificationId);
 }
 
@@ -293,8 +292,8 @@
         network->guid());
   }
 
-  NotificationDisplayService::GetForSystemNotifications()->Display(
-      NotificationHandler::Type::TRANSIENT, *GetNotification(network, state));
+  SystemNotificationHelper::GetInstance()->Display(
+      *GetNotification(network, state));
   UMA_HISTOGRAM_ENUMERATION(
       NetworkPortalNotificationController::kNotificationMetric,
       NetworkPortalNotificationController::NOTIFICATION_METRIC_DISPLAYED,
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
index a184fd89..eb250d6 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
+++ b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
@@ -22,6 +22,7 @@
 #include "chromeos/network/fake_network_device_handler.h"
 #include "chromeos/network/mock_managed_network_configuration_handler.h"
 #include "chromeos/network/onc/onc_certificate_importer.h"
+#include "chromeos/network/onc/onc_parsed_certificates.h"
 #include "chromeos/network/onc/onc_test_utils.h"
 #include "chromeos/network/onc/onc_utils.h"
 #include "components/onc/onc_constants.h"
@@ -121,8 +122,10 @@
     onc_trusted_certificates_ = std::move(onc_trusted_certificates);
   }
 
-  void SetExpectedONCCertificates(const base::ListValue& certificates) {
-    expected_onc_certificates_.reset(certificates.DeepCopy());
+  void SetExpectedONCCertificates(
+      std::unique_ptr<chromeos::onc::OncParsedCertificates>
+          expected_onc_certificates) {
+    expected_onc_certificates_ = std::move(expected_onc_certificates);
   }
 
   void SetExpectedONCSource(::onc::ONCSource source) {
@@ -135,23 +138,29 @@
     return count;
   }
 
-  void ImportCertificates(const base::ListValue& certificates,
-                          ::onc::ONCSource source,
-                          const DoneCallback& done_callback) override {
+  void ImportCertificates(
+      std::unique_ptr<chromeos::onc::OncParsedCertificates> certificates,
+      ::onc::ONCSource source,
+      DoneCallback done_callback) override {
     if (expected_onc_source_ != ::onc::ONC_SOURCE_UNKNOWN)
       EXPECT_EQ(expected_onc_source_, source);
     if (expected_onc_certificates_) {
-      EXPECT_TRUE(chromeos::onc::test_utils::Equals(
-          expected_onc_certificates_.get(), &certificates));
+      EXPECT_EQ(expected_onc_certificates_->has_error(),
+                certificates->has_error());
+      EXPECT_EQ(expected_onc_certificates_->server_or_authority_certificates(),
+                certificates->server_or_authority_certificates());
+      EXPECT_EQ(expected_onc_certificates_->client_certificates(),
+                certificates->client_certificates());
     }
+
     ++call_count_;
-    done_callback.Run(true, net::x509_util::DupCERTCertificateList(
-                                onc_trusted_certificates_));
+    std::move(done_callback).Run(true, std::move(onc_trusted_certificates_));
   }
 
  private:
   ::onc::ONCSource expected_onc_source_;
-  std::unique_ptr<base::ListValue> expected_onc_certificates_;
+  std::unique_ptr<chromeos::onc::OncParsedCertificates>
+      expected_onc_certificates_;
   net::ScopedCERTCertificateList onc_trusted_certificates_;
   unsigned int call_count_;
 
@@ -173,7 +182,7 @@
     "  },"
     "  \"Certificates\": ["
     "    { \"GUID\": \"{f998f760-272b-6939-4c2beffe428697ac}\","
-    "      \"PKCS12\": \"abc\","
+    "      \"PKCS12\": \"YWJj\","
     "      \"Type\": \"Client\" }"
     "  ],"
     "  \"Type\": \"UnencryptedConfiguration\""
@@ -238,7 +247,8 @@
     base::ListValue* certs = NULL;
     fake_toplevel_onc->GetListWithoutPathExpansion(
         onc::toplevel_config::kCertificates, &certs);
-    AppendAll(*certs, &fake_certificates_);
+    fake_certificates_ =
+        std::make_unique<chromeos::onc::OncParsedCertificates>(*certs);
 
     certificate_importer_ = new FakeCertificateImporter;
     certificate_importer_owned_.reset(certificate_importer_);
@@ -297,7 +307,7 @@
 
   base::ListValue fake_network_configs_;
   base::DictionaryValue fake_global_network_config_;
-  base::ListValue fake_certificates_;
+  std::unique_ptr<chromeos::onc::OncParsedCertificates> fake_certificates_;
   StrictMock<chromeos::MockManagedNetworkConfigurationHandler>
       network_config_handler_;
   FakeNetworkDeviceHandler network_device_handler_;
@@ -515,7 +525,8 @@
   Mock::VerifyAndClearExpectations(&network_config_handler_);
   EXPECT_EQ(0u, certificate_importer_->GetAndResetImportCount());
 
-  certificate_importer_->SetExpectedONCCertificates(fake_certificates_);
+  certificate_importer_->SetExpectedONCCertificates(
+      std::move(fake_certificates_));
   certificate_importer_->SetExpectedONCSource(onc::ONC_SOURCE_USER_POLICY);
 
   ASSERT_TRUE(certificate_importer_owned_);
@@ -573,7 +584,8 @@
                         ExpectedUsernameHash(),
                         IsEqualTo(&fake_network_configs_),
                         IsEqualTo(&fake_global_network_config_)));
-  certificate_importer_->SetExpectedONCCertificates(fake_certificates_);
+  certificate_importer_->SetExpectedONCCertificates(
+      std::move(fake_certificates_));
   certificate_importer_->SetExpectedONCSource(CurrentONCSource());
 
   CreateNetworkConfigurationUpdater();
@@ -601,7 +613,8 @@
                         IsEqualTo(&fake_network_configs_),
                         IsEqualTo(&fake_global_network_config_)));
   certificate_importer_->SetExpectedONCSource(CurrentONCSource());
-  certificate_importer_->SetExpectedONCCertificates(fake_certificates_);
+  certificate_importer_->SetExpectedONCCertificates(
+      std::move(fake_certificates_));
 
   MarkPolicyProviderInitialized();
   EXPECT_EQ(ExpectedImportCertificatesCallCount(),
@@ -624,7 +637,8 @@
                         IsEqualTo(&fake_network_configs_),
                         IsEqualTo(&fake_global_network_config_)));
   certificate_importer_->SetExpectedONCSource(CurrentONCSource());
-  certificate_importer_->SetExpectedONCCertificates(fake_certificates_);
+  certificate_importer_->SetExpectedONCCertificates(
+      std::move(fake_certificates_));
 
   CreateNetworkConfigurationUpdater();
 
@@ -650,7 +664,8 @@
                         IsEqualTo(&fake_network_configs_),
                         IsEqualTo(&fake_global_network_config_)));
   certificate_importer_->SetExpectedONCSource(CurrentONCSource());
-  certificate_importer_->SetExpectedONCCertificates(fake_certificates_);
+  certificate_importer_->SetExpectedONCCertificates(
+      std::move(fake_certificates_));
 
   PolicyMap policy;
   policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
@@ -664,7 +679,9 @@
   // Another update is expected if the policy goes away.
   EXPECT_CALL(network_config_handler_,
               SetPolicy(CurrentONCSource(), _, IsEmpty(), IsEmpty()));
-  certificate_importer_->SetExpectedONCCertificates(base::ListValue());
+  certificate_importer_->SetExpectedONCCertificates(
+      std::make_unique<chromeos::onc::OncParsedCertificates>(
+          base::ListValue()));
 
   policy.Erase(GetParam());
   UpdateProviderPolicy(policy);
diff --git a/chrome/browser/chromeos/policy/user_network_configuration_updater.cc b/chrome/browser/chromeos/policy/user_network_configuration_updater.cc
index a26486e..708bc915c 100644
--- a/chrome/browser/chromeos/policy/user_network_configuration_updater.cc
+++ b/chrome/browser/chromeos/policy/user_network_configuration_updater.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chromeos/network/managed_network_configuration_handler.h"
 #include "chromeos/network/onc/onc_certificate_importer_impl.h"
+#include "chromeos/network/onc/onc_parsed_certificates.h"
 #include "chromeos/network/onc/onc_utils.h"
 #include "components/policy/policy_constants.h"
 #include "components/user_manager/user.h"
@@ -109,7 +110,7 @@
   }
 
   certificate_importer_->ImportCertificates(
-      certificates_onc,
+      std::make_unique<chromeos::onc::OncParsedCertificates>(certificates_onc),
       onc_source_,
       base::Bind(&UserNetworkConfigurationUpdater::OnCertificatesImported,
                  base::Unretained(this)));
diff --git a/chrome/browser/chromeos/system/automatic_reboot_manager_unittest.cc b/chrome/browser/chromeos/system/automatic_reboot_manager_unittest.cc
index 5f21f1ca..1cfa7c6 100644
--- a/chrome/browser/chromeos/system/automatic_reboot_manager_unittest.cc
+++ b/chrome/browser/chromeos/system/automatic_reboot_manager_unittest.cc
@@ -39,7 +39,6 @@
 #include "content/public/browser/notification_source.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/message_center/message_center.h"
 
 using ::testing::_;
 using ::testing::Invoke;
diff --git a/chrome/browser/chromeos/ui/low_disk_notification.cc b/chrome/browser/chromeos/ui/low_disk_notification.cc
index f55ad65e..a11ac7d 100644
--- a/chrome/browser/chromeos/ui/low_disk_notification.cc
+++ b/chrome/browser/chromeos/ui/low_disk_notification.cc
@@ -12,7 +12,7 @@
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
-#include "chrome/browser/notifications/notification_display_service.h"
+#include "chrome/browser/notifications/system_notification_helper.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/grit/generated_resources.h"
@@ -68,8 +68,8 @@
   if (severity != last_notification_severity_ ||
       (severity == HIGH &&
        now - last_notification_time_ > notification_interval_)) {
-    NotificationDisplayService::GetForSystemNotifications()->Display(
-        NotificationHandler::Type::TRANSIENT, *CreateNotification(severity));
+    SystemNotificationHelper::GetInstance()->Display(
+        *CreateNotification(severity));
     last_notification_time_ = now;
     last_notification_severity_ = severity;
   }
diff --git a/chrome/browser/conflicts/installed_programs_win.h b/chrome/browser/conflicts/installed_programs_win.h
index 667be10..e98fa03 100644
--- a/chrome/browser/conflicts/installed_programs_win.h
+++ b/chrome/browser/conflicts/installed_programs_win.h
@@ -98,9 +98,14 @@
 
   // Given a |file|, checks if it matches an installed program on the user's
   // machine and appends all the matching programs to |programs|. Do not call
-  // this before the initialization is done.
-  bool GetInstalledPrograms(const base::FilePath& file,
-                            std::vector<ProgramInfo>* programs) const;
+  // this before initialization completes.
+  // Virtual to allow mocking.
+  virtual bool GetInstalledPrograms(const base::FilePath& file,
+                                    std::vector<ProgramInfo>* programs) const;
+
+  // Returns true if this instance is initialized and GetInstalledPrograms() can
+  // be called.
+  bool initialized() const { return initialized_; }
 
  protected:
   // Protected so that tests can subclass InstalledPrograms and access it.
diff --git a/chrome/browser/conflicts/module_database_win.cc b/chrome/browser/conflicts/module_database_win.cc
index 539d06fe..2f7811b 100644
--- a/chrome/browser/conflicts/module_database_win.cc
+++ b/chrome/browser/conflicts/module_database_win.cc
@@ -11,6 +11,8 @@
 #include "base/files/file_path.h"
 #include "base/location.h"
 #include "chrome/browser/conflicts/module_database_observer_win.h"
+#include "chrome/browser/conflicts/problematic_programs_updater_win.h"
+#include "chrome/browser/conflicts/third_party_metrics_recorder_win.h"
 
 namespace {
 
@@ -32,23 +34,20 @@
 ModuleDatabase::ModuleDatabase(
     scoped_refptr<base::SequencedTaskRunner> task_runner)
     : task_runner_(task_runner),
+      idle_timer_(
+          FROM_HERE,
+          kIdleTimeout,
+          base::Bind(&ModuleDatabase::OnDelayExpired, base::Unretained(this)),
+          false),
+      has_started_processing_(false),
       shell_extensions_enumerated_(false),
       ime_enumerated_(false),
       // ModuleDatabase owns |module_inspector_|, so it is safe to use
       // base::Unretained().
       module_inspector_(base::Bind(&ModuleDatabase::OnModuleInspected,
                                    base::Unretained(this))),
-      module_list_manager_(std::move(task_runner)),
-      third_party_metrics_(this),
-      has_started_processing_(false),
-      idle_timer_(
-          FROM_HERE,
-          kIdleTimeout,
-          base::Bind(&ModuleDatabase::OnDelayExpired, base::Unretained(this)),
-          false),
-      weak_ptr_factory_(this) {
-  // TODO(pmonette): Wire up the module list manager observer.
-}
+      module_list_manager_(task_runner),
+      weak_ptr_factory_(this) {}
 
 ModuleDatabase::~ModuleDatabase() {
   if (this == g_module_database_win_instance)
@@ -240,6 +239,14 @@
 }
 
 void ModuleDatabase::EnterIdleState() {
+  if (!installed_programs_.initialized()) {
+    // ModuleDatabase owns |installed_programs_|, so it is safe to use
+    // base::Unretained().
+    installed_programs_.Initialize(
+        base::BindOnce(&ModuleDatabase::OnInstalledProgramsInitialized,
+                       base::Unretained(this)));
+  }
+
   for (auto& observer : observer_list_)
     observer.OnModuleDatabaseIdle();
 }
@@ -250,3 +257,14 @@
       observer->OnNewModuleFound(module.first, module.second);
   }
 }
+
+void ModuleDatabase::OnInstalledProgramsInitialized() {
+  third_party_metrics_ =
+      std::make_unique<ThirdPartyMetricsRecorder>(installed_programs_);
+  AddObserver(third_party_metrics_.get());
+
+  problematic_programs_updater_ =
+      ProblematicProgramsUpdater::MaybeCreate(installed_programs_);
+  if (problematic_programs_updater_)
+    AddObserver(problematic_programs_updater_.get());
+}
diff --git a/chrome/browser/conflicts/module_database_win.h b/chrome/browser/conflicts/module_database_win.h
index 5c9ac811..2013824f 100644
--- a/chrome/browser/conflicts/module_database_win.h
+++ b/chrome/browser/conflicts/module_database_win.h
@@ -14,13 +14,15 @@
 #include "base/sequenced_task_runner.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
+#include "chrome/browser/conflicts/installed_programs_win.h"
 #include "chrome/browser/conflicts/module_info_win.h"
 #include "chrome/browser/conflicts/module_inspector_win.h"
 #include "chrome/browser/conflicts/module_list_manager_win.h"
-#include "chrome/browser/conflicts/third_party_metrics_recorder_win.h"
 #include "content/public/common/process_type.h"
 
 class ModuleDatabaseObserver;
+class ProblematicProgramsUpdater;
+class ThirdPartyMetricsRecorder;
 
 namespace base {
 class FilePath;
@@ -28,6 +30,10 @@
 
 // A class that keeps track of all modules loaded across Chrome processes.
 //
+// It is also the main class behind third-party modules tracking, and owns the
+// different classes that required to identify problematic programs and
+// record metrics.
+//
 // This is effectively a singleton, but doesn't use base::Singleton. The intent
 // is for the object to be created when Chrome is single-threaded, and for it
 // be set as the process-wide singleton via SetInstance.
@@ -158,12 +164,20 @@
   // OnNewModuleFound().
   void NotifyLoadedModules(ModuleDatabaseObserver* observer);
 
+  // Called when |installed_programs_| finishes its initialization.
+  void OnInstalledProgramsInitialized();
+
   // The task runner to which this object is bound.
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
   // A map of all known modules.
   ModuleMap modules_;
 
+  base::Timer idle_timer_;
+
+  // Indicates if the ModuleDatabase has started processing module load events.
+  bool has_started_processing_;
+
   // Indicates if all shell extensions have been enumerated.
   bool shell_extensions_enumerated_;
 
@@ -173,17 +187,21 @@
   // Inspects new modules on a blocking task runner.
   ModuleInspector module_inspector_;
 
+  // Holds observers.
+  base::ObserverList<ModuleDatabaseObserver> observer_list_;
+
   // Keeps track of where the most recent module list is located on disk, and
   // provides notifications when this changes.
   ModuleListManager module_list_manager_;
-  base::ObserverList<ModuleDatabaseObserver> observer_list_;
 
-  ThirdPartyMetricsRecorder third_party_metrics_;
+  // Retrieves the list of installed programs.
+  InstalledPrograms installed_programs_;
 
-  // Indicates if the ModuleDatabase has started processing module load events.
-  bool has_started_processing_;
+  // Records metrics on third-party modules.
+  std::unique_ptr<ThirdPartyMetricsRecorder> third_party_metrics_;
 
-  base::Timer idle_timer_;
+  // Maintains the cache of problematic programs.
+  std::unique_ptr<ProblematicProgramsUpdater> problematic_programs_updater_;
 
   // Weak pointer factory for this object. This is used when bouncing
   // incoming events to |task_runner_|.
diff --git a/chrome/browser/conflicts/module_database_win_unittest.cc b/chrome/browser/conflicts/module_database_win_unittest.cc
index f390579d..6ec3bc4 100644
--- a/chrome/browser/conflicts/module_database_win_unittest.cc
+++ b/chrome/browser/conflicts/module_database_win_unittest.cc
@@ -13,10 +13,12 @@
 #include "base/task_scheduler/post_task.h"
 #include "base/task_scheduler/task_scheduler.h"
 #include "base/test/scoped_mock_time_message_loop_task_runner.h"
-#include "base/test/scoped_task_environment.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/time/time.h"
 #include "chrome/browser/conflicts/module_database_observer_win.h"
+#include "chrome/test/base/scoped_testing_local_state.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -43,6 +45,7 @@
   ModuleDatabaseTest()
       : dll1_(kDll1),
         dll2_(kDll2),
+        scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()),
         module_database_(base::SequencedTaskRunnerHandle::Get()) {}
 
   const ModuleDatabase::ModuleMap& modules() {
@@ -56,7 +59,6 @@
   }
 
   void RunSchedulerUntilIdle() {
-    // Call ScopedTaskEnvironment::RunUntilIdle() when it supports mocking time.
     base::TaskScheduler::GetInstance()->FlushForTesting();
     mock_time_task_runner_->RunUntilIdle();
   }
@@ -71,10 +73,12 @@
 
  private:
   // Must be before |module_database_|.
-  base::test::ScopedTaskEnvironment scoped_task_environment_;
+  content::TestBrowserThreadBundle test_browser_thread_bundle_;
 
   base::ScopedMockTimeMessageLoopTaskRunner mock_time_task_runner_;
 
+  ScopedTestingLocalState scoped_testing_local_state_;
+
   ModuleDatabase module_database_;
 
   DISALLOW_COPY_AND_ASSIGN(ModuleDatabaseTest);
diff --git a/chrome/browser/conflicts/module_info_win.cc b/chrome/browser/conflicts/module_info_win.cc
index fa2432d..4ff7f47e 100644
--- a/chrome/browser/conflicts/module_info_win.cc
+++ b/chrome/browser/conflicts/module_info_win.cc
@@ -86,6 +86,8 @@
 
 ModuleInfoData::~ModuleInfoData() = default;
 
+ModuleInfoData::ModuleInfoData(ModuleInfoData&& module_data) noexcept = default;
+
 // -----------------------------------------------------------------------------
 
 std::unique_ptr<ModuleInspectionResult> InspectModule(
diff --git a/chrome/browser/conflicts/module_info_win.h b/chrome/browser/conflicts/module_info_win.h
index 779c0a5..39bc0f8 100644
--- a/chrome/browser/conflicts/module_info_win.h
+++ b/chrome/browser/conflicts/module_info_win.h
@@ -91,6 +91,8 @@
   ModuleInfoData();
   ~ModuleInfoData();
 
+  ModuleInfoData(ModuleInfoData&& module_data) noexcept;
+
   // Set of all process types in which this module has been seen (may not be
   // currently present in a process of that type). This is a conversion of
   // ProcessType enumeration to a bitfield. See "ProcessTypeToBit" and
diff --git a/chrome/browser/conflicts/module_inspector_win.cc b/chrome/browser/conflicts/module_inspector_win.cc
index 6f73e73..ebc3541 100644
--- a/chrome/browser/conflicts/module_inspector_win.cc
+++ b/chrome/browser/conflicts/module_inspector_win.cc
@@ -71,6 +71,8 @@
 void ModuleInspector::OnInspectionFinished(
     const ModuleInfoKey& module_key,
     std::unique_ptr<ModuleInspectionResult> inspection_result) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
   // Pop first, because the callback may want to know if there is any work left
   // to be done, which is caracterized by a non-empty queue.
   queue_.pop();
diff --git a/chrome/browser/conflicts/problematic_programs_updater_win.cc b/chrome/browser/conflicts/problematic_programs_updater_win.cc
new file mode 100644
index 0000000..8915271
--- /dev/null
+++ b/chrome/browser/conflicts/problematic_programs_updater_win.cc
@@ -0,0 +1,218 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/conflicts/problematic_programs_updater_win.h"
+
+#include <algorithm>
+#include <iterator>
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/win/registry.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/conflicts/module_database_win.h"
+#include "chrome/browser/conflicts/third_party_metrics_recorder_win.h"
+#include "chrome/common/pref_names.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/scoped_user_pref_update.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace {
+
+// Converts a json dictionary of programs to a vector of ProgramInfos.
+std::vector<InstalledPrograms::ProgramInfo> ConvertToProgramInfoVector(
+    const base::Value& programs) {
+  std::vector<InstalledPrograms::ProgramInfo> result;
+
+  for (const auto& element : programs.DictItems()) {
+    const std::string& name = element.first;
+    const base::Value& value = element.second;
+
+    if (!value.is_dict())
+      continue;
+
+    const base::Value* registry_is_hkcu_value =
+        value.FindKeyOfType("registry_is_hkcu", base::Value::Type::BOOLEAN);
+    const base::Value* registry_key_path_value =
+        value.FindKeyOfType("registry_key_path", base::Value::Type::STRING);
+    const base::Value* registry_wow64_access_value = value.FindKeyOfType(
+        "registry_wow64_access", base::Value::Type::INTEGER);
+
+    // If any is missing, skip this element.
+    if (!registry_is_hkcu_value || !registry_key_path_value ||
+        !registry_wow64_access_value) {
+      continue;
+    }
+
+    result.emplace_back(base::UTF8ToUTF16(name),
+                        registry_is_hkcu_value->GetBool() ? HKEY_CURRENT_USER
+                                                          : HKEY_LOCAL_MACHINE,
+                        base::UTF8ToUTF16(registry_key_path_value->GetString()),
+                        registry_wow64_access_value->GetInt());
+  }
+
+  return result;
+}
+
+// Serializes a vector of ProgramInfos to a json dictionary.
+base::Value ConvertToDictionary(
+    const std::vector<InstalledPrograms::ProgramInfo>& programs) {
+  base::Value result(base::Value::Type::DICTIONARY);
+
+  for (const InstalledPrograms::ProgramInfo& program : programs) {
+    base::Value element(base::Value::Type::DICTIONARY);
+
+    element.SetKey("registry_is_hkcu",
+                   base::Value(program.registry_root == HKEY_CURRENT_USER));
+    element.SetKey("registry_key_path", base::Value(program.registry_key_path));
+    element.SetKey(
+        "registry_wow64_access",
+        base::Value(static_cast<int>(program.registry_wow64_access)));
+
+    result.SetKey(base::UTF16ToUTF8(program.name), std::move(element));
+  }
+
+  return result;
+}
+
+}  // namespace
+
+const base::Feature kThirdPartyConflictsWarning{
+    "ThirdPartyConflictsWarning", base::FEATURE_ENABLED_BY_DEFAULT};
+
+ProblematicProgramsUpdater::~ProblematicProgramsUpdater() = default;
+
+// static
+void ProblematicProgramsUpdater::RegisterLocalStatePrefs(
+    PrefRegistrySimple* registry) {
+  registry->RegisterDictionaryPref(prefs::kProblematicPrograms);
+}
+
+// static
+std::unique_ptr<ProblematicProgramsUpdater>
+ProblematicProgramsUpdater::MaybeCreate(
+    const InstalledPrograms& installed_programs) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  std::unique_ptr<ProblematicProgramsUpdater> instance;
+
+  if (base::FeatureList::IsEnabled(kThirdPartyConflictsWarning))
+    instance.reset(new ProblematicProgramsUpdater(installed_programs));
+
+  return instance;
+}
+
+// static
+bool ProblematicProgramsUpdater::TrimCache() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  if (!base::FeatureList::IsEnabled(kThirdPartyConflictsWarning))
+    return false;
+
+  std::vector<InstalledPrograms::ProgramInfo> programs =
+      ConvertToProgramInfoVector(
+          *g_browser_process->local_state()
+               ->FindPreference(prefs::kProblematicPrograms)
+               ->GetValue());
+
+  // Remove entries that can no longer be found in the registry.
+  programs.erase(
+      std::remove_if(programs.begin(), programs.end(),
+                     [](const InstalledPrograms::ProgramInfo& element) {
+                       base::win::RegKey registry_key(
+                           element.registry_root,
+                           element.registry_key_path.c_str(),
+                           KEY_QUERY_VALUE | element.registry_wow64_access);
+                       return !registry_key.Valid();
+                     }),
+      programs.end());
+
+  // Write it back.
+  if (programs.empty()) {
+    g_browser_process->local_state()->ClearPref(prefs::kProblematicPrograms);
+  } else {
+    g_browser_process->local_state()->Set(prefs::kProblematicPrograms,
+                                          ConvertToDictionary(programs));
+  }
+  return !programs.empty();
+}
+
+// static
+bool ProblematicProgramsUpdater::HasCachedPrograms() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  if (!base::FeatureList::IsEnabled(kThirdPartyConflictsWarning))
+    return false;
+
+  return !g_browser_process->local_state()
+              ->GetDictionary(prefs::kProblematicPrograms)
+              ->empty();
+}
+
+// static
+base::Value ProblematicProgramsUpdater::GetCachedProgramNames() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  base::Value program_names(base::Value::Type::LIST);
+
+  if (base::FeatureList::IsEnabled(kThirdPartyConflictsWarning)) {
+    std::vector<InstalledPrograms::ProgramInfo> programs =
+        ConvertToProgramInfoVector(
+            *g_browser_process->local_state()
+                 ->FindPreference(prefs::kProblematicPrograms)
+                 ->GetValue());
+
+    for (const auto& program : programs)
+      // Only the name is returned.
+      program_names.GetList().push_back(base::Value(program.name));
+  }
+
+  return program_names;
+}
+
+void ProblematicProgramsUpdater::OnNewModuleFound(
+    const ModuleInfoKey& module_key,
+    const ModuleInfoData& module_data) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  // Only consider loaded modules.
+  if (module_data.module_types & ModuleInfoData::kTypeLoadedModule) {
+    installed_programs_.GetInstalledPrograms(module_key.module_path,
+                                             &programs_);
+  }
+}
+
+void ProblematicProgramsUpdater::OnModuleDatabaseIdle() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  // On the first call to OnModuleDatabaseIdle(), the previous value must always
+  // be overwritten.
+  if (before_first_idle_)
+    g_browser_process->local_state()->ClearPref(prefs::kProblematicPrograms);
+  before_first_idle_ = false;
+
+  // If there is no new problematic programs, there is nothing to do.
+  if (programs_.empty())
+    return;
+
+  // Converting the accumulated programs to a json dictionary takes care of
+  // eliminating duplicates.
+  base::Value new_programs = ConvertToDictionary(programs_);
+  programs_.clear();
+
+  // Update the existing dictionary.
+  DictionaryPrefUpdate update(g_browser_process->local_state(),
+                              prefs::kProblematicPrograms);
+  base::Value* existing_programs = update.Get();
+  for (auto&& element : new_programs.DictItems()) {
+    existing_programs->SetKey(std::move(element.first),
+                              std::move(element.second));
+  }
+}
+
+ProblematicProgramsUpdater::ProblematicProgramsUpdater(
+    const InstalledPrograms& installed_programs)
+    : installed_programs_(installed_programs) {}
diff --git a/chrome/browser/conflicts/problematic_programs_updater_win.h b/chrome/browser/conflicts/problematic_programs_updater_win.h
new file mode 100644
index 0000000..9529ea53
--- /dev/null
+++ b/chrome/browser/conflicts/problematic_programs_updater_win.h
@@ -0,0 +1,77 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CONFLICTS_PROBLEMATIC_PROGRAMS_UPDATER_WIN_H_
+#define CHROME_BROWSER_CONFLICTS_PROBLEMATIC_PROGRAMS_UPDATER_WIN_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/feature_list.h"
+#include "base/macros.h"
+#include "base/values.h"
+#include "chrome/browser/conflicts/installed_programs_win.h"
+#include "chrome/browser/conflicts/module_database_observer_win.h"
+
+class PrefRegistrySimple;
+
+// A feature that controls whether Chrome keeps track of problematic programs.
+extern const base::Feature kThirdPartyConflictsWarning;
+
+// Maintains a list of problematic programs that are installed on the machine.
+// These programs cause unwanted DLLs to be loaded into Chrome.
+//
+// Because the list is expensive to build, it is cached into the Local State
+// file so that it is available at startup, albeit somewhat out-of-date. To
+// remove stale elements from the list, use TrimCache().
+//
+// When kThirdPartyConflictsWarning is disabled, this class always behaves as-if
+// there are no problematic programs on the computer. This makes it safe to use
+// all of the class' static functions unconditionally.
+class ProblematicProgramsUpdater : public ModuleDatabaseObserver {
+ public:
+  ~ProblematicProgramsUpdater() override;
+
+  static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
+
+  // Creates an instance of the updater. Returns nullptr if the
+  // kThirdPartyConflictsWarning experiment is disabled.
+  //
+  // |installed_programs| must outlive the lifetime of this class.
+  static std::unique_ptr<ProblematicProgramsUpdater> MaybeCreate(
+      const InstalledPrograms& installed_programs);
+
+  // Removes stale programs from the cache. This can happen if a program was
+  // uninstalled between the time it was found and Chrome was relaunched.
+  // Returns true if any problematic programs are installed after trimming
+  // completes (i.e., HasCachedPrograms() would return true).
+  static bool TrimCache();
+
+  // Returns true if the cache contains at least one problematic program.
+  static bool HasCachedPrograms();
+
+  // Returns the names of all the cached problematic programs in a list Value.
+  static base::Value GetCachedProgramNames();
+
+  // ModuleDatabaseObserver:
+  void OnNewModuleFound(const ModuleInfoKey& module_key,
+                        const ModuleInfoData& module_data) override;
+  void OnModuleDatabaseIdle() override;
+
+ private:
+  explicit ProblematicProgramsUpdater(
+      const InstalledPrograms& installed_programs);
+
+  const InstalledPrograms& installed_programs_;
+
+  // Temporarily holds program names for modules that were recently found.
+  std::vector<InstalledPrograms::ProgramInfo> programs_;
+
+  // Becomes false on the first call to OnModuleDatabaseIdle.
+  bool before_first_idle_ = true;
+
+  DISALLOW_COPY_AND_ASSIGN(ProblematicProgramsUpdater);
+};
+
+#endif  // CHROME_BROWSER_CONFLICTS_PROBLEMATIC_PROGRAMS_UPDATER_WIN_H_
diff --git a/chrome/browser/conflicts/problematic_programs_updater_win_unittest.cc b/chrome/browser/conflicts/problematic_programs_updater_win_unittest.cc
new file mode 100644
index 0000000..91cfd78
--- /dev/null
+++ b/chrome/browser/conflicts/problematic_programs_updater_win_unittest.cc
@@ -0,0 +1,238 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/conflicts/problematic_programs_updater_win.h"
+
+#include <map>
+#include <utility>
+
+#include "base/logging.h"
+#include "base/strings/stringprintf.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/test_reg_util_win.h"
+#include "base/win/registry.h"
+#include "chrome/browser/conflicts/module_info_win.h"
+#include "chrome/test/base/scoped_testing_local_state.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class MockInstalledPrograms : public InstalledPrograms {
+ public:
+  MockInstalledPrograms() = default;
+
+  void AddInstalledProgram(const base::FilePath& file_path,
+                           InstalledPrograms::ProgramInfo program_info) {
+    programs_.insert({file_path, std::move(program_info)});
+  }
+
+  // Given a |file|, checks if it matches with an installed program on the
+  // user's machine and returns all the matching programs. Do not call this
+  // before the initialization is done.
+  // Virtual to allow mocking.
+  bool GetInstalledPrograms(const base::FilePath& file,
+                            std::vector<ProgramInfo>* programs) const override {
+    auto iter = programs_.find(file);
+    if (iter == programs_.end())
+      return false;
+
+    programs->push_back(iter->second);
+    return true;
+  }
+
+ private:
+  std::map<base::FilePath, ProgramInfo> programs_;
+
+  DISALLOW_COPY_AND_ASSIGN(MockInstalledPrograms);
+};
+
+constexpr wchar_t kDllPath1[] = L"c:\\path\\to\\module.dll";
+constexpr wchar_t kDllPath2[] = L"c:\\some\\shellextension.dll";
+
+}  // namespace
+
+class ProblematicProgramsUpdaterTest : public testing::Test {
+ protected:
+  ProblematicProgramsUpdaterTest()
+      : dll1_(kDllPath1),
+        dll2_(kDllPath2),
+        scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()) {}
+
+  void SetUp() override {
+    ASSERT_NO_FATAL_FAILURE(
+        registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER));
+    scoped_feature_list_.InitAndEnableFeature(kThirdPartyConflictsWarning);
+  }
+
+  enum class Option {
+    ADD_REGISTRY_ENTRY,
+    NO_REGISTRY_ENTRY,
+  };
+  void AddProblematicProgram(const base::FilePath& injected_module_path,
+                             const base::string16& program_name,
+                             Option option) {
+    static constexpr wchar_t kUninstallRegKeyFormat[] =
+        L"dummy\\uninstall\\%ls";
+
+    const base::string16 registry_key_path =
+        base::StringPrintf(kUninstallRegKeyFormat, program_name.c_str());
+
+    installed_programs_.AddInstalledProgram(
+        injected_module_path,
+        {program_name, HKEY_CURRENT_USER, registry_key_path, 0});
+
+    if (option == Option::ADD_REGISTRY_ENTRY) {
+      base::win::RegKey reg_key(HKEY_CURRENT_USER, registry_key_path.c_str(),
+                                KEY_CREATE_SUB_KEY);
+    }
+  }
+
+  MockInstalledPrograms& installed_programs() { return installed_programs_; }
+
+  const base::FilePath dll1_;
+  const base::FilePath dll2_;
+
+ private:
+  content::TestBrowserThreadBundle test_browser_thread_bundle_;
+
+  base::test::ScopedFeatureList scoped_feature_list_;
+
+  ScopedTestingLocalState scoped_testing_local_state_;
+
+  registry_util::RegistryOverrideManager registry_override_manager_;
+
+  MockInstalledPrograms installed_programs_;
+
+  DISALLOW_COPY_AND_ASSIGN(ProblematicProgramsUpdaterTest);
+};
+
+// Returns a ModuleInfoData marked as loaded into the process but otherwise
+// empty.
+ModuleInfoData CreateLoadedModuleInfoData() {
+  ModuleInfoData module_data;
+
+  module_data.module_types |= ModuleInfoData::kTypeLoadedModule;
+
+  return module_data;
+}
+
+// Tests that when the Local State cache is empty, no problematic programs are
+// returned.
+TEST_F(ProblematicProgramsUpdaterTest, EmptyCache) {
+  EXPECT_FALSE(ProblematicProgramsUpdater::HasCachedPrograms());
+  EXPECT_TRUE(
+      ProblematicProgramsUpdater::GetCachedProgramNames().GetList().empty());
+}
+
+// ProblematicProgramsUpdater doesn't do anything when there is noregistered
+// installed programs.
+TEST_F(ProblematicProgramsUpdaterTest, NoProblematicPrograms) {
+  auto problematic_programs_updater =
+      ProblematicProgramsUpdater::MaybeCreate(installed_programs());
+
+  // Simulate some arbitrary module loading into the process.
+  problematic_programs_updater->OnNewModuleFound(ModuleInfoKey(dll1_, 0, 0, 0),
+                                                 CreateLoadedModuleInfoData());
+  problematic_programs_updater->OnModuleDatabaseIdle();
+
+  EXPECT_FALSE(ProblematicProgramsUpdater::HasCachedPrograms());
+  EXPECT_TRUE(
+      ProblematicProgramsUpdater::GetCachedProgramNames().GetList().empty());
+}
+
+TEST_F(ProblematicProgramsUpdaterTest, OneConflict) {
+  AddProblematicProgram(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY);
+
+  auto problematic_programs_updater =
+      ProblematicProgramsUpdater::MaybeCreate(installed_programs());
+
+  // Simulate the module loading into the process.
+  problematic_programs_updater->OnNewModuleFound(ModuleInfoKey(dll1_, 0, 0, 0),
+                                                 CreateLoadedModuleInfoData());
+  problematic_programs_updater->OnModuleDatabaseIdle();
+
+  EXPECT_TRUE(ProblematicProgramsUpdater::HasCachedPrograms());
+  base::Value program_names =
+      ProblematicProgramsUpdater::GetCachedProgramNames();
+  ASSERT_EQ(1u, program_names.GetList().size());
+  EXPECT_EQ("Foo", program_names.GetList()[0].GetString());
+}
+
+TEST_F(ProblematicProgramsUpdaterTest, MultipleCallsToOnModuleDatabaseIdle) {
+  AddProblematicProgram(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY);
+  AddProblematicProgram(dll2_, L"Bar", Option::ADD_REGISTRY_ENTRY);
+
+  auto problematic_programs_updater =
+      ProblematicProgramsUpdater::MaybeCreate(installed_programs());
+
+  // Simulate the module loading into the process.
+  problematic_programs_updater->OnNewModuleFound(ModuleInfoKey(dll1_, 0, 0, 0),
+                                                 CreateLoadedModuleInfoData());
+  problematic_programs_updater->OnModuleDatabaseIdle();
+
+  // Add an additional module.
+  problematic_programs_updater->OnNewModuleFound(ModuleInfoKey(dll2_, 0, 0, 0),
+                                                 CreateLoadedModuleInfoData());
+  problematic_programs_updater->OnModuleDatabaseIdle();
+
+  EXPECT_TRUE(ProblematicProgramsUpdater::HasCachedPrograms());
+  base::Value program_names =
+      ProblematicProgramsUpdater::GetCachedProgramNames();
+  ASSERT_EQ(2u, program_names.GetList().size());
+}
+
+// This is meant to test that cached problematic programs are persisted
+// through browser restarts, via the Local State file.
+//
+// Since this isn't really doable in a unit test, this test at least check that
+// the list isn't tied to the lifetime of the ProblematicProgramsUpdater
+// instance. It is assumed that the Local State file works as intended.
+TEST_F(ProblematicProgramsUpdaterTest, PersistsThroughRestarts) {
+  AddProblematicProgram(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY);
+
+  auto problematic_programs_updater =
+      ProblematicProgramsUpdater::MaybeCreate(installed_programs());
+
+  // Simulate the module loading into the process.
+  problematic_programs_updater->OnNewModuleFound(ModuleInfoKey(dll1_, 0, 0, 0),
+                                                 CreateLoadedModuleInfoData());
+  problematic_programs_updater->OnModuleDatabaseIdle();
+
+  EXPECT_TRUE(ProblematicProgramsUpdater::HasCachedPrograms());
+
+  // Delete the instance.
+  problematic_programs_updater = nullptr;
+
+  EXPECT_TRUE(ProblematicProgramsUpdater::HasCachedPrograms());
+}
+
+// Tests that TrimCache() removes programs that do not have a registry entry.
+TEST_F(ProblematicProgramsUpdaterTest, TrimCache) {
+  AddProblematicProgram(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY);
+  AddProblematicProgram(dll2_, L"Bar", Option::NO_REGISTRY_ENTRY);
+
+  auto problematic_programs_updater =
+      ProblematicProgramsUpdater::MaybeCreate(installed_programs());
+
+  // Simulate the modules loading into the process.
+  problematic_programs_updater->OnNewModuleFound(ModuleInfoKey(dll1_, 0, 0, 0),
+                                                 CreateLoadedModuleInfoData());
+  problematic_programs_updater->OnNewModuleFound(ModuleInfoKey(dll2_, 0, 0, 0),
+                                                 CreateLoadedModuleInfoData());
+  problematic_programs_updater->OnModuleDatabaseIdle();
+
+  EXPECT_TRUE(ProblematicProgramsUpdater::HasCachedPrograms());
+  EXPECT_EQ(
+      2u, ProblematicProgramsUpdater::GetCachedProgramNames().GetList().size());
+
+  ProblematicProgramsUpdater::TrimCache();
+
+  EXPECT_TRUE(ProblematicProgramsUpdater::HasCachedPrograms());
+  base::Value program_names =
+      ProblematicProgramsUpdater::GetCachedProgramNames();
+  ASSERT_EQ(1u, program_names.GetList().size());
+  EXPECT_EQ("Foo", program_names.GetList()[0].GetString());
+}
diff --git a/chrome/browser/conflicts/third_party_metrics_recorder_win.cc b/chrome/browser/conflicts/third_party_metrics_recorder_win.cc
index 54b45fd..b7be7d9 100644
--- a/chrome/browser/conflicts/third_party_metrics_recorder_win.cc
+++ b/chrome/browser/conflicts/third_party_metrics_recorder_win.cc
@@ -11,7 +11,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_util.h"
-#include "chrome/browser/conflicts/module_database_win.h"
+#include "chrome/browser/conflicts/installed_programs_win.h"
 #include "chrome/browser/conflicts/module_info_win.h"
 
 namespace {
@@ -40,14 +40,8 @@
 }  // namespace
 
 ThirdPartyMetricsRecorder::ThirdPartyMetricsRecorder(
-    ModuleDatabase* module_database) {
-  // base::Unretained() is safe here because ThirdPartyMetricsRecorder owns
-  // |installed_programs_| and the callback won't be invoked if this instance is
-  // destroyed.
-  installed_programs_.Initialize(
-      base::BindOnce(&ThirdPartyMetricsRecorder::OnInstalledProgramsInitialized,
-                     base::Unretained(this), module_database));
-}
+    const InstalledPrograms& installed_programs)
+    : installed_programs_(installed_programs) {}
 
 ThirdPartyMetricsRecorder::~ThirdPartyMetricsRecorder() = default;
 
@@ -107,8 +101,3 @@
   base::UmaHistogramCustomCounts("ThirdPartyModules.Modules.Total",
                                  module_count_, 1, 500, 50);
 }
-
-void ThirdPartyMetricsRecorder::OnInstalledProgramsInitialized(
-    ModuleDatabase* module_database) {
-  module_database->AddObserver(this);
-}
diff --git a/chrome/browser/conflicts/third_party_metrics_recorder_win.h b/chrome/browser/conflicts/third_party_metrics_recorder_win.h
index e438b6e8..6ddceb2 100644
--- a/chrome/browser/conflicts/third_party_metrics_recorder_win.h
+++ b/chrome/browser/conflicts/third_party_metrics_recorder_win.h
@@ -6,17 +6,18 @@
 #define CHROME_BROWSER_CONFLICTS_THIRD_PARTY_METRICS_RECORDER_WIN_H_
 
 #include "base/macros.h"
-#include "chrome/browser/conflicts/installed_programs_win.h"
 #include "chrome/browser/conflicts/module_database_observer_win.h"
 
-class ModuleDatabase;
+class InstalledPrograms;
 struct ModuleInfoData;
 struct ModuleInfoKey;
 
 // Records metrics about third party modules loaded into Chrome.
 class ThirdPartyMetricsRecorder : public ModuleDatabaseObserver {
  public:
-  explicit ThirdPartyMetricsRecorder(ModuleDatabase* module_database);
+  // |installed_programs| must outlive |this|.
+  explicit ThirdPartyMetricsRecorder(
+      const InstalledPrograms& installed_programs);
   ~ThirdPartyMetricsRecorder() override;
 
   // ModuleDatabaseObserver:
@@ -25,9 +26,7 @@
   void OnModuleDatabaseIdle() override;
 
  private:
-  void OnInstalledProgramsInitialized(ModuleDatabase* module_database);
-
-  InstalledPrograms installed_programs_;
+  const InstalledPrograms& installed_programs_;
 
   // Flag used to avoid sending module counts multiple times.
   bool metrics_emitted_ = false;
diff --git a/chrome/browser/domain_reliability/service_factory.cc b/chrome/browser/domain_reliability/service_factory.cc
index 0aafe7c..ba9957c 100644
--- a/chrome/browser/domain_reliability/service_factory.cc
+++ b/chrome/browser/domain_reliability/service_factory.cc
@@ -7,7 +7,6 @@
 #include "base/command_line.h"
 #include "base/metrics/field_trial.h"
 #include "build/build_config.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 #include "chrome/common/chrome_switches.h"
 #include "components/domain_reliability/service.h"
@@ -70,8 +69,7 @@
     return false;
   if (command_line->HasSwitch(switches::kEnableDomainReliability))
     return true;
-  if (!ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-          g_browser_process->local_state()))
+  if (!ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled())
     return false;
   if (base::FieldTrialList::TrialExists(kFieldTrialName)) {
     std::string value = base::FieldTrialList::FindFullName(kFieldTrialName);
diff --git a/chrome/browser/extensions/api/autotest_private/DEPS b/chrome/browser/extensions/api/autotest_private/DEPS
new file mode 100644
index 0000000..b21e182
--- /dev/null
+++ b/chrome/browser/extensions/api/autotest_private/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+ui/message_center",
+]
diff --git a/chrome/browser/extensions/api/autotest_private/autotest_private_api.cc b/chrome/browser/extensions/api/autotest_private/autotest_private_api.cc
index be46ff52..033ce0f 100644
--- a/chrome/browser/extensions/api/autotest_private/autotest_private_api.cc
+++ b/chrome/browser/extensions/api/autotest_private/autotest_private_api.cc
@@ -396,6 +396,10 @@
   DVLOG(1) << "AutotestPrivateGetVisibleNotificationsFunction";
   std::unique_ptr<base::ListValue> values(new base::ListValue);
 #if defined(OS_CHROMEOS)
+  // TODO(estade): we can't rely on the message center being available in the
+  // browser process (in --mash). Make autotests that use it fail loudly. See
+  // crbug.com/804570
+  CHECK(message_center::MessageCenter::Get());
   for (auto* notification :
        message_center::MessageCenter::Get()->GetVisibleNotifications()) {
     auto result = std::make_unique<base::DictionaryValue>();
diff --git a/chrome/browser/extensions/api/metrics_private/chrome_metrics_private_delegate.cc b/chrome/browser/extensions/api/metrics_private/chrome_metrics_private_delegate.cc
index a919810..9771932b 100644
--- a/chrome/browser/extensions/api/metrics_private/chrome_metrics_private_delegate.cc
+++ b/chrome/browser/extensions/api/metrics_private/chrome_metrics_private_delegate.cc
@@ -4,14 +4,12 @@
 
 #include "chrome/browser/extensions/api/metrics_private/chrome_metrics_private_delegate.h"
 
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 
 namespace extensions {
 
 bool ChromeMetricsPrivateDelegate::IsCrashReportingEnabled() {
-  return ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-      g_browser_process->local_state());
+  return ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled();
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_api.cc b/chrome/browser/extensions/api/terminal/terminal_private_api.cc
index ee44ebf..a16bdea 100644
--- a/chrome/browser/extensions/api/terminal/terminal_private_api.cc
+++ b/chrome/browser/extensions/api/terminal/terminal_private_api.cc
@@ -25,6 +25,7 @@
 #include "extensions/browser/app_window/app_window.h"
 #include "extensions/browser/app_window/app_window_registry.h"
 #include "extensions/browser/event_router.h"
+#include "extensions/browser/extensions_browser_client.h"
 
 namespace terminal_private = extensions::api::terminal_private;
 namespace OnTerminalResize =
@@ -123,6 +124,10 @@
   if (command_.empty())
     return RespondNow(Error("Invalid process name."));
 
+  const std::string user_id_hash =
+      ExtensionsBrowserClient::Get()->GetUserIdHashFromContext(
+          browser_context());
+
   content::WebContents* caller_contents = GetSenderWebContents();
   if (!caller_contents)
     return RespondNow(Error("No web contents."));
@@ -151,19 +156,22 @@
                      tab_id),
           base::Bind(
               &TerminalPrivateOpenTerminalProcessFunction::RespondOnUIThread,
-              this)));
+              this),
+          user_id_hash));
   return RespondLater();
 }
 
 void TerminalPrivateOpenTerminalProcessFunction::OpenOnRegistryTaskRunner(
     const ProcessOutputCallback& output_callback,
-    const OpenProcessCallback& callback) {
+    const OpenProcessCallback& callback,
+    const std::string& user_id_hash) {
   DCHECK(!command_.empty());
 
   chromeos::ProcessProxyRegistry* registry =
       chromeos::ProcessProxyRegistry::Get();
 
-  int terminal_id = registry->OpenProcess(command_.c_str(), output_callback);
+  int terminal_id =
+      registry->OpenProcess(command_.c_str(), user_id_hash, output_callback);
 
   content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
                                    base::BindOnce(callback, terminal_id));
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_api.h b/chrome/browser/extensions/api/terminal/terminal_private_api.h
index c6455784..5990901 100644
--- a/chrome/browser/extensions/api/terminal/terminal_private_api.h
+++ b/chrome/browser/extensions/api/terminal/terminal_private_api.h
@@ -33,7 +33,8 @@
   using OpenProcessCallback = base::Callback<void(int terminal_id)>;
 
   void OpenOnRegistryTaskRunner(const ProcessOutputCallback& output_callback,
-                                const OpenProcessCallback& callback);
+                                const OpenProcessCallback& callback,
+                                const std::string& user_id_hash);
   void RespondOnUIThread(int terminal_id);
 
   std::string command_;
diff --git a/chrome/browser/extensions/extension_storage_monitor.cc b/chrome/browser/extensions/extension_storage_monitor.cc
index 723012b..7721573 100644
--- a/chrome/browser/extensions/extension_storage_monitor.cc
+++ b/chrome/browser/extensions/extension_storage_monitor.cc
@@ -39,9 +39,9 @@
 #include "storage/browser/quota/storage_observer.h"
 #include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/message_center/public/cpp/message_center_constants.h"
 #include "ui/message_center/public/cpp/notification.h"
 #include "ui/message_center/public/cpp/notifier_id.h"
-#include "ui/message_center/views/constants.h"
 
 using content::BrowserThread;
 
diff --git a/chrome/browser/first_run/first_run_internal_posix.cc b/chrome/browser/first_run/first_run_internal_posix.cc
index 01aaa0532..3af5f979 100644
--- a/chrome/browser/first_run/first_run_internal_posix.cc
+++ b/chrome/browser/first_run/first_run_internal_posix.cc
@@ -63,7 +63,7 @@
   // in enterprise scenarios. If that is the case, skip the dialog entirely, as
   // it's not worth bothering the user for only the default browser question
   // (which is likely to be forced in enterprise deployments anyway).
-  if (IsMetricsReportingPolicyManaged(g_browser_process->local_state()))
+  if (IsMetricsReportingPolicyManaged())
     return false;
 
   // For real first runs, Mac and Desktop Linux initialize the default metrics
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 8852e8bb..040de0b 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1146,6 +1146,12 @@
 const char kPinchScaleDescription[] =
     "Enables experimental support for scale using pinch.";
 
+const char kPreviewsAllowedName[] = "Previews Allowed";
+const char kPreviewsAllowedDescription[] =
+    "Allows previews to be shown subject to specific preview types being "
+    "enabled and the client experiencing specific triggering conditions. "
+    "May be used as a kill-switch to turn off all potential preview types.";
+
 const char kPrintPdfAsImageName[] = "Print Pdf as Image";
 const char kPrintPdfAsImageDescription[] =
     "If enabled, an option to print PDF files as images will be available in "
@@ -1743,10 +1749,9 @@
     "Enables downloading pages in the background in case page is not yet "
     "loaded in current tab.";
 
-const char kChromeHomeName[] = "Chrome Home";
-const char kChromeHomeDescription[] =
-    "Enables Chrome Home on Android. You must restart the browser"
-    " twice for changes to take effect.";
+const char kChromeDuplexName[] = "Chrome Duplex";
+const char kChromeDuplexDescription[] =
+    "Enables Chrome Duplex, split toolbar Chrome Home, on Android.";
 
 const char kChromeHomeBottomNavLabelsName[] =
     "Chrome Home bottom navigation menu item labels.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index bbb4f28..796f0ea 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -716,6 +716,9 @@
 extern const char kPinchScaleName[];
 extern const char kPinchScaleDescription[];
 
+extern const char kPreviewsAllowedName[];
+extern const char kPreviewsAllowedDescription[];
+
 extern const char kPrintPdfAsImageName[];
 extern const char kPrintPdfAsImageDescription[];
 
@@ -1070,6 +1073,9 @@
 extern const char kBackgroundLoaderForDownloadsName[];
 extern const char kBackgroundLoaderForDownloadsDescription[];
 
+extern const char kChromeDuplexName[];
+extern const char kChromeDuplexDescription[];
+
 extern const char kChromeHomeBottomNavLabelsName[];
 extern const char kChromeHomeBottomNavLabelsDescription[];
 
@@ -1102,9 +1108,6 @@
 extern const char kChromeHomeSwipeLogicRestrictArea[];
 extern const char kChromeHomeSwipeLogicVelocity[];
 
-extern const char kChromeHomeName[];
-extern const char kChromeHomeDescription[];
-
 extern const char kChromeModernDesignName[];
 extern const char kChromeModernDesignDescription[];
 
diff --git a/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.cc b/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.cc
index bd85f3b..06af3fb 100644
--- a/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.cc
+++ b/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.cc
@@ -56,19 +56,7 @@
   ContextMenuDelegate* menu_delegate =
       ContextMenuDelegate::FromWebContents(guest_web_contents());
   DCHECK(menu_delegate);
-
-  content::ContextMenuParams new_params = params;
-  // The only case where |context_menu_position_| is not initialized is the case
-  // where the input event is directly sent to the guest WebContents without
-  // ever going throught the embedder and BrowserPlugin's
-  // RenderWidgetHostViewGuest. This only happens in some tests, e.g.,
-  // WebViewInteractiveTest.ContextMenuParamCoordinates.
-  if (context_menu_position_) {
-    new_params.x = context_menu_position_->x();
-    new_params.y = context_menu_position_->y();
-  }
-
-  pending_menu_ = menu_delegate->BuildMenu(guest_web_contents(), new_params);
+  pending_menu_ = menu_delegate->BuildMenu(guest_web_contents(), params);
   // It's possible for the returned menu to be null, so early out to avoid
   // a crash. TODO(wjmaclean): find out why it's possible for this to happen
   // in the first place, and if it's an error.
@@ -126,12 +114,4 @@
              chrome::kChromeUIChromeSigninURL;
 }
 
-void ChromeWebViewGuestDelegate::SetContextMenuPosition(
-    const gfx::Point& position) {
-  if (context_menu_position_ == nullptr)
-    context_menu_position_.reset(new gfx::Point());
-
-  *context_menu_position_ = position;
-}
-
 }  // namespace extensions
diff --git a/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h b/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h
index f64e07c..468debd 100644
--- a/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h
+++ b/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h
@@ -36,8 +36,6 @@
     return web_view_guest()->web_contents();
   }
 
-  void SetContextMenuPosition(const gfx::Point& position) override;
-
   // Returns the top level items (ignoring submenus) as Value.
   static std::unique_ptr<base::ListValue> MenuModelToValue(
       const ui::SimpleMenuModel& menu_model);
@@ -52,8 +50,6 @@
 
   WebViewGuest* const web_view_guest_;
 
-  std::unique_ptr<gfx::Point> context_menu_position_;
-
   // This is used to ensure pending tasks will not fire after this object is
   // destroyed.
   base::WeakPtrFactory<ChromeWebViewGuestDelegate> weak_ptr_factory_;
diff --git a/chrome/browser/install_verification/win/install_verification.cc b/chrome/browser/install_verification/win/install_verification.cc
index 15dcb38..0c0b3810d 100644
--- a/chrome/browser/install_verification/win/install_verification.cc
+++ b/chrome/browser/install_verification/win/install_verification.cc
@@ -20,7 +20,7 @@
 #include "chrome/browser/install_verification/win/module_ids.h"
 #include "chrome/browser/install_verification/win/module_info.h"
 #include "chrome/browser/install_verification/win/module_verification_common.h"
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 
 namespace {
 
@@ -64,7 +64,7 @@
     if (!path.empty()) {
       std::string ascii_path(base::SysWideToUTF8(path.BaseName().value()));
       DCHECK(base::IsStringASCII(ascii_path));
-      hash = metrics::HashName(base::ToLowerASCII(ascii_path));
+      hash = variations::HashName(base::ToLowerASCII(ascii_path));
     }
   }
 
diff --git a/chrome/browser/lifetime/application_lifetime.cc b/chrome/browser/lifetime/application_lifetime.cc
index 14b7a277..eba3fee 100644
--- a/chrome/browser/lifetime/application_lifetime.cc
+++ b/chrome/browser/lifetime/application_lifetime.cc
@@ -230,8 +230,7 @@
   // environment variable is defined. So we undefine this environment variable
   // before restarting, as the restarted processes will inherit their
   // environment variables from ours, thus suppressing crash uploads.
-  if (!ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-          g_browser_process->local_state())) {
+  if (!ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled()) {
     HMODULE exe_module = GetModuleHandle(kBrowserProcessExecutableName);
     if (exe_module) {
       typedef void (__cdecl *ClearBreakpadPipeEnvVar)();
diff --git a/chrome/browser/metrics/antivirus_metrics_provider_win.cc b/chrome/browser/metrics/antivirus_metrics_provider_win.cc
index 4dab7abb..205b329 100644
--- a/chrome/browser/metrics/antivirus_metrics_provider_win.cc
+++ b/chrome/browser/metrics/antivirus_metrics_provider_win.cc
@@ -37,7 +37,7 @@
 #include "base/win/scoped_variant.h"
 #include "base/win/windows_version.h"
 #include "chrome/common/channel_info.h"
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 #include "components/version_info/version_info.h"
 #include "third_party/metrics_proto/system_profile.pb.h"
 
@@ -308,7 +308,7 @@
     product_name.Release();
     if (ShouldReportFullNames())
       av_product.set_product_name(name);
-    av_product.set_product_name_hash(metrics::HashName(name));
+    av_product.set_product_name_hash(variations::HashName(name));
 
     base::win::ScopedBstr remediation_path;
     result = product->get_RemediationPath(remediation_path.Receive());
@@ -323,7 +323,8 @@
     if (GetProductVersion(&path_str, &product_version)) {
       if (ShouldReportFullNames())
         av_product.set_product_version(product_version);
-      av_product.set_product_version_hash(metrics::HashName(product_version));
+      av_product.set_product_version_hash(
+          variations::HashName(product_version));
     }
 
     result_list.push_back(av_product);
@@ -440,7 +441,7 @@
 
     if (ShouldReportFullNames())
       av_product.set_product_name(name);
-    av_product.set_product_name_hash(metrics::HashName(name));
+    av_product.set_product_name_hash(variations::HashName(name));
 
     base::win::ScopedVariant exe_path;
     hr = class_object->Get(L"pathToSignedProductExe", 0, exe_path.Receive(), 0,
@@ -458,7 +459,8 @@
     if (GetProductVersion(&path_str, &product_version)) {
       if (ShouldReportFullNames())
         av_product.set_product_version(product_version);
-      av_product.set_product_version_hash(metrics::HashName(product_version));
+      av_product.set_product_version_hash(
+          variations::HashName(product_version));
     }
 
     result_list.push_back(av_product);
@@ -508,8 +510,8 @@
     av_product.set_product_name(product_name);
     av_product.set_product_version(product_version);
   }
-  av_product.set_product_name_hash(metrics::HashName(product_name));
-  av_product.set_product_version_hash(metrics::HashName(product_version));
+  av_product.set_product_name_hash(variations::HashName(product_name));
+  av_product.set_product_version_hash(variations::HashName(product_version));
 
   products->push_back(av_product);
 }
diff --git a/chrome/browser/metrics/antivirus_metrics_provider_win_unittest.cc b/chrome/browser/metrics/antivirus_metrics_provider_win_unittest.cc
index 0485cc4..7bb177f7 100644
--- a/chrome/browser/metrics/antivirus_metrics_provider_win_unittest.cc
+++ b/chrome/browser/metrics/antivirus_metrics_provider_win_unittest.cc
@@ -18,7 +18,7 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/version.h"
 #include "base/win/windows_version.h"
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -35,7 +35,7 @@
   if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
     bool defender_found = false;
     for (const auto& av : system_profile.antivirus_product()) {
-      if (av.product_name_hash() == metrics::HashName(kWindowsDefender)) {
+      if (av.product_name_hash() == variations::HashName(kWindowsDefender)) {
         defender_found = true;
         if (expect_unhashed_value) {
           EXPECT_TRUE(av.has_product_name());
diff --git a/chrome/browser/metrics/chrome_metrics_service_accessor.cc b/chrome/browser/metrics/chrome_metrics_service_accessor.cc
index 034bbcea..7f454f3 100644
--- a/chrome/browser/metrics/chrome_metrics_service_accessor.cc
+++ b/chrome/browser/metrics/chrome_metrics_service_accessor.cc
@@ -31,8 +31,7 @@
 }
 
 // static
-bool ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-    PrefService* local_state) {
+bool ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled() {
   if (g_metrics_consent_for_testing)
     return *g_metrics_consent_for_testing;
 
@@ -45,12 +44,12 @@
   // This is only possible during unit tests. If the unit test didn't set the
   // local_state then it doesn't care about pref value and therefore we return
   // false.
-  if (!local_state) {
+  if (!g_browser_process->local_state()) {
     DLOG(WARNING) << "Local state has not been set and pref cannot be read";
     return false;
   }
 
-  return IsMetricsReportingEnabled(local_state);
+  return IsMetricsReportingEnabled(g_browser_process->local_state());
 }
 
 // static
diff --git a/chrome/browser/metrics/chrome_metrics_service_accessor.h b/chrome/browser/metrics/chrome_metrics_service_accessor.h
index 116a7fe..4873510 100644
--- a/chrome/browser/metrics/chrome_metrics_service_accessor.h
+++ b/chrome/browser/metrics/chrome_metrics_service_accessor.h
@@ -18,7 +18,6 @@
 class ChromeMetricsServiceClient;
 class ChromePasswordManagerClient;
 class NavigationMetricsRecorder;
-class PrefService;
 class Profile;
 
 namespace {
@@ -45,10 +44,6 @@
 class FileManagerPrivateIsUMAEnabledFunction;
 }
 
-namespace metrics_services_manager {
-class MetricsServicesManager;
-}
-
 namespace options {
 class BrowserOptionsHandler;
 }
@@ -114,8 +109,6 @@
   friend class extensions::ChromeMetricsPrivateDelegate;
   friend class extensions::FileManagerPrivateIsUMAEnabledFunction;
   friend void ChangeMetricsReportingStateWithReply(
-      PrefService*,
-      metrics_services_manager::MetricsServicesManager*,
       bool,
       const OnMetricsReportingCallbackType&);
   friend class options::BrowserOptionsHandler;
@@ -145,14 +138,10 @@
   // Returns true if metrics reporting is enabled. This does NOT necessary mean
   // that it is active as configuration may prevent it on some devices (i.e.
   // the "MetricsReporting" field trial that controls sampling). To include
-  // that, call: metrics_services_manager->IsReportingEnabled()
-  // |local_state| is the PrefService for local state. Typically this comes from
-  // g_browser_process->local_state(), but during startup |g_browser_process|
-  // may not have been created, in which case it's the local state that will
-  // eventually be assigned to |g_browser_process|.
+  // that, call: metrics_services_manager->IsReportingEnabled().
   // TODO(gayane): Consolidate metric prefs on all platforms.
   // http://crbug.com/362192,  http://crbug.com/532084
-  static bool IsMetricsAndCrashReportingEnabled(PrefService* local_state);
+  static bool IsMetricsAndCrashReportingEnabled();
 
   // Calls metrics::MetricsServiceAccessor::RegisterSyntheticFieldTrial() with
   // g_browser_process->metrics_service(). See that function's declaration for
diff --git a/chrome/browser/metrics/chrome_metrics_service_accessor_unittest.cc b/chrome/browser/metrics/chrome_metrics_service_accessor_unittest.cc
index 3fd4140b..6da420e 100644
--- a/chrome/browser/metrics/chrome_metrics_service_accessor_unittest.cc
+++ b/chrome/browser/metrics/chrome_metrics_service_accessor_unittest.cc
@@ -38,27 +38,27 @@
   GetLocalState()->SetDefaultPrefValue(pref, base::Value(false));
 
   GetLocalState()->SetBoolean(pref, false);
-  EXPECT_FALSE(ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-      GetLocalState()));
+  EXPECT_FALSE(
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
   GetLocalState()->SetBoolean(pref, true);
-  EXPECT_TRUE(ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-      GetLocalState()));
+  EXPECT_TRUE(
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
   GetLocalState()->ClearPref(pref);
-  EXPECT_FALSE(ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-      GetLocalState()));
+  EXPECT_FALSE(
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
 
   // If field trials are forced, metrics should always be disabled, regardless
   // of the value of the pref.
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       switches::kForceFieldTrials);
-  EXPECT_FALSE(ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-      GetLocalState()));
+  EXPECT_FALSE(
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
   GetLocalState()->SetBoolean(pref, true);
-  EXPECT_FALSE(ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-      GetLocalState()));
+  EXPECT_FALSE(
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
 #else
   // Metrics Reporting is never enabled when GOOGLE_CHROME_BUILD is undefined.
-  EXPECT_FALSE(ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-      GetLocalState()));
+  EXPECT_FALSE(
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
 #endif
 }
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc
index 8251789d..287c125 100644
--- a/chrome/browser/metrics/chrome_metrics_service_client.cc
+++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -529,7 +529,7 @@
 }
 
 bool ChromeMetricsServiceClient::IsReportingPolicyManaged() {
-  return IsMetricsReportingPolicyManaged(g_browser_process->local_state());
+  return IsMetricsReportingPolicyManaged();
 }
 
 metrics::EnableMetricsDefault
@@ -600,7 +600,7 @@
       base::MakeUnique<metrics::ScreenInfoMetricsProvider>());
 
   metrics_service_->RegisterMetricsProvider(CreateFileMetricsProvider(
-      metrics_state_manager_->IsMetricsReportingEnabled()));
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled()));
 
   metrics_service_->RegisterMetricsProvider(
       base::MakeUnique<metrics::DriveMetricsProvider>(
diff --git a/chrome/browser/metrics/chrome_metrics_services_manager_client.cc b/chrome/browser/metrics/chrome_metrics_services_manager_client.cc
index 2472f8ec..2e88876 100644
--- a/chrome/browser/metrics/chrome_metrics_services_manager_client.cc
+++ b/chrome/browser/metrics/chrome_metrics_services_manager_client.cc
@@ -94,13 +94,11 @@
 #if defined(OS_CHROMEOS)
 // Callback to update the metrics reporting state when the Chrome OS metrics
 // reporting setting changes.
-void OnCrosMetricsReportingSettingChange(
-    PrefService* local_state,
-    metrics_services_manager::MetricsServicesManager* manager) {
+void OnCrosMetricsReportingSettingChange() {
   bool enable_metrics = false;
   chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref,
                                             &enable_metrics);
-  ChangeMetricsReportingState(local_state, manager, enable_metrics);
+  ChangeMetricsReportingState(enable_metrics);
 }
 #endif
 
@@ -120,13 +118,11 @@
 class ChromeMetricsServicesManagerClient::ChromeEnabledStateProvider
     : public metrics::EnabledStateProvider {
  public:
-  explicit ChromeEnabledStateProvider(PrefService* local_state)
-      : local_state_(local_state) {}
+  ChromeEnabledStateProvider() {}
   ~ChromeEnabledStateProvider() override {}
 
   bool IsConsentGiven() const override {
-    return ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-        local_state_);
+    return ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled();
   }
 
   bool IsReportingEnabled() const override {
@@ -134,19 +130,12 @@
            ChromeMetricsServicesManagerClient::IsClientInSample();
   }
 
- private:
-  // This code may be run before |g_browser_process| has been created so it
-  // needs to cache |local_state_|. This cached value will be the same as
-  // g_browser_process->local_state() once created.
-  PrefService* local_state_;
-
   DISALLOW_COPY_AND_ASSIGN(ChromeEnabledStateProvider);
 };
 
 ChromeMetricsServicesManagerClient::ChromeMetricsServicesManagerClient(
     PrefService* local_state)
-    : enabled_state_provider_(
-          std::make_unique<ChromeEnabledStateProvider>(local_state)),
+    : enabled_state_provider_(std::make_unique<ChromeEnabledStateProvider>()),
       local_state_(local_state) {
   DCHECK(local_state);
 }
@@ -229,13 +218,11 @@
 
 #if defined(OS_CHROMEOS)
 void ChromeMetricsServicesManagerClient::OnCrosSettingsCreated() {
-  metrics_services_manager::MetricsServicesManager* manager =
-      g_browser_process->GetMetricsServicesManager();
   cros_settings_observer_ = chromeos::CrosSettings::Get()->AddSettingsObserver(
       chromeos::kStatsReportingPref,
-      base::Bind(&OnCrosMetricsReportingSettingChange, local_state_, manager));
+      base::Bind(&OnCrosMetricsReportingSettingChange));
   // Invoke the callback once initially to set the metrics reporting state.
-  OnCrosMetricsReportingSettingChange(local_state_, manager);
+  OnCrosMetricsReportingSettingChange();
 }
 #endif
 
diff --git a/chrome/browser/metrics/metrics_reporting_state.cc b/chrome/browser/metrics/metrics_reporting_state.cc
index 947136f..2592dea8 100644
--- a/chrome/browser/metrics/metrics_reporting_state.cc
+++ b/chrome/browser/metrics/metrics_reporting_state.cc
@@ -8,6 +8,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/task_runner_util.h"
 #include "build/build_config.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/installer/util/google_update_settings.h"
@@ -53,20 +54,16 @@
 //  |updated_pref| is the result of attempted update.
 // Update considers to be successful if |to_update_pref| and |updated_pref| are
 // the same.
-void SetMetricsReporting(
-    PrefService* local_state,
-    metrics_services_manager::MetricsServicesManager* metrics_services_manager,
-    bool to_update_pref,
-    const OnMetricsReportingCallbackType& callback_fn,
-    bool updated_pref) {
-  local_state->SetBoolean(metrics::prefs::kMetricsReportingEnabled,
-                          updated_pref);
+void SetMetricsReporting(bool to_update_pref,
+                         const OnMetricsReportingCallbackType& callback_fn,
+                         bool updated_pref) {
+  g_browser_process->local_state()->SetBoolean(
+      metrics::prefs::kMetricsReportingEnabled, updated_pref);
 
-  UpdateMetricsPrefsOnPermissionChange(
-      local_state, metrics_services_manager->GetMetricsService(), updated_pref);
+  UpdateMetricsPrefsOnPermissionChange(updated_pref);
 
   // Uses the current state of whether reporting is enabled to enable services.
-  metrics_services_manager->UpdateUploadPermissions(true);
+  g_browser_process->GetMetricsServicesManager()->UpdateUploadPermissions(true);
 
   if (to_update_pref == updated_pref) {
     RecordMetricsReportingHistogramValue(updated_pref ?
@@ -80,28 +77,21 @@
 
 }  // namespace
 
-void ChangeMetricsReportingState(
-    PrefService* local_state,
-    metrics_services_manager::MetricsServicesManager* metrics_services_manager,
-    bool enabled) {
-  ChangeMetricsReportingStateWithReply(local_state, metrics_services_manager,
-                                       enabled,
+void ChangeMetricsReportingState(bool enabled) {
+  ChangeMetricsReportingStateWithReply(enabled,
                                        OnMetricsReportingCallbackType());
 }
 
 // TODO(gayane): Instead of checking policy before setting the metrics pref set
 // the pref and register for notifications for the rest of the changes.
 void ChangeMetricsReportingStateWithReply(
-    PrefService* local_state,
-    metrics_services_manager::MetricsServicesManager* metrics_services_manager,
     bool enabled,
     const OnMetricsReportingCallbackType& callback_fn) {
 #if !defined(OS_ANDROID)
-  if (IsMetricsReportingPolicyManaged(local_state)) {
+  if (IsMetricsReportingPolicyManaged()) {
     if (!callback_fn.is_null()) {
       callback_fn.Run(
-          ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-              local_state));
+          ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
     }
     return;
   }
@@ -109,31 +99,30 @@
   base::PostTaskAndReplyWithResult(
       GoogleUpdateSettings::CollectStatsConsentTaskRunner(), FROM_HERE,
       base::Bind(&SetGoogleUpdateSettings, enabled),
-      base::Bind(&SetMetricsReporting, local_state, metrics_services_manager,
-                 enabled, callback_fn));
+      base::Bind(&SetMetricsReporting, enabled, callback_fn));
 }
 
-void UpdateMetricsPrefsOnPermissionChange(
-    PrefService* local_state,
-    metrics::MetricsService* metrics_service,
-    bool metrics_enabled) {
+void UpdateMetricsPrefsOnPermissionChange(bool metrics_enabled) {
   if (metrics_enabled) {
     // When a user opts in to the metrics reporting service, the previously
     // collected data should be cleared to ensure that nothing is reported
     // before a user opts in and all reported data is accurate.
-    metrics_service->ClearSavedStabilityMetrics();
+    g_browser_process->metrics_service()->ClearSavedStabilityMetrics();
   } else {
     // Clear the client id pref when opting out.
     // Note: Clearing client id will not affect the running state (e.g. field
     // trial randomization), as the pref is only read on startup.
-    local_state->ClearPref(metrics::prefs::kMetricsClientID);
-    local_state->ClearPref(metrics::prefs::kMetricsReportingEnabledTimestamp);
+    g_browser_process->local_state()->ClearPref(
+        metrics::prefs::kMetricsClientID);
+    g_browser_process->local_state()->ClearPref(
+        metrics::prefs::kMetricsReportingEnabledTimestamp);
     crash_keys::ClearMetricsClientId();
   }
 }
 
-bool IsMetricsReportingPolicyManaged(PrefService* local_state) {
+bool IsMetricsReportingPolicyManaged() {
+  const PrefService* pref_service = g_browser_process->local_state();
   const PrefService::Preference* pref =
-      local_state->FindPreference(metrics::prefs::kMetricsReportingEnabled);
+      pref_service->FindPreference(metrics::prefs::kMetricsReportingEnabled);
   return pref && pref->IsManaged();
 }
diff --git a/chrome/browser/metrics/metrics_reporting_state.h b/chrome/browser/metrics/metrics_reporting_state.h
index 79f6977..06893c2 100644
--- a/chrome/browser/metrics/metrics_reporting_state.h
+++ b/chrome/browser/metrics/metrics_reporting_state.h
@@ -8,55 +8,28 @@
 #include "base/callback.h"
 #include "components/metrics/metrics_service_client.h"
 
-class PrefService;
-
 typedef base::Callback<void(bool)> OnMetricsReportingCallbackType;
 
-namespace metrics {
-class MetricsService;
-}
-
-namespace metrics_services_manager {
-class MetricsServicesManager;
-}
-
-// Many of these functions take objects available from |g_browser_process|. For
-// example, ChangeMetricsReportingState() takes local state. This is done as
-// during startup some of this code is run at a point when |g_browser_process|
-// may not have been created. Unless your code is run during early
-// initialization use |g_browser_process| to obtain the appropriate value.
-
 // Changes metrics reporting state without caring about the success of the
-// change. See early comment for details on args.
-void ChangeMetricsReportingState(
-    PrefService* local_state,
-    metrics_services_manager::MetricsServicesManager* metrics_services_manager,
-    bool enabled);
+// change.
+void ChangeMetricsReportingState(bool enabled);
 
 // Changes metrics reporting state to the new value of |enabled|. Starts or
 // stops the metrics service based on the new state and then runs |callback_fn|
 // (which can be null) with the updated state (as the operation may fail). On
 // platforms other than CrOS and Android, also updates the underlying pref.
-// See early comment for details on args.
 // TODO(gayane): Support setting the pref on all platforms.
 void ChangeMetricsReportingStateWithReply(
-    PrefService* local_state,
-    metrics_services_manager::MetricsServicesManager* metrics_services_manager,
     bool enabled,
     const OnMetricsReportingCallbackType& callback_fn);
 
 // Update metrics prefs on a permission (opt-in/out) change. When opting out,
 // this clears various client ids. When opting in, this resets saving crash
 // prefs, so as not to trigger upload of various stale data.
-// See early comment for details on args.
-void UpdateMetricsPrefsOnPermissionChange(
-    PrefService* local_state,
-    metrics::MetricsService* metrics_service,
-    bool metrics_enabled);
+void UpdateMetricsPrefsOnPermissionChange(bool metrics_enabled);
 
 // Returns whether MetricsReporting can be modified by the user (except
 // Android).
-// See early comment for details on args.
-bool IsMetricsReportingPolicyManaged(PrefService* local_state);
+bool IsMetricsReportingPolicyManaged();
 
 #endif  // CHROME_BROWSER_METRICS_METRICS_REPORTING_STATE_H_
diff --git a/chrome/browser/metrics/metrics_reporting_state_browsertest.cc b/chrome/browser/metrics/metrics_reporting_state_browsertest.cc
index bb3745f..764e100a 100644
--- a/chrome/browser/metrics/metrics_reporting_state_browsertest.cc
+++ b/chrome/browser/metrics/metrics_reporting_state_browsertest.cc
@@ -75,8 +75,7 @@
   ~MetricsReportingStateTest() override = default;
 
   static bool IsMetricsAndCrashReportingEnabled() {
-    return ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-        g_browser_process->local_state());
+    return ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled();
   }
 
   bool is_metrics_reporting_enabled_initial_value() const { return GetParam(); }
@@ -157,8 +156,6 @@
   base::RunLoop run_loop;
   bool value_after_change = false;
   ChangeMetricsReportingStateWithReply(
-      g_browser_process->local_state(),
-      g_browser_process->GetMetricsServicesManager(),
       !is_metrics_reporting_enabled_initial_value(),
       base::Bind(&OnMetricsReportingStateChanged, &value_after_change,
                  run_loop.QuitClosure()));
diff --git a/chrome/browser/net/errorpage_browsertest.cc b/chrome/browser/net/errorpage_browsertest.cc
index f81196d..ca4b943 100644
--- a/chrome/browser/net/errorpage_browsertest.cc
+++ b/chrome/browser/net/errorpage_browsertest.cc
@@ -60,6 +60,7 @@
 #include "content/public/test/url_loader_interceptor.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "net/base/filename_util.h"
+#include "net/base/mock_network_change_notifier.h"
 #include "net/base/net_errors.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/http/failing_http_transaction_factory.h"
@@ -1348,6 +1349,59 @@
   EXPECT_EQ(3, interceptor_requests());
 }
 
+class ErrorPageAutoReloadOffline : public ErrorPageAutoReloadTest {
+ public:
+  void PreRunTestOnMainThread() override {
+    // Helps the browser to create renderer in offline mode.
+    MockNetwork();
+    InProcessBrowserTest::PreRunTestOnMainThread();
+  }
+  void PostRunTestOnMainThread() override {
+    InProcessBrowserTest::PostRunTestOnMainThread();
+    ReleaseNetwork();
+  }
+
+  void MockNetwork() {
+    mock_network_ =
+        std::make_unique<net::test::ScopedMockNetworkChangeNotifier>();
+    mock_network_->mock_network_change_notifier()->SetConnectionType(
+        net::NetworkChangeNotifier::CONNECTION_NONE);
+  }
+
+  void ReleaseNetwork() { mock_network_.reset(); }
+
+ private:
+  std::unique_ptr<net::test::ScopedMockNetworkChangeNotifier> mock_network_;
+};
+
+IN_PROC_BROWSER_TEST_F(ErrorPageAutoReloadOffline,
+                       AvoidAutoReloadingWhenOffline) {
+  GURL test_url("http://error.page.auto.reload");
+  InstallInterceptor(test_url, 1);
+
+  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), test_url,
+                                                            1);
+  base::RunLoop().RunUntilIdle();
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  content::WaitForLoadStop(web_contents);
+  // Make sure that first autoreload did not happen.
+  EXPECT_EQ(1, interceptor_requests());
+
+  // Release network. Now the renderer can receive notifications about network.
+  ReleaseNetwork();
+
+  // Browser is online now. Autoreload request should start immediately.
+  net::NetworkChangeNotifier::NotifyObserversOfMaxBandwidthChangeForTests(
+      1., net::NetworkChangeNotifier::CONNECTION_WIFI);
+
+  content::TestNavigationObserver tab_observer(web_contents, 1);
+  tab_observer.Wait();
+
+  EXPECT_EQ(2, interceptor_requests());
+}
+
 // TODO(dougt): AddressUnreachableInterceptor can be removed as soon as the
 // Network Service is the only code path.
 
diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc
index fdbcb504..69b7865b 100644
--- a/chrome/browser/net/network_context_configuration_browsertest.cc
+++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -28,7 +28,6 @@
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/common/content_switches.h"
-#include "content/public/common/simple_url_loader.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/simple_url_loader_test_helper.h"
@@ -45,6 +44,7 @@
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/resource_response.h"
 #include "services/network/public/cpp/resource_response_info.h"
+#include "services/network/public/cpp/simple_url_loader.h"
 #include "services/network/public/interfaces/network_service.mojom.h"
 #include "services/network/public/interfaces/url_loader.mojom.h"
 #include "services/network/public/interfaces/url_loader_factory.mojom.h"
@@ -217,8 +217,8 @@
     request->url = GURL("http://jabberwocky.test:1872/echo");
 
     content::SimpleURLLoaderTestHelper simple_loader_helper;
-    std::unique_ptr<content::SimpleURLLoader> simple_loader =
-        content::SimpleURLLoader::Create(std::move(request),
+    std::unique_ptr<network::SimpleURLLoader> simple_loader =
+        network::SimpleURLLoader::Create(std::move(request),
                                          TRAFFIC_ANNOTATION_FOR_TESTS);
 
     simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
@@ -283,8 +283,8 @@
       std::make_unique<network::ResourceRequest>();
   request->url = embedded_test_server()->GetURL("/echo");
   content::SimpleURLLoaderTestHelper simple_loader_helper;
-  std::unique_ptr<content::SimpleURLLoader> simple_loader =
-      content::SimpleURLLoader::Create(std::move(request),
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
                                        TRAFFIC_ANNOTATION_FOR_TESTS);
 
   simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
@@ -303,8 +303,8 @@
       std::make_unique<network::ResourceRequest>();
   request->url = GURL("data:text/plain,foo");
   content::SimpleURLLoaderTestHelper simple_loader_helper;
-  std::unique_ptr<content::SimpleURLLoader> simple_loader =
-      content::SimpleURLLoader::Create(std::move(request),
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
                                        TRAFFIC_ANNOTATION_FOR_TESTS);
 
   simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
@@ -333,8 +333,8 @@
       std::make_unique<network::ResourceRequest>();
   request->url = net::FilePathToFileURL(file_path);
   content::SimpleURLLoaderTestHelper simple_loader_helper;
-  std::unique_ptr<content::SimpleURLLoader> simple_loader =
-      content::SimpleURLLoader::Create(std::move(request),
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
                                        TRAFFIC_ANNOTATION_FOR_TESTS);
 
   simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
@@ -356,8 +356,8 @@
       std::make_unique<network::ResourceRequest>();
   request->url = request_url;
   content::SimpleURLLoaderTestHelper simple_loader_helper;
-  std::unique_ptr<content::SimpleURLLoader> simple_loader =
-      content::SimpleURLLoader::Create(std::move(request),
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
                                        TRAFFIC_ANNOTATION_FOR_TESTS);
 
   simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
@@ -376,8 +376,8 @@
       std::make_unique<network::ResourceRequest>();
   request2->url = request_url;
   content::SimpleURLLoaderTestHelper simple_loader_helper2;
-  std::unique_ptr<content::SimpleURLLoader> simple_loader2 =
-      content::SimpleURLLoader::Create(std::move(request2),
+  std::unique_ptr<network::SimpleURLLoader> simple_loader2 =
+      network::SimpleURLLoader::Create(std::move(request2),
                                        TRAFFIC_ANNOTATION_FOR_TESTS);
   simple_loader2->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
       loader_factory(), simple_loader_helper2.GetCallback());
@@ -418,8 +418,8 @@
   request->url = test_url;
   request->headers.SetHeader("foo", "foopity foo");
   content::SimpleURLLoaderTestHelper simple_loader_helper;
-  std::unique_ptr<content::SimpleURLLoader> simple_loader =
-      content::SimpleURLLoader::Create(std::move(request),
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
                                        TRAFFIC_ANNOTATION_FOR_TESTS);
   simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
       loader_factory(), simple_loader_helper.GetCallback());
@@ -498,8 +498,8 @@
   // the test server anyways.
   request->url = GURL("http://127.0.0.1/echo");
   content::SimpleURLLoaderTestHelper simple_loader_helper;
-  std::unique_ptr<content::SimpleURLLoader> simple_loader =
-      content::SimpleURLLoader::Create(std::move(request),
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
                                        TRAFFIC_ANNOTATION_FOR_TESTS);
 
   simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
@@ -665,8 +665,8 @@
   request->url = GURL("http://jabberwocky.test:1872/echo");
 
   content::SimpleURLLoaderTestHelper simple_loader_helper;
-  std::unique_ptr<content::SimpleURLLoader> simple_loader =
-      content::SimpleURLLoader::Create(std::move(request),
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
                                        TRAFFIC_ANNOTATION_FOR_TESTS);
 
   simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
diff --git a/chrome/browser/net/profile_network_context_service_browsertest.cc b/chrome/browser/net/profile_network_context_service_browsertest.cc
index 8b97d3da..1a48b027 100644
--- a/chrome/browser/net/profile_network_context_service_browsertest.cc
+++ b/chrome/browser/net/profile_network_context_service_browsertest.cc
@@ -80,8 +80,8 @@
       std::make_unique<network::ResourceRequest>();
   request->url = embedded_test_server()->GetURL("/cachetime");
   content::SimpleURLLoaderTestHelper simple_loader_helper;
-  std::unique_ptr<content::SimpleURLLoader> simple_loader =
-      content::SimpleURLLoader::Create(std::move(request),
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
                                        TRAFFIC_ANNOTATION_FOR_TESTS);
 
   simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
@@ -114,8 +114,8 @@
   request->load_flags |= net::LOAD_IGNORE_ALL_CERT_ERRORS;
 #endif  // !defined(OS_MACOSX)
   content::SimpleURLLoaderTestHelper simple_loader_helper;
-  std::unique_ptr<content::SimpleURLLoader> simple_loader =
-      content::SimpleURLLoader::Create(std::move(request),
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
                                        TRAFFIC_ANNOTATION_FOR_TESTS);
   simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
       loader_factory(), simple_loader_helper.GetCallback());
@@ -163,8 +163,8 @@
       std::make_unique<network::ResourceRequest>();
   request->url = embedded_test_server()->GetURL("/cachetime");
   content::SimpleURLLoaderTestHelper simple_loader_helper;
-  std::unique_ptr<content::SimpleURLLoader> simple_loader =
-      content::SimpleURLLoader::Create(std::move(request),
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
                                        TRAFFIC_ANNOTATION_FOR_TESTS);
 
   simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
diff --git a/chrome/browser/notifications/DEPS b/chrome/browser/notifications/DEPS
index 49a4ca2..795e3dd 100644
--- a/chrome/browser/notifications/DEPS
+++ b/chrome/browser/notifications/DEPS
@@ -1,5 +1,4 @@
 include_rules = [
-  # TODO(mash): Remove. http://crbug.com/723882
-  "+ash",
   "+dbus",
+  "+ui/message_center",
 ]
diff --git a/chrome/browser/notifications/notification_platform_bridge_android.cc b/chrome/browser/notifications/notification_platform_bridge_android.cc
index 9a15952c..93fa8683 100644
--- a/chrome/browser/notifications/notification_platform_bridge_android.cc
+++ b/chrome/browser/notifications/notification_platform_bridge_android.cc
@@ -67,14 +67,8 @@
 
 NotificationActionType GetNotificationActionType(
     message_center::ButtonInfo button) {
-  switch (button.type) {
-    case message_center::ButtonType::BUTTON:
-      return NotificationActionType::BUTTON;
-    case message_center::ButtonType::TEXT:
-      return NotificationActionType::TEXT;
-  }
-  NOTREACHED();
-  return NotificationActionType::TEXT;
+  return button.placeholder ? NotificationActionType::TEXT
+                            : NotificationActionType::BUTTON;
 }
 
 ScopedJavaLocalRef<jobjectArray> ConvertToJavaActionInfos(
@@ -91,8 +85,11 @@
     ScopedJavaLocalRef<jstring> title =
         base::android::ConvertUTF16ToJavaString(env, button.title);
     int type = GetNotificationActionType(button);
-    ScopedJavaLocalRef<jstring> placeholder =
-        base::android::ConvertUTF16ToJavaString(env, button.placeholder);
+    ScopedJavaLocalRef<jstring> placeholder;
+    if (button.placeholder) {
+      placeholder =
+          base::android::ConvertUTF16ToJavaString(env, *button.placeholder);
+    }
     ScopedJavaLocalRef<jobject> icon =
         JNI_NotificationPlatformBridge_ConvertToJavaBitmap(env, button.icon);
     ScopedJavaLocalRef<jobject> action_info = Java_ActionInfo_createActionInfo(
diff --git a/chrome/browser/notifications/notification_platform_bridge_chromeos.cc b/chrome/browser/notifications/notification_platform_bridge_chromeos.cc
index 44038578..a532923 100644
--- a/chrome/browser/notifications/notification_platform_bridge_chromeos.cc
+++ b/chrome/browser/notifications/notification_platform_bridge_chromeos.cc
@@ -6,7 +6,6 @@
 
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/notifications/chrome_ash_message_center_client.h"
 #include "chrome/browser/notifications/notification_display_service_impl.h"
 #include "chrome/browser/profiles/profile.h"
@@ -29,16 +28,6 @@
 }  // namespace
 
 // static
-NotificationDisplayService*
-NotificationDisplayService::GetForSystemNotifications() {
-  // System notifications (such as those for network state) aren't tied to a
-  // particular user and can show up before any user is logged in, so fall back
-  // to the signin profile, which is guaranteed to exist.
-  return NotificationDisplayService::GetForProfile(
-      chromeos::ProfileHelper::GetSigninProfile());
-}
-
-// static
 NotificationPlatformBridge* NotificationPlatformBridge::Create() {
   return new NotificationPlatformBridgeChromeOs();
 }
diff --git a/chrome/browser/notifications/notification_template_builder.cc b/chrome/browser/notifications/notification_template_builder.cc
index 91259c17..57fcbe6 100644
--- a/chrome/browser/notifications/notification_template_builder.cc
+++ b/chrome/browser/notifications/notification_template_builder.cc
@@ -295,11 +295,11 @@
   bool inline_reply = false;
   std::string placeholder;
   for (const auto& button : buttons) {
-    if (button.type != message_center::ButtonType::TEXT)
+    if (!button.placeholder)
       continue;
 
     inline_reply = true;
-    placeholder = base::UTF16ToUTF8(button.placeholder);
+    placeholder = base::UTF16ToUTF8(*button.placeholder);
     break;
   }
 
diff --git a/chrome/browser/notifications/notification_template_builder_unittest.cc b/chrome/browser/notifications/notification_template_builder_unittest.cc
index 1554e9d..2089f55 100644
--- a/chrome/browser/notifications/notification_template_builder_unittest.cc
+++ b/chrome/browser/notifications/notification_template_builder_unittest.cc
@@ -155,7 +155,6 @@
 
   std::vector<message_center::ButtonInfo> buttons;
   message_center::ButtonInfo button1(base::ASCIIToUTF16("Button1"));
-  button1.type = message_center::ButtonType::TEXT;
   button1.placeholder = base::ASCIIToUTF16("Reply here");
   buttons.emplace_back(button1);
   buttons.emplace_back(base::ASCIIToUTF16("Button2"));
@@ -188,11 +187,9 @@
 
   std::vector<message_center::ButtonInfo> buttons;
   message_center::ButtonInfo button1(base::ASCIIToUTF16("Button1"));
-  button1.type = message_center::ButtonType::TEXT;
   button1.placeholder = base::ASCIIToUTF16("Reply here");
   buttons.emplace_back(button1);
   message_center::ButtonInfo button2(base::ASCIIToUTF16("Button2"));
-  button2.type = message_center::ButtonType::TEXT;
   button2.placeholder = base::ASCIIToUTF16("Should not appear");
   buttons.emplace_back(button2);
   notification->set_buttons(buttons);
@@ -225,7 +222,6 @@
   std::vector<message_center::ButtonInfo> buttons;
   buttons.emplace_back(base::ASCIIToUTF16("Button1"));
   message_center::ButtonInfo button2(base::ASCIIToUTF16("Button2"));
-  button2.type = message_center::ButtonType::TEXT;
   button2.placeholder = base::ASCIIToUTF16("Reply here");
   buttons.emplace_back(button2);
   notification->set_buttons(buttons);
@@ -369,7 +365,6 @@
 
   std::vector<message_center::ButtonInfo> buttons;
   message_center::ButtonInfo button(base::ASCIIToUTF16("Button1"));
-  button.type = message_center::ButtonType::TEXT;
   button.placeholder = base::ASCIIToUTF16("Reply here");
   button.icon = gfx::Image::CreateFrom1xBitmap(icon);
   buttons.emplace_back(button);
diff --git a/chrome/browser/notifications/platform_notification_service_impl.cc b/chrome/browser/notifications/platform_notification_service_impl.cc
index 8f046dc..a6128d5 100644
--- a/chrome/browser/notifications/platform_notification_service_impl.cc
+++ b/chrome/browser/notifications/platform_notification_service_impl.cc
@@ -540,17 +540,9 @@
     // the 1x bitmap - crbug.com/585815.
     button.icon =
         gfx::Image::CreateFrom1xBitmap(notification_resources.action_icons[i]);
-    button.placeholder =
-        action.placeholder.is_null()
-            ? l10n_util::GetStringUTF16(IDS_NOTIFICATION_REPLY_PLACEHOLDER)
-            : action.placeholder.string();
-    switch (action.type) {
-      case content::PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON:
-        button.type = message_center::ButtonType::BUTTON;
-        break;
-      case content::PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT:
-        button.type = message_center::ButtonType::TEXT;
-        break;
+    if (action.type == content::PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT) {
+      button.placeholder = action.placeholder.as_optional_string16().value_or(
+          l10n_util::GetStringUTF16(IDS_NOTIFICATION_REPLY_PLACEHOLDER));
     }
     buttons.push_back(button);
   }
diff --git a/chrome/browser/notifications/platform_notification_service_unittest.cc b/chrome/browser/notifications/platform_notification_service_unittest.cc
index 3cb30c57..e495af9 100644
--- a/chrome/browser/notifications/platform_notification_service_unittest.cc
+++ b/chrome/browser/notifications/platform_notification_service_unittest.cc
@@ -247,9 +247,9 @@
   const auto& buttons = notification.buttons();
   ASSERT_EQ(2u, buttons.size());
   EXPECT_EQ("Button 1", base::UTF16ToUTF8(buttons[0].title));
-  EXPECT_EQ(message_center::ButtonType::BUTTON, buttons[0].type);
+  EXPECT_FALSE(buttons[0].placeholder);
   EXPECT_EQ("Button 2", base::UTF16ToUTF8(buttons[1].title));
-  EXPECT_EQ(message_center::ButtonType::TEXT, buttons[1].type);
+  EXPECT_TRUE(buttons[1].placeholder);
 }
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
diff --git a/chrome/browser/notifications/system_notification_helper.cc b/chrome/browser/notifications/system_notification_helper.cc
new file mode 100644
index 0000000..c88fdeaa
--- /dev/null
+++ b/chrome/browser/notifications/system_notification_helper.cc
@@ -0,0 +1,83 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/notifications/system_notification_helper.h"
+
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/notifications/notification_display_service.h"
+#include "chrome/browser/profiles/profile_manager.h"
+
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#endif
+
+SystemNotificationHelper* SystemNotificationHelper::GetInstance() {
+  return base::Singleton<SystemNotificationHelper>::get();
+}
+
+SystemNotificationHelper::SystemNotificationHelper() = default;
+SystemNotificationHelper::~SystemNotificationHelper() = default;
+
+void SystemNotificationHelper::Display(
+    const message_center::Notification& notification) {
+  pending_notifications_[notification.id()] = notification;
+  g_browser_process->profile_manager()->CreateProfileAsync(
+      GetProfilePath(),
+      base::AdaptCallbackForRepeating(
+          base::BindOnce(&SystemNotificationHelper::DoDisplayNotification,
+                         weak_factory_.GetWeakPtr(), notification.id())),
+      base::string16(), std::string(), std::string());
+}
+
+void SystemNotificationHelper::Close(const std::string& notification_id) {
+  size_t erased = pending_notifications_.erase(notification_id);
+  Profile* profile =
+      g_browser_process->profile_manager()->GetProfileByPath(GetProfilePath());
+  if (!profile)
+    return;
+
+  // If the profile has finished loading, we should have already removed the
+  // notification from the pending list in DoDisplayNotification().
+  DCHECK_EQ(0u, erased);
+  NotificationDisplayService::GetForProfile(profile->GetOffTheRecordProfile())
+      ->Close(NotificationHandler::Type::TRANSIENT, notification_id);
+}
+
+void SystemNotificationHelper::DoDisplayNotification(
+    const std::string& notification_id,
+    Profile* profile,
+    Profile::CreateStatus status) {
+  auto iter = pending_notifications_.find(notification_id);
+  if (iter == pending_notifications_.end())
+    return;
+
+  if (profile) {
+    // We use the incognito profile both to match
+    // ProfileHelper::GetSigninProfile() and to be sure we don't store anything
+    // about it across program restarts.
+    NotificationDisplayService::GetForProfile(profile->GetOffTheRecordProfile())
+        ->Display(NotificationHandler::Type::TRANSIENT, iter->second);
+  }
+  pending_notifications_.erase(iter);
+}
+
+// static
+Profile* SystemNotificationHelper::GetProfileForTesting() {
+  return g_browser_process->profile_manager()
+      ->GetProfile(GetProfilePath())
+      ->GetOffTheRecordProfile();
+}
+
+// static
+base::FilePath SystemNotificationHelper::GetProfilePath() {
+#if defined(OS_CHROMEOS)
+  // System notifications (such as those for network state) aren't tied to a
+  // particular user and can show up before any user is logged in, so use the
+  // signin profile, which is guaranteed to already exist.
+  return chromeos::ProfileHelper::GetSigninProfileDir();
+#else
+  // The "system profile" probably hasn't been loaded yet.
+  return g_browser_process->profile_manager()->GetSystemProfilePath();
+#endif
+}
diff --git a/chrome/browser/notifications/system_notification_helper.h b/chrome/browser/notifications/system_notification_helper.h
new file mode 100644
index 0000000..a983af81f
--- /dev/null
+++ b/chrome/browser/notifications/system_notification_helper.h
@@ -0,0 +1,57 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NOTIFICATIONS_SYSTEM_NOTIFICATION_HELPER_H_
+#define CHROME_BROWSER_NOTIFICATIONS_SYSTEM_NOTIFICATION_HELPER_H_
+
+#include "base/files/file_path.h"
+#include "base/memory/singleton.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/profiles/profile.h"
+#include "ui/message_center/public/cpp/notification.h"
+
+// This class assists in displaying notifications that do not have an associated
+// Profile. It uses a system profile which may not be loaded. Thus, Display() is
+// not always synchronous.
+class SystemNotificationHelper {
+ public:
+  // Returns the singleton instance.
+  static SystemNotificationHelper* GetInstance();
+
+  // Displays a notification which isn't tied to a normal user profile. The
+  // notification will be displayed asynchronously if the generic profile has
+  // not yet been loaded.
+  void Display(const message_center::Notification& notification);
+
+  // Closes a notification which isn't tied to a normal user profile.
+  void Close(const std::string& notification_id);
+
+  // Loads the profile used for the profile-agnostic NotificationDisplayService.
+  static Profile* GetProfileForTesting();
+
+ private:
+  friend struct base::DefaultSingletonTraits<SystemNotificationHelper>;
+
+  SystemNotificationHelper();
+  ~SystemNotificationHelper();
+
+  void DoDisplayNotification(const std::string& notification_id,
+                             Profile* profile,
+                             Profile::CreateStatus status);
+
+  // Returns the path for a non-user-specific profile. This will be used for
+  // system notifications which aren't tied to a particular normal profile.
+  static base::FilePath GetProfilePath();
+
+  // Notifications are added to this queue when the system profile has not yet
+  // been loaded. They are removed in Close() if it's called before the profile
+  // loads, or after the notification is displayed if that happens first.
+  std::map<std::string, message_center::Notification> pending_notifications_;
+
+  base::WeakPtrFactory<SystemNotificationHelper> weak_factory_{this};
+
+  DISALLOW_COPY_AND_ASSIGN(SystemNotificationHelper);
+};
+
+#endif  // CHROME_BROWSER_NOTIFICATIONS_SYSTEM_NOTIFICATION_HELPER_H_
diff --git a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
index 3fee001..64eae3f 100644
--- a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
+++ b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
@@ -276,11 +276,8 @@
   gcm::GCMDriver* gcm_driver =
       gcm::GCMProfileServiceFactory::GetForProfile(profile)->driver();
 
-  OAuth2TokenService* token_service =
-      ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
-
-  SigninManagerBase* signin_manager =
-      SigninManagerFactory::GetForProfile(profile);
+  identity::IdentityManager* identity_manager =
+      IdentityManagerFactory::GetForProfile(profile);
 
   scoped_refptr<net::URLRequestContextGetter> request_context =
       content::BrowserContext::GetDefaultStoragePartition(profile)
@@ -296,9 +293,8 @@
   }
 
   auto subscription_manager = base::MakeUnique<SubscriptionManagerImpl>(
-      request_context, pref_service, variations_service, signin_manager,
-      token_service, api_key, locale,
-      GetPushUpdatesSubscriptionEndpoint(chrome::GetChannel()),
+      request_context, pref_service, variations_service, identity_manager,
+      api_key, locale, GetPushUpdatesSubscriptionEndpoint(chrome::GetChannel()),
       GetPushUpdatesUnsubscriptionEndpoint(chrome::GetChannel()));
 
   instance_id::InstanceIDProfileService* instance_id_profile_service =
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index d409469..60b8e50 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -707,8 +707,7 @@
     Profile* profile) {
   // Only annotate PasswordState onto the navigation entry if user is
   // opted into UMA and they're not syncing w/ a custom passphrase.
-  if (!ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-          g_browser_process->local_state()))
+  if (!ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled())
     return false;
 
   browser_sync::ProfileSyncService* profile_sync_service =
diff --git a/chrome/browser/permissions/permission_request_impl.cc b/chrome/browser/permissions/permission_request_impl.cc
index d318a08..a716bb8 100644
--- a/chrome/browser/permissions/permission_request_impl.cc
+++ b/chrome/browser/permissions/permission_request_impl.cc
@@ -53,7 +53,7 @@
     case CONTENT_SETTINGS_TYPE_ACCESSIBILITY_EVENTS:
       return IDR_ANDROID_INFOBAR_ACCESSIBILITY_EVENTS;
     case CONTENT_SETTINGS_TYPE_CLIPBOARD_READ:
-      return IDR_ANDROID_INFOBAR_WARNING;
+      return IDR_ANDROID_INFOBAR_CLIPBOARD;
     default:
       NOTREACHED();
       return IDR_ANDROID_INFOBAR_WARNING;
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index 41528d6..4ba8a08 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -2660,9 +2660,10 @@
   GURL first_url = embedded_test_server()->GetURL("/client-redirect?" +
                                                   redirected_url.spec());
 
-  ui_test_utils::NavigateToURL(browser(), first_url);
-  content::WaitForLoadStop(
-      browser()->tab_strip_model()->GetActiveWebContents());
+  // There are two navigations: one when loading client-redirect.html and
+  // another when the document redirects using http-equiv="refresh".
+  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(),
+                                                            first_url, 2);
   EXPECT_EQ(base::ASCIIToUTF16("Redirected!"),
             browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
 
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 01fafe8..32203e8c 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -271,6 +271,7 @@
 #if defined(OS_WIN)
 #include "chrome/browser/apps/app_launch_for_metro_restart_win.h"
 #include "chrome/browser/component_updater/sw_reporter_installer_win.h"
+#include "chrome/browser/conflicts/problematic_programs_updater_win.h"
 #include "chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.h"
 #include "chrome/browser/safe_browsing/settings_reset_prompt/settings_reset_prompt_prefs_manager.h"
 #include "chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util.h"
@@ -464,6 +465,7 @@
   component_updater::RegisterPrefsForSwReporter(registry);
   desktop_ios_promotion::RegisterLocalPrefs(registry);
   password_manager::PasswordManager::RegisterLocalPrefs(registry);
+  ProblematicProgramsUpdater::RegisterLocalStatePrefs(registry);
 #endif
 
 #if defined(TOOLKIT_VIEWS)
diff --git a/chrome/browser/profile_resetter/triggered_profile_resetter_win_unittest.cc b/chrome/browser/profile_resetter/triggered_profile_resetter_win_unittest.cc
index 464c114..437db27 100644
--- a/chrome/browser/profile_resetter/triggered_profile_resetter_win_unittest.cc
+++ b/chrome/browser/profile_resetter/triggered_profile_resetter_win_unittest.cc
@@ -31,9 +31,8 @@
         override_manager_.OverrideRegistry(HKEY_CURRENT_USER));
 
     // Activate the triggered reset field trial for these tests.
-    field_trial_list_.reset(
-        new base::FieldTrialList(
-            base::MakeUnique<metrics::SHA1EntropyProvider>("foo")));
+    field_trial_list_.reset(new base::FieldTrialList(
+        base::MakeUnique<variations::SHA1EntropyProvider>("foo")));
     base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial(
         "TriggeredResetFieldTrial", "On");
     trial->group();
diff --git a/chrome/browser/profiling_host/background_profiling_triggers.cc b/chrome/browser/profiling_host/background_profiling_triggers.cc
index d9f624c2..c88f9fbf 100644
--- a/chrome/browser/profiling_host/background_profiling_triggers.cc
+++ b/chrome/browser/profiling_host/background_profiling_triggers.cc
@@ -82,8 +82,7 @@
 }
 
 bool BackgroundProfilingTriggers::IsAllowedToUpload() const {
-  if (!ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-          g_browser_process->local_state())) {
+  if (!ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled()) {
     return false;
   }
 
diff --git a/chrome/browser/recovery/recovery_install_global_error.cc b/chrome/browser/recovery/recovery_install_global_error.cc
index bd68103..27db27b 100644
--- a/chrome/browser/recovery/recovery_install_global_error.cc
+++ b/chrome/browser/recovery/recovery_install_global_error.cc
@@ -15,6 +15,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/chromium_strings.h"
+#include "chrome/grit/generated_resources.h"
 #include "components/prefs/pref_service.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/paint_vector_icon.h"
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc
index b6b84220..3ba3a23 100644
--- a/chrome/browser/renderer_host/chrome_render_message_filter.cc
+++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc
@@ -304,7 +304,6 @@
 
 #if BUILDFLAG(ENABLE_PLUGINS)
 void ChromeRenderMessageFilter::OnIsCrashReportingEnabled(bool* enabled) {
-  *enabled = ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-      g_browser_process->local_state());
+  *enabled = ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled();
 }
 #endif
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
index f76f5f8..b78c47f3 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
@@ -318,6 +318,8 @@
    * @return {boolean} True if evt was processed.
    */
   onBrailleKeyEvent: function(evt, content) {
+    // Note: panning within content occurs earlier in event dispatch.
+    Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH);
     switch (evt.command) {
       case cvox.BrailleKeyCommand.PAN_LEFT:
         CommandHandler.onCommand('previousObject');
@@ -467,6 +469,7 @@
    * @private
    */
   onAccessibilityGesture_: function(gesture) {
+    Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH);
     var command = Background.GESTURE_COMMAND_MAP[gesture];
     if (command)
       CommandHandler.onCommand(command);
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js
index 1ceb4a3..e7e1c391 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/command_handler.js
@@ -252,7 +252,8 @@
   var dir = Dir.FORWARD;
   var pred = null;
   var predErrorMsg = undefined;
-  var rootPred = AutomationPredicate.root;
+  var rootPred = AutomationPredicate.editableRoot;
+  var shouldWrap = true;
   var speechProps = {};
   var skipSync = false;
   var didNavigate = false;
@@ -619,6 +620,7 @@
           current.start.node, tableOpts);
       predErrorMsg = 'no_cell_above';
       rootPred = AutomationPredicate.table;
+      shouldWrap = false;
       break;
     case 'previousCol':
       dir = Dir.BACKWARD;
@@ -627,6 +629,7 @@
           current.start.node, tableOpts);
       predErrorMsg = 'no_cell_left';
       rootPred = AutomationPredicate.row;
+      shouldWrap = false;
       break;
     case 'nextRow':
       var tableOpts = {row: true, dir: dir};
@@ -634,6 +637,7 @@
           current.start.node, tableOpts);
       predErrorMsg = 'no_cell_below';
       rootPred = AutomationPredicate.table;
+      shouldWrap = false;
       break;
     case 'nextCol':
       var tableOpts = {col: true, dir: dir};
@@ -641,6 +645,7 @@
           current.start.node, tableOpts);
       predErrorMsg = 'no_cell_right';
       rootPred = AutomationPredicate.row;
+      shouldWrap = false;
       break;
     case 'goToRowFirstCell':
     case 'goToRowLastCell':
@@ -668,6 +673,7 @@
       // Should not be outputted.
       predErrorMsg = 'no_cell_above';
       rootPred = AutomationPredicate.table;
+      shouldWrap = false;
       break;
     case 'goToColLastCell':
       dir = Dir.BACKWARD;
@@ -683,6 +689,7 @@
       // Should not be outputted.
       predErrorMsg = 'no_cell_below';
       rootPred = AutomationPredicate.table;
+      shouldWrap = false;
       break;
     case 'goToFirstCell':
     case 'goToLastCell':
@@ -710,8 +717,7 @@
     var bound = current.getBound(dir).node;
     if (bound) {
       var node = AutomationUtil.findNextNode(
-          bound, dir, pred,
-          {skipInitialAncestry: true, root: AutomationPredicate.editableRoot});
+          bound, dir, pred, {skipInitialAncestry: true, root: rootPred});
 
       if (node && !skipSync) {
         node = AutomationUtil.findNodePre(
@@ -723,6 +729,16 @@
         current = cursors.Range.fromNode(node);
       } else {
         cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.WRAP);
+        if (!shouldWrap) {
+          if (predErrorMsg) {
+            new Output()
+                .withString(Msgs.getMsg(predErrorMsg))
+                .withQueueMode(cvox.QueueMode.FLUSH)
+                .go();
+          }
+          return false;
+        }
+
         var root = bound;
         while (root && !AutomationPredicate.editableRoot(root))
           root = root.parent;
@@ -737,10 +753,8 @@
                       root, dir, AutomationPredicate.leaf) ||
               bound;
         }
-        node = AutomationUtil.findNextNode(bound, dir, pred, {
-          skipInitialAncestry: true,
-          root: AutomationPredicate.editableRoot
-        });
+        node = AutomationUtil.findNextNode(
+            bound, dir, pred, {skipInitialAncestry: true, root: rootPred});
 
         if (node && !skipSync) {
           node = AutomationUtil.findNodePre(
@@ -751,8 +765,10 @@
         if (node) {
           current = cursors.Range.fromNode(node);
         } else if (predErrorMsg) {
-          cvox.ChromeVox.tts.speak(
-              Msgs.getMsg(predErrorMsg), cvox.QueueMode.FLUSH);
+          new Output()
+              .withString(Msgs.getMsg(predErrorMsg))
+              .withQueueMode(cvox.QueueMode.FLUSH)
+              .go();
           return false;
         }
       }
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
index e06f7926..9a7143f 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
@@ -159,10 +159,6 @@
     var prev = ChromeVoxState.instance.currentRange;
     if (prev.contentEquals(cursors.Range.fromNode(evt.target)) ||
         evt.target.state.focused) {
-      // Category flush here since previous focus events via navigation can
-      // cause double speak.
-      Output.forceModeForNextSpeechUtterance(cvox.QueueMode.CATEGORY_FLUSH);
-
       // Intentionally skip setting range.
       new Output()
           .withRichSpeechAndBraille(
@@ -183,14 +179,6 @@
   /**
    * @param {!AutomationEvent} evt
    */
-  onEventWithFlushedOutput: function(evt) {
-    Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH);
-    this.onEventDefault(evt);
-  },
-
-  /**
-   * @param {!AutomationEvent} evt
-   */
   onAriaAttributeChanged: function(evt) {
     if (evt.target.state.editable)
       return;
@@ -284,7 +272,6 @@
     if (!AutomationPredicate.checkable(evt.target))
       return;
 
-    Output.forceModeForNextSpeechUtterance(cvox.QueueMode.CATEGORY_FLUSH);
     var event = new CustomAutomationEvent(
         EventType.CHECKED_STATE_CHANGED, evt.target, evt.eventFrom);
     this.onEventIfInRange(event);
@@ -327,10 +314,6 @@
     if (node.role == RoleType.EMBEDDED_OBJECT || node.role == RoleType.WEB_VIEW)
       return;
 
-    // Category flush speech triggered by events with no source. This includes
-    // views.
-    if (evt.eventFrom == '')
-      Output.forceModeForNextSpeechUtterance(cvox.QueueMode.CATEGORY_FLUSH);
     if (!node.root)
       return;
 
@@ -363,7 +346,6 @@
 
       if (focusIsAncestor) {
         focus = evt.target;
-        Output.forceModeForNextSpeechUtterance(cvox.QueueMode.CATEGORY_FLUSH);
       }
 
       // Create text edit handler, if needed, now in order not to miss initial
@@ -506,7 +488,6 @@
       var override = evt.target.role == RoleType.MENU_ITEM ||
           (evt.target.root == focus.root &&
            focus.root.role == RoleType.DESKTOP);
-      Output.forceModeForNextSpeechUtterance(cvox.QueueMode.CATEGORY_FLUSH);
       if (override || AutomationUtil.isDescendantOf(evt.target, focus))
         this.onEventDefault(evt);
     }.bind(this));
@@ -623,7 +604,6 @@
 
     ChromeVoxState.instance.setCurrentRange(cursors.Range.fromNode(focus));
 
-    Output.forceModeForNextSpeechUtterance(cvox.QueueMode.CATEGORY_FLUSH);
     o.withRichSpeechAndBraille(
          ChromeVoxState.instance.currentRange, null, evt.type)
         .go();
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/keyboard_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/keyboard_handler.js
index 2bd3034..13c0068 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/keyboard_handler.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/keyboard_handler.js
@@ -40,12 +40,12 @@
     if (cvox.ChromeVox.passThroughMode)
       return false;
 
+    Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH);
     if (!cvox.ChromeVoxKbHandler.basicKeyDownActionsListener(evt)) {
       evt.preventDefault();
       evt.stopPropagation();
       this.eatenKeyDowns_.add(evt.keyCode);
     }
-    Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH);
     return false;
   },
 
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
index c058820..c7d7f28 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
@@ -870,11 +870,11 @@
   go: function() {
     // Speech.
     var queueMode = cvox.QueueMode.CATEGORY_FLUSH;
-    if (this.queueMode_ !== undefined) {
-      queueMode = /** @type{cvox.QueueMode} */ (this.queueMode_);
-    } else if (Output.forceModeForNextSpeechUtterance_ !== undefined) {
+    if (Output.forceModeForNextSpeechUtterance_ !== undefined) {
       queueMode = /** @type{cvox.QueueMode} */ (
           Output.forceModeForNextSpeechUtterance_);
+    } else if (this.queueMode_ !== undefined) {
+      queueMode = /** @type{cvox.QueueMode} */ (this.queueMode_);
     }
 
     if (this.speechBuffer_.length > 0)
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js
index 98bdab6..2dd21fa 100644
--- a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js
+++ b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js
@@ -294,10 +294,7 @@
     /** @private */
     showExportPasswords_: {
       type: Boolean,
-      value: function() {
-        return loadTimeData.valueExists('showExportPasswords') &&
-            loadTimeData.getBoolean('showExportPasswords');
-      }
+      computed: 'showExportPasswordsAndReady_(savedPasswords)'
     },
 
     /** @private */
@@ -582,6 +579,16 @@
 
   /**
    * @private
+   * @param {!Array<!PasswordManager.PasswordUiEntry>} savedPasswords
+   */
+  showExportPasswordsAndReady_: function(savedPasswords) {
+    return loadTimeData.valueExists('showExportPasswords') &&
+        loadTimeData.getBoolean('showExportPasswords') &&
+        savedPasswords.length > 0;
+  },
+
+  /**
+   * @private
    * @param {boolean} showExportPasswords
    * @param {boolean} showImportPasswords
    * @return {boolean}
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc
index 0c87139..d7e89945 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc
@@ -195,8 +195,7 @@
 }
 
 bool ChromeCleanerControllerDelegate::IsMetricsAndCrashReportingEnabled() {
-  return ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-      g_browser_process->local_state());
+  return ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled();
 }
 
 void ChromeCleanerControllerDelegate::TagForResetting(Profile* profile) {
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc
index 00b81a3..323ab2f 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc
@@ -900,8 +900,7 @@
       invocation->set_reporter_logs_upload_enabled(false);
     }
 
-    if (ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-            local_state)) {
+    if (ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled()) {
       invocation->mutable_command_line().AppendSwitch(
           chrome_cleaner::kEnableCrashReportingSwitch);
     }
diff --git a/chrome/browser/safe_browsing/download_protection/download_url_sb_client.cc b/chrome/browser/safe_browsing/download_protection/download_url_sb_client.cc
index a41ae90..7b97d19 100644
--- a/chrome/browser/safe_browsing/download_protection/download_url_sb_client.cc
+++ b/chrome/browser/safe_browsing/download_protection/download_url_sb_client.cc
@@ -6,7 +6,6 @@
 
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_number_conversions.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/safe_browsing/download_protection/download_protection_service.h"
@@ -120,8 +119,7 @@
   hit_report.post_data = post_data;
   hit_report.extended_reporting_level = extended_reporting_level_;
   hit_report.is_metrics_reporting_active =
-      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-          g_browser_process->local_state());
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled();
 
   ui_manager_->MaybeReportSafeBrowsingHit(hit_report, item_->GetWebContents());
 }
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
index f4cffcf..6b704cd 100644
--- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
@@ -22,7 +22,6 @@
 #include "base/task_scheduler/task_traits.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 #include "chrome/browser/profiles/profile.h"
@@ -825,8 +824,7 @@
       report->mutable_environment()->mutable_process();
 
   process->set_metrics_consent(
-      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-          g_browser_process->local_state()));
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
 
   // Associate process-wide incidents with any eligible profile. If there is no
   // eligible profile, drop the incidents.
diff --git a/chrome/browser/safe_browsing/ui_manager.cc b/chrome/browser/safe_browsing/ui_manager.cc
index 65f7fd7..83f3da7 100644
--- a/chrome/browser/safe_browsing/ui_manager.cc
+++ b/chrome/browser/safe_browsing/ui_manager.cc
@@ -90,8 +90,7 @@
       profile ? GetExtendedReportingLevel(*profile->GetPrefs())
               : SBER_LEVEL_OFF;
   hit_report.is_metrics_reporting_active =
-      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-          g_browser_process->local_state());
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled();
 
   MaybeReportSafeBrowsingHit(hit_report, web_contents);
 
diff --git a/chrome/browser/search/instant_unittest_base.cc b/chrome/browser/search/instant_unittest_base.cc
index 014ed8c8..4c80ca3 100644
--- a/chrome/browser/search/instant_unittest_base.cc
+++ b/chrome/browser/search/instant_unittest_base.cc
@@ -27,7 +27,7 @@
 
 InstantUnitTestBase::InstantUnitTestBase() {
   field_trial_list_.reset(new base::FieldTrialList(
-      base::MakeUnique<metrics::SHA1EntropyProvider>("42")));
+      base::MakeUnique<variations::SHA1EntropyProvider>("42")));
 }
 
 InstantUnitTestBase::~InstantUnitTestBase() {
diff --git a/chrome/browser/signin/easy_unlock_notification_controller_chromeos.cc b/chrome/browser/signin/easy_unlock_notification_controller_chromeos.cc
index be6948c..da1a3a4 100644
--- a/chrome/browser/signin/easy_unlock_notification_controller_chromeos.cc
+++ b/chrome/browser/signin/easy_unlock_notification_controller_chromeos.cc
@@ -15,7 +15,6 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/chromeos/devicetype_utils.h"
-#include "ui/message_center/message_center_types.h"
 #include "ui/message_center/public/cpp/notification_types.h"
 
 namespace {
diff --git a/chrome/browser/site_details_browsertest.cc b/chrome/browser/site_details_browsertest.cc
index da97313..065f95ac 100644
--- a/chrome/browser/site_details_browsertest.cc
+++ b/chrome/browser/site_details_browsertest.cc
@@ -28,7 +28,6 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/metrics/metrics_service.h"
-#include "components/variations/metrics_util.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/common/content_switches.h"
diff --git a/chrome/browser/speech/speech_recognizer.cc b/chrome/browser/speech/speech_recognizer.cc
index 77bc7aca..4549d7b 100644
--- a/chrome/browser/speech/speech_recognizer.cc
+++ b/chrome/browser/speech/speech_recognizer.cc
@@ -58,7 +58,7 @@
   friend class base::RefCountedThreadSafe<SpeechRecognizer::EventListener>;
   ~EventListener() override;
 
-  void NotifyRecognitionStateChanged(SpeechRecognizerState new_state);
+  void NotifyRecognitionStateChanged(SpeechRecognizerStatus new_state);
 
   // Starts a timer for |timeout_seconds|. When the timer expires, will stop
   // capturing audio and get a final utterance from the recognition manager.
@@ -161,7 +161,7 @@
 }
 
 void SpeechRecognizer::EventListener::NotifyRecognitionStateChanged(
-    SpeechRecognizerState new_state) {
+    SpeechRecognizerStatus new_state) {
   content::BrowserThread::PostTask(
       content::BrowserThread::UI, FROM_HERE,
       base::Bind(&SpeechRecognizerDelegate::OnSpeechRecognitionStateChanged,
diff --git a/chrome/browser/speech/speech_recognizer_browsertest.cc b/chrome/browser/speech/speech_recognizer_browsertest.cc
index 7d7df1ed..1e653f5 100644
--- a/chrome/browser/speech/speech_recognizer_browsertest.cc
+++ b/chrome/browser/speech/speech_recognizer_browsertest.cc
@@ -35,7 +35,7 @@
 
   MOCK_METHOD2(OnSpeechResult, void(const base::string16&, bool));
   MOCK_METHOD1(OnSpeechSoundLevelChanged, void(int16_t));
-  MOCK_METHOD1(OnSpeechRecognitionStateChanged, void(SpeechRecognizerState));
+  MOCK_METHOD1(OnSpeechRecognitionStateChanged, void(SpeechRecognizerStatus));
   MOCK_METHOD2(GetSpeechAuthParameters, void(std::string*, std::string*));
 
  private:
diff --git a/chrome/browser/speech/speech_recognizer_delegate.h b/chrome/browser/speech/speech_recognizer_delegate.h
index 82cdcfc..cd46682 100644
--- a/chrome/browser/speech/speech_recognizer_delegate.h
+++ b/chrome/browser/speech/speech_recognizer_delegate.h
@@ -11,7 +11,7 @@
 #include "base/strings/string16.h"
 
 // Requires cleanup. See crbug.com/800374.
-enum SpeechRecognizerState {
+enum SpeechRecognizerStatus {
   SPEECH_RECOGNIZER_OFF = 0,
   SPEECH_RECOGNIZER_READY,
   SPEECH_RECOGNIZER_RECOGNIZING,
@@ -34,7 +34,7 @@
 
   // Invoked when the state of speech recognition is changed.
   virtual void OnSpeechRecognitionStateChanged(
-      SpeechRecognizerState new_state) = 0;
+      SpeechRecognizerStatus new_state) = 0;
 
   // Get the OAuth2 scope and token to pass to the speech recognizer. Does not
   // modify the arguments if no auth token is available or allowed.
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 53b9827..92afdec 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -2110,6 +2110,7 @@
       "//ash",
       "//ash:ash_with_content",
       "//ash/public/cpp",
+      "//ash/public/cpp/vector_icons",
       "//ash/resources/vector_icons",
       "//ash/strings",
       "//chrome/browser/chromeos",
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.h b/chrome/browser/ui/app_list/app_list_model_updater.h
index 71e783542..c52867bb 100644
--- a/chrome/browser/ui/app_list/app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/app_list_model_updater.h
@@ -84,6 +84,9 @@
       base::OnceCallback<void(const std::unordered_map<std::string, size_t>&)>;
   virtual void GetIdToAppListIndexMap(GetIdToAppListIndexMapCallback callback) {
   }
+  virtual void ContextMenuItemSelected(const std::string& id,
+                                       int command_id,
+                                       int event_flags) {}
 
   // Methods for AppListSyncableService:
   virtual void AddItemToOemFolder(
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.cc b/chrome/browser/ui/app_list/app_list_view_delegate.cc
index 2d4810f..4eaa263 100644
--- a/chrome/browser/ui/app_list/app_list_view_delegate.cc
+++ b/chrome/browser/ui/app_list/app_list_view_delegate.cc
@@ -12,6 +12,7 @@
 #include "ash/app_list/model/app_list_model.h"
 #include "ash/app_list/model/app_list_view_state.h"
 #include "ash/app_list/model/search/search_model.h"
+#include "ash/public/cpp/menu_utils.h"
 #include "ash/public/interfaces/constants.mojom.h"
 #include "base/command_line.h"
 #include "base/metrics/histogram_functions.h"
@@ -211,16 +212,25 @@
 }
 
 void AppListViewDelegate::GetWallpaperProminentColors(
-    std::vector<SkColor>* colors) {
-  *colors = wallpaper_prominent_colors_;
+    GetWallpaperProminentColorsCallback callback) {
+  std::move(callback).Run(wallpaper_prominent_colors_);
 }
 
 void AppListViewDelegate::ActivateItem(const std::string& id, int event_flags) {
   model_updater_->ActivateChromeItem(id, event_flags);
 }
 
-ui::MenuModel* AppListViewDelegate::GetContextMenuModel(const std::string& id) {
-  return model_updater_->GetContextMenuModel(id);
+void AppListViewDelegate::GetContextMenuModel(
+    const std::string& id,
+    GetContextMenuModelCallback callback) {
+  ui::MenuModel* menu = model_updater_->GetContextMenuModel(id);
+  std::move(callback).Run(ash::menu_utils::GetMojoMenuItemsFromModel(menu));
+}
+
+void AppListViewDelegate::ContextMenuItemSelected(const std::string& id,
+                                                  int command_id,
+                                                  int event_flags) {
+  model_updater_->ContextMenuItemSelected(id, command_id, event_flags);
 }
 
 void AppListViewDelegate::AddObserver(
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.h b/chrome/browser/ui/app_list/app_list_view_delegate.h
index 13f13f92..05458098 100644
--- a/chrome/browser/ui/app_list/app_list_view_delegate.h
+++ b/chrome/browser/ui/app_list/app_list_view_delegate.h
@@ -70,9 +70,14 @@
   void ViewShown() override;
   void Dismiss() override;
   void ViewClosing() override;
-  void GetWallpaperProminentColors(std::vector<SkColor>* colors) override;
+  void GetWallpaperProminentColors(
+      GetWallpaperProminentColorsCallback callback) override;
   void ActivateItem(const std::string& id, int event_flags) override;
-  ui::MenuModel* GetContextMenuModel(const std::string& id) override;
+  void GetContextMenuModel(const std::string& id,
+                           GetContextMenuModelCallback callback) override;
+  void ContextMenuItemSelected(const std::string& id,
+                               int command_id,
+                               int event_flags) override;
   void AddObserver(app_list::AppListViewDelegateObserver* observer) override;
   void RemoveObserver(app_list::AppListViewDelegateObserver* observer) override;
 
diff --git a/chrome/browser/ui/app_list/arc/arc_app_item.cc b/chrome/browser/ui/app_list/arc/arc_app_item.cc
index 8c4e0bc..ea63aac 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_item.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_item.cc
@@ -84,3 +84,7 @@
                                             GetController()));
   return context_menu_->GetMenuModel();
 }
+
+app_list::AppContextMenu* ArcAppItem::GetAppContextMenu() {
+  return context_menu_.get();
+}
diff --git a/chrome/browser/ui/app_list/arc/arc_app_item.h b/chrome/browser/ui/app_list/arc/arc_app_item.h
index 038748fe..3ede972b 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_item.h
+++ b/chrome/browser/ui/app_list/arc/arc_app_item.h
@@ -49,6 +49,9 @@
   // Updates the app item's icon, if necessary making it gray.
   void UpdateIcon();
 
+  // ChromeAppListItem overrides:
+  app_list::AppContextMenu* GetAppContextMenu() override;
+
   std::unique_ptr<ArcAppIcon> arc_app_icon_;
   std::unique_ptr<ArcAppContextMenu> context_menu_;
 
diff --git a/chrome/browser/ui/app_list/chrome_app_list_item.cc b/chrome/browser/ui/app_list/chrome_app_list_item.cc
index 29489de..466e8f6e 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_item.cc
+++ b/chrome/browser/ui/app_list/chrome_app_list_item.cc
@@ -92,6 +92,16 @@
   return false;
 }
 
+app_list::AppContextMenu* ChromeAppListItem::GetAppContextMenu() {
+  return nullptr;
+}
+
+void ChromeAppListItem::ContextMenuItemSelected(int command_id,
+                                                int event_flags) {
+  if (GetAppContextMenu())
+    GetAppContextMenu()->ExecuteCommand(command_id, event_flags);
+}
+
 extensions::AppSorting* ChromeAppListItem::GetAppSorting() {
   return extensions::ExtensionSystem::Get(profile())->app_sorting();
 }
diff --git a/chrome/browser/ui/app_list/chrome_app_list_item.h b/chrome/browser/ui/app_list/chrome_app_list_item.h
index 77a93a0..fb6a0d3 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_item.h
+++ b/chrome/browser/ui/app_list/chrome_app_list_item.h
@@ -10,6 +10,7 @@
 #include <utility>
 
 #include "base/macros.h"
+#include "chrome/browser/ui/app_list/app_context_menu.h"
 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
 #include "ui/gfx/image/image_skia.h"
 
@@ -79,6 +80,9 @@
   // has its Android analog installed.
   virtual bool IsBadged() const;
 
+  // Invoked when a context menu item of this item is selected.
+  void ContextMenuItemSelected(int command_id, int event_flags);
+
   bool CompareForTest(const ChromeAppListItem* other) const;
 
   std::string ToDebugString() const;
@@ -107,6 +111,10 @@
   // Set the default position if it exists.
   void SetDefaultPositionIfApplicable();
 
+  // Get the context menu of a certain app. This could be different for
+  // different kinds of items.
+  virtual app_list::AppContextMenu* GetAppContextMenu();
+
   // The following methods set Chrome side data here, and call model updater
   // interfaces that talk to ash directly.
   void SetIcon(const gfx::ImageSkia& icon);
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
index 6ec6a9b0..eb85384a 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
+++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -230,6 +230,14 @@
   return count;
 }
 
+void ChromeAppListModelUpdater::ContextMenuItemSelected(const std::string& id,
+                                                        int command_id,
+                                                        int event_flags) {
+  ChromeAppListItem* chrome_item = FindItem(id);
+  if (chrome_item)
+    chrome_item->ContextMenuItemSelected(command_id, event_flags);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Methods for AppListSyncableService
 
@@ -436,5 +444,10 @@
   std::unique_ptr<app_list::AppListItem> ash_app_list_item =
       std::make_unique<app_list::AppListItem>(metadata->id);
   ash_app_list_item->SetMetadata(std::move(metadata));
+
+  ChromeAppListItem* chrome_app_item = FindItem(ash_app_list_item->id());
+  if (chrome_app_item && !chrome_app_item->icon().isNull())
+    ash_app_list_item->SetIcon(chrome_app_item->icon());
+
   return ash_app_list_item;
 }
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
index e67cbad3..8b72925 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
@@ -76,6 +76,9 @@
   void GetIdToAppListIndexMap(GetIdToAppListIndexMapCallback callback) override;
   size_t BadgedItemCount() override;
   ui::MenuModel* GetContextMenuModel(const std::string& id);
+  void ContextMenuItemSelected(const std::string& id,
+                               int command_id,
+                               int event_flags) override;
 
   // Methods for AppListSyncableService:
   void AddItemToOemFolder(
diff --git a/chrome/browser/ui/app_list/extension_app_item.cc b/chrome/browser/ui/app_list/extension_app_item.cc
index af650f1..d041fc8 100644
--- a/chrome/browser/ui/app_list/extension_app_item.cc
+++ b/chrome/browser/ui/app_list/extension_app_item.cc
@@ -184,6 +184,10 @@
   return icon_ && icon_->icon_is_badged();
 }
 
+app_list::AppContextMenu* ExtensionAppItem::GetAppContextMenu() {
+  return context_menu_.get();
+}
+
 void ExtensionAppItem::ExecuteLaunchCommand(int event_flags) {
   Launch(event_flags);
 }
diff --git a/chrome/browser/ui/app_list/extension_app_item.h b/chrome/browser/ui/app_list/extension_app_item.h
index 03644b0..221904a 100644
--- a/chrome/browser/ui/app_list/extension_app_item.h
+++ b/chrome/browser/ui/app_list/extension_app_item.h
@@ -79,6 +79,7 @@
   ui::MenuModel* GetContextMenuModel() override;
   const char* GetItemType() const override;
   bool IsBadged() const override;
+  app_list::AppContextMenu* GetAppContextMenu() override;
 
   // Overridden from app_list::AppContextMenuDelegate:
   void ExecuteLaunchCommand(int event_flags) override;
diff --git a/chrome/browser/ui/app_list/search/common/url_icon_source.cc b/chrome/browser/ui/app_list/search/common/url_icon_source.cc
index 8f142e7..b551cc1 100644
--- a/chrome/browser/ui/app_list/search/common/url_icon_source.cc
+++ b/chrome/browser/ui/app_list/search/common/url_icon_source.cc
@@ -10,10 +10,10 @@
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/storage_partition.h"
-#include "content/public/common/simple_url_loader.h"
 #include "net/base/load_flags.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/simple_url_loader.h"
 #include "services/network/public/interfaces/url_loader_factory.mojom.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/image/image_skia_operations.h"
@@ -65,7 +65,7 @@
             policy_exception_justification:
               "Not implemented, considered not useful."
           })");
-  simple_loader_ = content::SimpleURLLoader::Create(std::move(resource_request),
+  simple_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
                                                     traffic_annotation);
   network::mojom::URLLoaderFactory* loader_factory =
       content::BrowserContext::GetDefaultStoragePartition(browser_context_)
diff --git a/chrome/browser/ui/app_list/search/common/url_icon_source.h b/chrome/browser/ui/app_list/search/common/url_icon_source.h
index 4f5c8d1b..153b92a 100644
--- a/chrome/browser/ui/app_list/search/common/url_icon_source.h
+++ b/chrome/browser/ui/app_list/search/common/url_icon_source.h
@@ -18,6 +18,9 @@
 
 namespace content {
 class BrowserContext;
+}
+
+namespace network {
 class SimpleURLLoader;
 }
 
@@ -61,7 +64,7 @@
   const int default_icon_resource_id_;
 
   bool icon_fetch_attempted_;
-  std::unique_ptr<content::SimpleURLLoader> simple_loader_;
+  std::unique_ptr<network::SimpleURLLoader> simple_loader_;
 
   gfx::ImageSkia icon_;
 
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
index c0bcbcf..5e639428 100644
--- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
+++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
@@ -20,6 +20,7 @@
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/ash_config.h"
+#include "chrome/browser/chromeos/docked_magnifier/docked_magnifier_client.h"
 #include "chrome/browser/chromeos/night_light/night_light_client.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/ash/accessibility/accessibility_controller_client.h"
@@ -278,6 +279,11 @@
         g_browser_process->system_request_context());
     night_light_client_->Start();
   }
+
+  if (ash::switches::IsDockedMagnifierEnabled()) {
+    docked_magnifier_client_ = std::make_unique<DockedMagnifierClient>();
+    docked_magnifier_client_->Start();
+  }
 }
 
 void ChromeBrowserMainExtraPartsAsh::PostMainMessageLoopRun() {
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h
index 291f983..60ebb50 100644
--- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h
+++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h
@@ -26,6 +26,7 @@
 class ChromeNewWindowClient;
 class ChromeShellContentState;
 class DataPromoNotification;
+class DockedMagnifierClient;
 class ImeControllerClient;
 class ImmersiveContextMus;
 class ImmersiveHandlerFactoryMus;
@@ -107,6 +108,7 @@
   // Initialized in PostBrowserStart in all configs:
   std::unique_ptr<DataPromoNotification> data_promo_notification_;
   std::unique_ptr<NightLightClient> night_light_client_;
+  std::unique_ptr<DockedMagnifierClient> docked_magnifier_client_;
 
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsAsh);
 };
diff --git a/chrome/browser/ui/ash/chrome_screenshot_grabber_browsertest.cc b/chrome/browser/ui/ash/chrome_screenshot_grabber_browsertest.cc
index a08d6eb..af5d4af 100644
--- a/chrome/browser/ui/ash/chrome_screenshot_grabber_browsertest.cc
+++ b/chrome/browser/ui/ash/chrome_screenshot_grabber_browsertest.cc
@@ -19,7 +19,6 @@
 #include "ui/base/clipboard/clipboard.h"
 #include "ui/base/clipboard/clipboard_monitor.h"
 #include "ui/base/clipboard/clipboard_observer.h"
-#include "ui/message_center/message_center_observer.h"
 
 class ChromeScreenshotGrabberBrowserTest
     : public InProcessBrowserTest,
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
index c30e435..41c1bf2 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -3888,8 +3888,8 @@
   // opposite order. Last created goes in front.
   ash::MenuItemList items = item_delegate->GetAppMenuItems(0);
   ASSERT_EQ(items.size(), 2U);
-  EXPECT_EQ(items[0]->command_id, 0U);
-  EXPECT_EQ(items[1]->command_id, 1U);
+  EXPECT_EQ(items[0]->command_id, 0);
+  EXPECT_EQ(items[1]->command_id, 1);
 
   // Execute command to activate first window.
   item_delegate->ExecuteCommand(false, items[1]->command_id, ui::EF_NONE,
diff --git a/chrome/browser/ui/ash/network/network_state_notifier.cc b/chrome/browser/ui/ash/network/network_state_notifier.cc
index 6e884378..58dde19a 100644
--- a/chrome/browser/ui/ash/network/network_state_notifier.cc
+++ b/chrome/browser/ui/ash/network/network_state_notifier.cc
@@ -12,7 +12,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/chromeos/net/shill_error.h"
-#include "chrome/browser/notifications/notification_display_service.h"
+#include "chrome/browser/notifications/system_notification_helper.h"
 #include "chrome/browser/ui/ash/system_tray_client.h"
 #include "chrome/grit/generated_resources.h"
 #include "chromeos/network/network_configuration_handler.h"
@@ -91,8 +91,7 @@
           GetErrorNotificationVectorIcon(network_type),
           message_center::SystemNotificationWarningLevel::CRITICAL_WARNING);
   notification->set_priority(message_center::SYSTEM_PRIORITY);
-  NotificationDisplayService::GetForSystemNotifications()->Display(
-      NotificationHandler::Type::TRANSIENT, *notification);
+  SystemNotificationHelper::GetInstance()->Display(*notification);
 }
 
 bool ShouldConnectFailedNotificationBeShown(const std::string& error_name,
@@ -288,8 +287,7 @@
           cellular->network_technology() == shill::kNetworkTechnologyLte
               ? IDR_AURA_UBER_TRAY_NETWORK_NOTIFICATION_LTE
               : IDR_AURA_UBER_TRAY_NETWORK_NOTIFICATION_3G);
-  NotificationDisplayService::GetForSystemNotifications()->Display(
-      NotificationHandler::Type::TRANSIENT,
+  SystemNotificationHelper::GetInstance()->Display(
       *message_center::Notification::CreateSystemNotification(
           kNetworkActivateNotificationId,
           l10n_util::GetStringUTF16(IDS_NETWORK_CELLULAR_ACTIVATED_TITLE),
@@ -326,8 +324,7 @@
                    << guid;
     return;
   }
-  NotificationDisplayService::GetForSystemNotifications()->Display(
-      NotificationHandler::Type::TRANSIENT,
+  SystemNotificationHelper::GetInstance()->Display(
       *message_center::Notification::CreateSystemNotification(
           kNetworkActivateNotificationId,
           l10n_util::GetStringUTF16(IDS_NETWORK_ACTIVATION_ERROR_TITLE),
@@ -341,8 +338,7 @@
 }
 
 void NetworkStateNotifier::RemoveConnectNotification() {
-  NotificationDisplayService::GetForSystemNotifications()->Close(
-      NotificationHandler::Type::TRANSIENT, kNetworkConnectNotificationId);
+  SystemNotificationHelper::GetInstance()->Close(kNetworkConnectNotificationId);
 }
 
 void NetworkStateNotifier::ConnectErrorPropertiesSucceeded(
diff --git a/chrome/browser/ui/cocoa/first_run_dialog.mm b/chrome/browser/ui/cocoa/first_run_dialog.mm
index 0b01a37..b27dc8c 100644
--- a/chrome/browser/ui/cocoa/first_run_dialog.mm
+++ b/chrome/browser/ui/cocoa/first_run_dialog.mm
@@ -13,7 +13,6 @@
 #include "base/run_loop.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/first_run/first_run.h"
 #include "chrome/browser/first_run/first_run_dialog.h"
 #include "chrome/browser/metrics/metrics_reporting_state.h"
@@ -72,9 +71,7 @@
   // If the dialog asked the user to opt-in for stats and crash reporting,
   // record the decision and enable the crash reporter if appropriate.
   bool consent_given = [dialog.get() isStatsReportingEnabled];
-  ChangeMetricsReportingState(g_browser_process->local_state(),
-                              g_browser_process->GetMetricsServicesManager(),
-                              consent_given);
+  ChangeMetricsReportingState(consent_given);
 
   // If selected, set as default browser. Skip in automated tests so that an OS
   // dialog confirming the default browser choice isn't left on screen.
diff --git a/chrome/browser/ui/views/first_run_dialog.cc b/chrome/browser/ui/views/first_run_dialog.cc
index 54b1435..ce5f152 100644
--- a/chrome/browser/ui/views/first_run_dialog.cc
+++ b/chrome/browser/ui/views/first_run_dialog.cc
@@ -9,7 +9,6 @@
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/first_run/first_run.h"
 #include "chrome/browser/metrics/metrics_reporting_state.h"
 #include "chrome/browser/platform_util.h"
@@ -115,10 +114,8 @@
 bool FirstRunDialog::Accept() {
   GetWidget()->Hide();
 
-  ChangeMetricsReportingStateWithReply(
-      g_browser_process->local_state(),
-      g_browser_process->GetMetricsServicesManager(),
-      report_crashes_->checked(), base::Bind(&InitCrashReporterIfEnabled));
+  ChangeMetricsReportingStateWithReply(report_crashes_->checked(),
+                                       base::Bind(&InitCrashReporterIfEnabled));
 
   if (make_default_->checked())
     shell_integration::SetAsDefaultBrowser();
diff --git a/chrome/browser/ui/views/frame/browser_frame_header_ash.cc b/chrome/browser/ui/views/frame/browser_frame_header_ash.cc
index ba310be0..f3f3cc58 100644
--- a/chrome/browser/ui/views/frame/browser_frame_header_ash.cc
+++ b/chrome/browser/ui/views/frame/browser_frame_header_ash.cc
@@ -8,7 +8,7 @@
 #include "ash/frame/caption_buttons/frame_caption_button.h"
 #include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
 #include "ash/frame/frame_header_util.h"
-#include "ash/resources/vector_icons/vector_icons.h"
+#include "ash/public/cpp/vector_icons/vector_icons.h"
 #include "base/logging.h"
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/browser.h"
diff --git a/chrome/browser/ui/views/message_center/DEPS b/chrome/browser/ui/views/message_center/DEPS
new file mode 100644
index 0000000..b21e182
--- /dev/null
+++ b/chrome/browser/ui/views/message_center/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+ui/message_center",
+]
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc
index 6fb00e14..161bea5 100644
--- a/chrome/browser/ui/views/session_crashed_bubble_view.cc
+++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -15,7 +15,6 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/task_runner_util.h"
 #include "build/build_config.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/metrics/metrics_reporting_state.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/sessions/session_restore.h"
@@ -148,8 +147,7 @@
   bool offer_uma_optin = false;
 
   if (DoesSupportConsentCheck() && !uma_opted_in_already)
-    offer_uma_optin =
-        !IsMetricsReportingPolicyManaged(g_browser_process->local_state());
+    offer_uma_optin = !IsMetricsReportingPolicyManaged();
 
   Browser* browser = browser_observer->browser();
 
@@ -347,9 +345,7 @@
   // Record user's choice for opt-in in to UMA.
   // There's no opt-out choice in the crash restore bubble.
   if (uma_option_ && uma_option_->checked()) {
-    ChangeMetricsReportingState(g_browser_process->local_state(),
-                                g_browser_process->GetMetricsServicesManager(),
-                                true);
+    ChangeMetricsReportingState(true);
     RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_UMA_OPTIN);
   }
 }
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
index 0bf4821..fa699e8 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -754,7 +754,8 @@
   if (test_expects_complete_login_)
     SubmitLoginFormForTest();
 
-  LoginDisplayHost::default_host()->OnGaiaScreenReady();
+  if (LoginDisplayHost::default_host())
+    LoginDisplayHost::default_host()->OnGaiaScreenReady();
 }
 
 void GaiaScreenHandler::DoCompleteLogin(const std::string& gaia_id,
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 41d6a2e..8b809eb 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -1485,7 +1485,7 @@
     lock_screen_utils::SetUserInputMethod(account_id.GetUserEmail(),
                                           ime_state_.get());
     lock_screen_utils::SetKeyboardSettings(account_id);
-    if (delegate_ && load_wallpaper)
+    if (LoginDisplayHost::default_host() && load_wallpaper)
       LoginDisplayHost::default_host()->LoadWallpaper(account_id);
 
     bool use_24hour_clock = false;
diff --git a/chrome/browser/ui/webui/crashes_ui.cc b/chrome/browser/ui/webui/crashes_ui.cc
index bfb3fb2..d8444cb 100644
--- a/chrome/browser/ui/webui/crashes_ui.cc
+++ b/chrome/browser/ui/webui/crashes_ui.cc
@@ -16,7 +16,6 @@
 #include "base/sys_info.h"
 #include "base/values.h"
 #include "build/build_config.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/crash_upload_list/crash_upload_list.h"
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 #include "chrome/browser/metrics/metrics_reporting_state.h"
@@ -161,8 +160,7 @@
 
 void CrashesDOMHandler::UpdateUI() {
   bool crash_reporting_enabled =
-      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-          g_browser_process->local_state());
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled();
 
   bool system_crash_reporter = false;
 #if defined(OS_CHROMEOS)
@@ -177,8 +175,7 @@
   // Maunal uploads currently are supported only for Crashpad-using platforms
   // and Android, and only if crash uploads are not disabled by policy.
   support_manual_uploads =
-      crash_reporting_enabled ||
-      !IsMetricsReportingPolicyManaged(g_browser_process->local_state());
+      crash_reporting_enabled || !IsMetricsReportingPolicyManaged();
 
   // Show crash reports regardless of |crash_reporting_enabled| so that users
   // can manually upload those reports.
@@ -216,9 +213,8 @@
   DCHECK(success);
 
   // Only allow manual uploads if crash uploads aren’t disabled by policy.
-  if (!ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-          g_browser_process->local_state()) &&
-      IsMetricsReportingPolicyManaged(g_browser_process->local_state())) {
+  if (!ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled() &&
+      IsMetricsReportingPolicyManaged()) {
     return;
   }
   upload_list_->RequestSingleUploadAsync(local_id);
diff --git a/chrome/browser/ui/webui/flash_ui.cc b/chrome/browser/ui/webui/flash_ui.cc
index ea39adcf..f4352f0 100644
--- a/chrome/browser/ui/webui/flash_ui.cc
+++ b/chrome/browser/ui/webui/flash_ui.cc
@@ -26,7 +26,6 @@
 #include "base/timer/timer.h"
 #include "base/values.h"
 #include "build/build_config.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/crash_upload_list/crash_upload_list.h"
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 #include "chrome/browser/plugins/plugin_prefs.h"
@@ -301,8 +300,7 @@
   // Crash information.
   AddPair(list.get(), base::string16(), "--- Crash data ---");
   bool crash_reporting_enabled =
-      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-          g_browser_process->local_state());
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled();
   if (crash_reporting_enabled) {
     std::vector<UploadList::UploadInfo> crashes;
     upload_list_->GetUploads(10, &crashes);
diff --git a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc
index e31861f..0a4eb3c 100644
--- a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc
+++ b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc
@@ -23,18 +23,19 @@
 
 // HTML DOM ID used in the JavaScript code. The IDs are generated here so that
 // the DOM would have sensible name instead of autogenerated IDs.
-const char kAmpRedirectionPreviewsHtmlId[] = "amp-preview-status";
+const char kPreviewsAllowedHtmlId[] = "previews-allowed-status";
 const char kClientLoFiPreviewsHtmlId[] = "client-lofi-preview-status";
 const char kNoScriptPreviewsHtmlId[] = "noscript-preview-status";
 const char kOfflinePreviewsHtmlId[] = "offline-preview-status";
 
 // Descriptions for previews.
-const char kAmpRedirectionDescription[] = "AMP Previews";
+const char kPreviewsAllowedDescription[] = "Previews Allowed";
 const char kClientLoFiDescription[] = "Client LoFi Previews";
 const char kNoScriptDescription[] = "NoScript Previews";
 const char kOfflineDesciption[] = "Offline Previews";
 
 // Flag feature name.
+const char kPreviewsAllowedFeatureName[] = "Previews";
 const char kNoScriptFeatureName[] = "NoScriptPreviews";
 #if defined(OS_ANDROID)
 const char kOfflinePageFeatureName[] = "OfflinePreviews";
@@ -42,6 +43,7 @@
 
 // HTML DOM ID used in the JavaScript code. The IDs are generated here so that
 // the DOM would have sensible name instead of autogenerated IDs.
+const char kPreviewsAllowedFlagHtmlId[] = "previews-flag";
 const char kEctFlagHtmlId[] = "ect-flag";
 const char kNoScriptFlagHtmlId[] = "noscript-flag";
 const char kOfflinePageFlagHtmlId[] = "offline-page-flag";
@@ -49,6 +51,7 @@
 
 // Links to flags in chrome://flags.
 // TODO(thanhdle): Refactor into vector of structs. crbug.com/787010.
+const char kPreviewsAllowedFlagLink[] = "chrome://flags/#allow-previews";
 const char kEctFlagLink[] = "chrome://flags/#force-effective-connection-type";
 const char kNoScriptFlagLink[] = "chrome://flags/#enable-noscript-previews";
 const char kOfflinePageFlagLink[] = "chrome://flags/#enable-offline-previews";
@@ -186,11 +189,11 @@
     GetPreviewsEnabledCallback callback) {
   std::vector<mojom::PreviewsStatusPtr> statuses;
 
-  auto amp_status = mojom::PreviewsStatus::New();
-  amp_status->description = kAmpRedirectionDescription;
-  amp_status->enabled = previews::params::IsAMPRedirectionPreviewEnabled();
-  amp_status->htmlId = kAmpRedirectionPreviewsHtmlId;
-  statuses.push_back(std::move(amp_status));
+  auto previews_allowed_status = mojom::PreviewsStatus::New();
+  previews_allowed_status->description = kPreviewsAllowedDescription;
+  previews_allowed_status->enabled = previews::params::ArePreviewsAllowed();
+  previews_allowed_status->htmlId = kPreviewsAllowedHtmlId;
+  statuses.push_back(std::move(previews_allowed_status));
 
   auto client_lofi_status = mojom::PreviewsStatus::New();
   client_lofi_status->description = kClientLoFiDescription;
@@ -217,6 +220,15 @@
     GetPreviewsFlagsDetailsCallback callback) {
   std::vector<mojom::PreviewsFlagPtr> flags;
 
+  auto previews_allowed_status = mojom::PreviewsFlag::New();
+  previews_allowed_status->description =
+      flag_descriptions::kPreviewsAllowedName;
+  previews_allowed_status->link = kPreviewsAllowedFlagLink;
+  previews_allowed_status->value =
+      GetFeatureFlagStatus(kPreviewsAllowedFeatureName);
+  previews_allowed_status->htmlId = kPreviewsAllowedFlagHtmlId;
+  flags.push_back(std::move(previews_allowed_status));
+
   auto ect_status = mojom::PreviewsFlag::New();
   ect_status->description =
       flag_descriptions::kForceEffectiveConnectionTypeName;
diff --git a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc
index 41e8772..d9572b7 100644
--- a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc
+++ b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc
@@ -44,13 +44,13 @@
 namespace {
 
 // The HTML DOM ID used in Javascript.
-constexpr char kAMPRedirectionPreviewsHtmlId[] = "amp-preview-status";
+constexpr char kPreviewsAllowedHtmlId[] = "previews-allowed-status";
 constexpr char kClientLoFiPreviewsHtmlId[] = "client-lofi-preview-status";
 constexpr char kNoScriptPreviewsHtmlId[] = "noscript-preview-status";
 constexpr char kOfflinePreviewsHtmlId[] = "offline-preview-status";
 
 // Descriptions for previews.
-constexpr char kAmpRedirectionDescription[] = "AMP Previews";
+constexpr char kPreviewsAllowedDescription[] = "Previews Allowed";
 constexpr char kClientLoFiDescription[] = "Client LoFi Previews";
 constexpr char kNoScriptDescription[] = "NoScript Previews";
 constexpr char kOfflineDesciption[] = "Offline Previews";
@@ -318,30 +318,28 @@
   EXPECT_EQ(expected, passed_in_modes.size());
 }
 
-TEST_F(InterventionsInternalsPageHandlerTest, AMPRedirectionDisabled) {
-  // Init with kAMPRedirection disabled.
-  scoped_feature_list_->InitWithFeatures({},
-                                         {previews::features::kAMPRedirection});
+TEST_F(InterventionsInternalsPageHandlerTest, PreviewsAllowedDisabled) {
+  // Init with kPreviews disabled.
+  scoped_feature_list_->InitWithFeatures({}, {previews::features::kPreviews});
 
   page_handler_->GetPreviewsEnabled(
       base::BindOnce(&MockGetPreviewsEnabledCallback));
-  auto amp_redirection = passed_in_modes.find(kAMPRedirectionPreviewsHtmlId);
-  ASSERT_NE(passed_in_modes.end(), amp_redirection);
-  EXPECT_EQ(kAmpRedirectionDescription, amp_redirection->second->description);
-  EXPECT_FALSE(amp_redirection->second->enabled);
+  auto previews_allowed = passed_in_modes.find(kPreviewsAllowedHtmlId);
+  ASSERT_NE(passed_in_modes.end(), previews_allowed);
+  EXPECT_EQ(kPreviewsAllowedDescription, previews_allowed->second->description);
+  EXPECT_FALSE(previews_allowed->second->enabled);
 }
 
-TEST_F(InterventionsInternalsPageHandlerTest, AMPRedirectionEnabled) {
-  // Init with kAMPRedirection enabled.
-  scoped_feature_list_->InitWithFeatures({previews::features::kAMPRedirection},
-                                         {});
+TEST_F(InterventionsInternalsPageHandlerTest, PreviewsAllowedEnabled) {
+  // Init with kPreviews enabled.
+  scoped_feature_list_->InitWithFeatures({previews::features::kPreviews}, {});
 
   page_handler_->GetPreviewsEnabled(
       base::BindOnce(&MockGetPreviewsEnabledCallback));
-  auto amp_redirection = passed_in_modes.find(kAMPRedirectionPreviewsHtmlId);
-  ASSERT_NE(passed_in_modes.end(), amp_redirection);
-  EXPECT_EQ(kAmpRedirectionDescription, amp_redirection->second->description);
-  EXPECT_TRUE(amp_redirection->second->enabled);
+  auto previews_allowed = passed_in_modes.find(kPreviewsAllowedHtmlId);
+  ASSERT_NE(passed_in_modes.end(), previews_allowed);
+  EXPECT_EQ(kPreviewsAllowedDescription, previews_allowed->second->description);
+  EXPECT_TRUE(previews_allowed->second->enabled);
 }
 
 TEST_F(InterventionsInternalsPageHandlerTest, ClientLoFiDisabled) {
@@ -425,7 +423,7 @@
   page_handler_->GetPreviewsFlagsDetails(
       base::BindOnce(&MockGetPreviewsFlagsCallback));
 
-  constexpr size_t expected = 4;
+  constexpr size_t expected = 5;
   EXPECT_EQ(expected, passed_in_flags.size());
 }
 
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
index cc973a0..066ccec1 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
@@ -84,6 +84,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/debug_daemon_client.h"
 #include "chromeos/network/onc/onc_certificate_importer_impl.h"
+#include "chromeos/network/onc/onc_parsed_certificates.h"
 #include "chromeos/network/onc/onc_utils.h"
 #endif
 
@@ -1020,11 +1021,10 @@
   chromeos::onc::CertificateImporterImpl cert_importer(
       BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), nssdb);
   cert_importer.ImportCertificates(
-      certificates,
+      std::make_unique<chromeos::onc::OncParsedCertificates>(certificates),
       onc_source,
       base::Bind(&NetInternalsMessageHandler::OnCertificatesImported,
-                 AsWeakPtr(),
-                 error));
+                 AsWeakPtr(), error));
 }
 
 void NetInternalsMessageHandler::OnCertificatesImported(
diff --git a/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc b/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc
index 9616e09..def21ea7 100644
--- a/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc
+++ b/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc
@@ -65,16 +65,14 @@
       std::make_unique<base::DictionaryValue>());
   dict->SetBoolean(
       "enabled",
-      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(
-          g_browser_process->local_state()));
-  dict->SetBoolean("managed", IsMetricsReportingPolicyManaged(
-                                  g_browser_process->local_state()));
+      ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
+  dict->SetBoolean("managed", IsMetricsReportingPolicyManaged());
   return dict;
 }
 
 void MetricsReportingHandler::HandleSetMetricsReportingEnabled(
     const base::ListValue* args) {
-  if (IsMetricsReportingPolicyManaged(g_browser_process->local_state())) {
+  if (IsMetricsReportingPolicyManaged()) {
     NOTREACHED();
     // NOTE: ChangeMetricsReportingState() already checks whether metrics
     // reporting is managed by policy. Also, the UI really shouldn't be able to
@@ -86,9 +84,7 @@
 
   bool enabled;
   CHECK(args->GetBoolean(0, &enabled));
-  ChangeMetricsReportingState(g_browser_process->local_state(),
-                              g_browser_process->GetMetricsServicesManager(),
-                              enabled);
+  ChangeMetricsReportingState(enabled);
 }
 
 void MetricsReportingHandler::OnPolicyChanged(const base::Value* previous,
diff --git a/chrome/browser/usb/web_usb_detector.cc b/chrome/browser/usb/web_usb_detector.cc
index f29ba28b..2716ab8 100644
--- a/chrome/browser/usb/web_usb_detector.cc
+++ b/chrome/browser/usb/web_usb_detector.cc
@@ -11,6 +11,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/net/referrer.h"
+#include "chrome/browser/notifications/system_notification_helper.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
@@ -34,7 +35,6 @@
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/paint_vector_icon.h"
-#include "ui/message_center/message_center.h"
 #include "ui/message_center/public/cpp/notification.h"
 #include "ui/message_center/public/cpp/notification_delegate.h"
 #include "url/gurl.h"
@@ -109,8 +109,7 @@
       // If the disposition is not already set, go ahead and set it.
       if (disposition_ == WEBUSB_NOTIFICATION_CLOSED)
         disposition_ = WEBUSB_NOTIFICATION_CLOSED_MANUAL_NAVIGATION;
-      message_center::MessageCenter::Get()->RemoveNotification(
-          notification_id_, false /* by_user */);
+      SystemNotificationHelper::GetInstance()->Close(notification_id_);
     }
   }
 
@@ -198,33 +197,25 @@
   std::string notification_id = device->guid();
 
   message_center::RichNotificationData rich_notification_data;
-  std::unique_ptr<message_center::Notification> notification(
-      new message_center::Notification(
-          message_center::NOTIFICATION_TYPE_SIMPLE, notification_id,
-          l10n_util::GetStringFUTF16(
-              IDS_WEBUSB_DEVICE_DETECTED_NOTIFICATION_TITLE, product_name),
-          l10n_util::GetStringFUTF16(
-              IDS_WEBUSB_DEVICE_DETECTED_NOTIFICATION,
-              url_formatter::FormatUrlForSecurityDisplay(
-                  landing_page,
-                  url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC)),
-          gfx::Image(gfx::CreateVectorIcon(vector_icons::kUsbIcon, 64,
-                                           gfx::kChromeIconGrey)),
-          base::string16(), GURL(),
-          message_center::NotifierId(
-              message_center::NotifierId::SYSTEM_COMPONENT, kNotifierWebUsb),
-          rich_notification_data,
-          new WebUsbNotificationDelegate(landing_page, notification_id)));
-
-  notification->SetSystemPriority();
-  message_center::MessageCenter::Get()->AddNotification(
-      std::move(notification));
+  message_center::Notification notification(
+      message_center::NOTIFICATION_TYPE_SIMPLE, notification_id,
+      l10n_util::GetStringFUTF16(IDS_WEBUSB_DEVICE_DETECTED_NOTIFICATION_TITLE,
+                                 product_name),
+      l10n_util::GetStringFUTF16(
+          IDS_WEBUSB_DEVICE_DETECTED_NOTIFICATION,
+          url_formatter::FormatUrlForSecurityDisplay(
+              landing_page, url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC)),
+      gfx::Image(gfx::CreateVectorIcon(vector_icons::kUsbIcon, 64,
+                                       gfx::kChromeIconGrey)),
+      base::string16(), GURL(),
+      message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT,
+                                 kNotifierWebUsb),
+      rich_notification_data,
+      new WebUsbNotificationDelegate(landing_page, notification_id));
+  notification.SetSystemPriority();
+  SystemNotificationHelper::GetInstance()->Display(notification);
 }
 
 void WebUsbDetector::OnDeviceRemoved(scoped_refptr<device::UsbDevice> device) {
-  std::string notification_id = device->guid();
-  message_center::MessageCenter* message_center =
-      message_center::MessageCenter::Get();
-  if (message_center->FindVisibleNotificationById(notification_id))
-    message_center->RemoveNotification(notification_id, false /* by_user */);
+  SystemNotificationHelper::GetInstance()->Close(device->guid());
 }
diff --git a/chrome/browser/usb/web_usb_detector_unittest.cc b/chrome/browser/usb/web_usb_detector_unittest.cc
index f6f9d0d..9ec5b65 100644
--- a/chrome/browser/usb/web_usb_detector_unittest.cc
+++ b/chrome/browser/usb/web_usb_detector_unittest.cc
@@ -9,6 +9,9 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/histogram_tester.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/notifications/notification_display_service.h"
+#include "chrome/browser/notifications/notification_display_service_tester.h"
+#include "chrome/browser/notifications/system_notification_helper.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -20,7 +23,6 @@
 #include "device/usb/mock_usb_device.h"
 #include "device/usb/mock_usb_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/message_center/message_center.h"
 #include "ui/message_center/public/cpp/notification.h"
 #include "ui/message_center/public/cpp/notification_delegate.h"
 #include "url/gurl.h"
@@ -61,21 +63,14 @@
     chromeos::ProfileHelper::Get()->SetActiveUserIdForTesting(kProfileName);
 #endif
     BrowserList::SetLastActive(browser());
-
-#if !defined(OS_CHROMEOS)
-    message_center::MessageCenter::Initialize();
-#endif
-    message_center_ = message_center::MessageCenter::Get();
-    ASSERT_TRUE(message_center_ != nullptr);
+    display_service_ = std::make_unique<NotificationDisplayServiceTester>(
+        SystemNotificationHelper::GetProfileForTesting());
 
     web_usb_detector_.reset(new WebUsbDetector());
   }
 
   void TearDown() override {
     BrowserWithTestWindowTest::TearDown();
-#if !defined(OS_CHROMEOS)
-    message_center::MessageCenter::Shutdown();
-#endif
     web_usb_detector_.reset(nullptr);
   }
 
@@ -83,11 +78,11 @@
 
  protected:
   device::MockDeviceClient device_client_;
-  message_center::MessageCenter* message_center_;
+  std::unique_ptr<WebUsbDetector> web_usb_detector_;
+  std::unique_ptr<NotificationDisplayServiceTester> display_service_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(WebUsbDetectorTest);
-  std::unique_ptr<WebUsbDetector> web_usb_detector_;
 };
 
 TEST_F(WebUsbDetectorTest, UsbDeviceAddedAndRemoved) {
@@ -100,9 +95,9 @@
   Initialize();
 
   device_client_.usb_service()->AddDevice(device);
-  message_center::Notification* notification =
-      message_center_->FindVisibleNotificationById(guid);
-  ASSERT_TRUE(notification != nullptr);
+  base::Optional<message_center::Notification> notification =
+      display_service_->GetNotification(guid);
+  ASSERT_TRUE(notification);
   base::string16 expected_title =
       base::ASCIIToUTF16("Google Product A detected");
   EXPECT_EQ(expected_title, notification->title());
@@ -112,9 +107,8 @@
   EXPECT_TRUE(notification->delegate() != nullptr);
 
   device_client_.usb_service()->RemoveDevice(device);
-  // Device is removed, so notification should be removed from the
-  // message_center too.
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid) == nullptr);
+  // Device is removed, so notification should be removed too.
+  EXPECT_FALSE(display_service_->GetNotification(guid));
 }
 
 TEST_F(WebUsbDetectorTest, UsbDeviceWithoutProductNameAddedAndRemoved) {
@@ -128,10 +122,10 @@
 
   device_client_.usb_service()->AddDevice(device);
   // For device without product name, no notification is generated.
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid));
 
   device_client_.usb_service()->RemoveDevice(device);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid));
 }
 
 TEST_F(WebUsbDetectorTest, UsbDeviceWithoutLandingPageAddedAndRemoved) {
@@ -144,10 +138,10 @@
 
   device_client_.usb_service()->AddDevice(device);
   // For device without landing page, no notification is generated.
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid));
 
   device_client_.usb_service()->RemoveDevice(device);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid));
 }
 
 TEST_F(WebUsbDetectorTest, UsbDeviceWasThereBeforeAndThenRemoved) {
@@ -158,12 +152,12 @@
 
   // USB device was added before web_usb_detector was created.
   device_client_.usb_service()->AddDevice(device);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid));
 
   Initialize();
 
   device_client_.usb_service()->RemoveDevice(device);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid));
 }
 
 TEST_F(
@@ -190,18 +184,18 @@
   // Three usb devices were added and removed before web_usb_detector was
   // created.
   device_client_.usb_service()->AddDevice(device_1);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_1) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_1));
   device_client_.usb_service()->AddDevice(device_2);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_2) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_2));
   device_client_.usb_service()->AddDevice(device_3);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_3) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_3));
 
   device_client_.usb_service()->RemoveDevice(device_1);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_1) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_1));
   device_client_.usb_service()->RemoveDevice(device_2);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_2) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_2));
   device_client_.usb_service()->RemoveDevice(device_3);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_3) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_3));
 
   WebUsbDetector web_usb_detector;
   web_usb_detector.Initialize();
@@ -230,20 +224,20 @@
 
   // Three usb devices were added before web_usb_detector was created.
   device_client_.usb_service()->AddDevice(device_1);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_1) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_1));
   device_client_.usb_service()->AddDevice(device_2);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_2) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_2));
   device_client_.usb_service()->AddDevice(device_3);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_3) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_3));
 
   Initialize();
 
   device_client_.usb_service()->RemoveDevice(device_1);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_1) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_1));
   device_client_.usb_service()->RemoveDevice(device_2);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_2) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_2));
   device_client_.usb_service()->RemoveDevice(device_3);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_3) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_3));
 }
 
 TEST_F(WebUsbDetectorTest,
@@ -268,19 +262,19 @@
 
   // Two usb devices were added before web_usb_detector was created.
   device_client_.usb_service()->AddDevice(device_1);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_1) == nullptr);
-  device_client_.usb_service()->AddDevice(device_3);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_3) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_1));
+  device_client_.usb_service()->AddDevice(device_2);
+  EXPECT_FALSE(display_service_->GetNotification(guid_2));
 
   Initialize();
 
   device_client_.usb_service()->RemoveDevice(device_1);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_1) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_1));
 
   device_client_.usb_service()->AddDevice(device_2);
-  message_center::Notification* notification =
-      message_center_->FindVisibleNotificationById(guid_2);
-  ASSERT_TRUE(notification != nullptr);
+  base::Optional<message_center::Notification> notification =
+      display_service_->GetNotification(guid_2);
+  ASSERT_TRUE(notification);
   base::string16 expected_title =
       base::ASCIIToUTF16("Google Product B detected");
   EXPECT_EQ(expected_title, notification->title());
@@ -289,11 +283,8 @@
   EXPECT_EQ(expected_message, notification->message());
   EXPECT_TRUE(notification->delegate() != nullptr);
 
-  device_client_.usb_service()->RemoveDevice(device_3);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_3) == nullptr);
-
   device_client_.usb_service()->RemoveDevice(device_2);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_2) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_2));
 }
 
 TEST_F(WebUsbDetectorTest, ThreeUsbDevicesAddedAndRemoved) {
@@ -318,9 +309,9 @@
   Initialize();
 
   device_client_.usb_service()->AddDevice(device_1);
-  message_center::Notification* notification_1 =
-      message_center_->FindVisibleNotificationById(guid_1);
-  ASSERT_TRUE(notification_1 != nullptr);
+  base::Optional<message_center::Notification> notification_1 =
+      display_service_->GetNotification(guid_1);
+  ASSERT_TRUE(notification_1);
   base::string16 expected_title_1 =
       base::ASCIIToUTF16("Google Product A detected");
   EXPECT_EQ(expected_title_1, notification_1->title());
@@ -330,12 +321,12 @@
   EXPECT_TRUE(notification_1->delegate() != nullptr);
 
   device_client_.usb_service()->RemoveDevice(device_1);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_1) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_1));
 
   device_client_.usb_service()->AddDevice(device_2);
-  message_center::Notification* notification_2 =
-      message_center_->FindVisibleNotificationById(guid_2);
-  ASSERT_TRUE(notification_2 != nullptr);
+  base::Optional<message_center::Notification> notification_2 =
+      display_service_->GetNotification(guid_2);
+  ASSERT_TRUE(notification_2);
   base::string16 expected_title_2 =
       base::ASCIIToUTF16("Google Product B detected");
   EXPECT_EQ(expected_title_2, notification_2->title());
@@ -345,12 +336,12 @@
   EXPECT_TRUE(notification_2->delegate() != nullptr);
 
   device_client_.usb_service()->RemoveDevice(device_2);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_2) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_2));
 
   device_client_.usb_service()->AddDevice(device_3);
-  message_center::Notification* notification_3 =
-      message_center_->FindVisibleNotificationById(guid_3);
-  ASSERT_TRUE(notification_3 != nullptr);
+  base::Optional<message_center::Notification> notification_3 =
+      display_service_->GetNotification(guid_3);
+  ASSERT_TRUE(notification_3);
   base::string16 expected_title_3 =
       base::ASCIIToUTF16("Google Product C detected");
   EXPECT_EQ(expected_title_3, notification_3->title());
@@ -360,7 +351,7 @@
   EXPECT_TRUE(notification_3->delegate() != nullptr);
 
   device_client_.usb_service()->RemoveDevice(device_3);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_3) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_3));
 }
 
 TEST_F(WebUsbDetectorTest, ThreeUsbDeviceAddedAndRemovedDifferentOrder) {
@@ -385,9 +376,9 @@
   Initialize();
 
   device_client_.usb_service()->AddDevice(device_1);
-  message_center::Notification* notification_1 =
-      message_center_->FindVisibleNotificationById(guid_1);
-  ASSERT_TRUE(notification_1 != nullptr);
+  base::Optional<message_center::Notification> notification_1 =
+      display_service_->GetNotification(guid_1);
+  ASSERT_TRUE(notification_1);
   base::string16 expected_title_1 =
       base::ASCIIToUTF16("Google Product A detected");
   EXPECT_EQ(expected_title_1, notification_1->title());
@@ -397,9 +388,9 @@
   EXPECT_TRUE(notification_1->delegate() != nullptr);
 
   device_client_.usb_service()->AddDevice(device_2);
-  message_center::Notification* notification_2 =
-      message_center_->FindVisibleNotificationById(guid_2);
-  ASSERT_TRUE(notification_2 != nullptr);
+  base::Optional<message_center::Notification> notification_2 =
+      display_service_->GetNotification(guid_2);
+  ASSERT_TRUE(notification_2);
   base::string16 expected_title_2 =
       base::ASCIIToUTF16("Google Product B detected");
   EXPECT_EQ(expected_title_2, notification_2->title());
@@ -409,12 +400,12 @@
   EXPECT_TRUE(notification_2->delegate() != nullptr);
 
   device_client_.usb_service()->RemoveDevice(device_2);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_2) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_2));
 
   device_client_.usb_service()->AddDevice(device_3);
-  message_center::Notification* notification_3 =
-      message_center_->FindVisibleNotificationById(guid_3);
-  ASSERT_TRUE(notification_3 != nullptr);
+  base::Optional<message_center::Notification> notification_3 =
+      display_service_->GetNotification(guid_3);
+  ASSERT_TRUE(notification_3);
   base::string16 expected_title_3 =
       base::ASCIIToUTF16("Google Product C detected");
   EXPECT_EQ(expected_title_3, notification_3->title());
@@ -424,10 +415,10 @@
   EXPECT_TRUE(notification_3->delegate() != nullptr);
 
   device_client_.usb_service()->RemoveDevice(device_1);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_1) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_1));
 
   device_client_.usb_service()->RemoveDevice(device_3);
-  EXPECT_TRUE(message_center_->FindVisibleNotificationById(guid_3) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_3));
 }
 
 TEST_F(WebUsbDetectorTest, UsbDeviceAddedWhileActiveTabUrlIsLandingPage) {
@@ -441,7 +432,7 @@
   AddTab(browser(), landing_page_1);
 
   device_client_.usb_service()->AddDevice(device_1);
-  ASSERT_TRUE(message_center_->FindVisibleNotificationById(guid_1) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_1));
 }
 
 TEST_F(WebUsbDetectorTest, UsbDeviceAddedBeforeActiveTabUrlIsLandingPage) {
@@ -454,10 +445,10 @@
   Initialize();
 
   device_client_.usb_service()->AddDevice(device_1);
-  ASSERT_TRUE(message_center_->FindVisibleNotificationById(guid_1) != nullptr);
+  EXPECT_TRUE(display_service_->GetNotification(guid_1));
 
   AddTab(browser(), landing_page_1);
-  ASSERT_TRUE(message_center_->FindVisibleNotificationById(guid_1) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_1));
   histogram_tester.ExpectUniqueSample("WebUsb.NotificationClosed", 3, 1);
 }
 
@@ -477,9 +468,9 @@
   AddTab(browser(), landing_page_2);
 
   device_client_.usb_service()->AddDevice(device_1);
-  message_center::Notification* notification_1 =
-      message_center_->FindVisibleNotificationById(guid_1);
-  ASSERT_TRUE(notification_1 != nullptr);
+  base::Optional<message_center::Notification> notification_1 =
+      display_service_->GetNotification(guid_1);
+  ASSERT_TRUE(notification_1);
   EXPECT_EQ(2, tab_strip_model->count());
 
   notification_1->Click();
@@ -487,7 +478,7 @@
   content::WebContents* web_contents =
       tab_strip_model->GetWebContentsAt(tab_strip_model->active_index());
   EXPECT_EQ(landing_page_1, web_contents->GetURL());
-  ASSERT_TRUE(message_center_->FindVisibleNotificationById(guid_1) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_1));
   histogram_tester.ExpectUniqueSample("WebUsb.NotificationClosed", 2, 1);
 }
 
@@ -503,9 +494,9 @@
   Initialize();
 
   device_client_.usb_service()->AddDevice(device_1);
-  message_center::Notification* notification_1 =
-      message_center_->FindVisibleNotificationById(guid_1);
-  ASSERT_TRUE(notification_1 != nullptr);
+  base::Optional<message_center::Notification> notification_1 =
+      display_service_->GetNotification(guid_1);
+  ASSERT_TRUE(notification_1);
   EXPECT_EQ(0, tab_strip_model->count());
 
   notification_1->Click();
@@ -513,8 +504,7 @@
   content::WebContents* web_contents =
       tab_strip_model->GetWebContentsAt(tab_strip_model->active_index());
   EXPECT_EQ(landing_page_1, web_contents->GetURL());
-  ASSERT_TRUE(message_center_->FindVisibleNotificationById(guid_1) == nullptr);
+  EXPECT_FALSE(display_service_->GetNotification(guid_1));
   histogram_tester.ExpectUniqueSample("WebUsb.NotificationClosed", 2, 1);
 }
-
 #endif  // !OS_WIN
diff --git a/chrome/browser/vr/vr_tab_helper.cc b/chrome/browser/vr/vr_tab_helper.cc
index eca591b..b6a20f4 100644
--- a/chrome/browser/vr/vr_tab_helper.cc
+++ b/chrome/browser/vr/vr_tab_helper.cc
@@ -29,7 +29,7 @@
 
   WebPreferences web_prefs =
       web_contents_->GetRenderViewHost()->GetWebkitPreferences();
-  web_prefs.immersive_mode_enabled = is_in_vr_;
+  web_prefs.page_popups_suppressed = is_in_vr_;
   web_contents_->GetRenderViewHost()->UpdateWebkitPreferences(web_prefs);
 }
 
diff --git a/chrome/browser/win/chrome_elf_init_unittest.cc b/chrome/browser/win/chrome_elf_init_unittest.cc
index e122f11..b544e53d 100644
--- a/chrome/browser/win/chrome_elf_init_unittest.cc
+++ b/chrome/browser/win/chrome_elf_init_unittest.cc
@@ -95,7 +95,7 @@
 
   // Create the field trial with the blacklist disabled group.
   base::FieldTrialList field_trial_list(
-      base::MakeUnique<metrics::SHA1EntropyProvider>("test"));
+      base::MakeUnique<variations::SHA1EntropyProvider>("test"));
 
   scoped_refptr<base::FieldTrial> trial(
     base::FieldTrialList::CreateFieldTrial(
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 959b767..3d05eb8 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -2434,6 +2434,14 @@
 
 // True if the user has dismissed the "desktop to iOS" history page promotion.
 const char kHistoryPageIOSPromoDismissed[] = "history_page_ios_promo_dismissed";
+
+// Acts as a cache to remember problematic programs through restarts. Used for
+// the third-party conflicts warning.
+const char kProblematicPrograms[] = "problematic_programs";
+
+// A boolean value, controlling whether third party software is allowed to
+// inject into Chrome's processes.
+const char kThirdPartyBlockingEnabled[] = "third_party_blocking_enabled";
 #endif
 
 // An integer that keeps track of prompt waves for the settings reset
@@ -2551,10 +2559,4 @@
 const char kWebDriverOverridesIncompatiblePolicies[] =
     "webdriver.override_incompatible_policy";
 
-#if defined(OS_WIN)
-// A boolean value, controlling whether third party software is allowed to
-// inject into Chrome's processes.
-const char kThirdPartyBlockingEnabled[] = "third_party_blocking_enabled";
-#endif
-
 }  // namespace prefs
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index d2ea385a..d89c908 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -868,6 +868,9 @@
 extern const char kBookmarksFootNoteIOSPromoDismissed[];
 extern const char kNumberHistoryPageIOSPromoShown[];
 extern const char kHistoryPageIOSPromoDismissed[];
+
+extern const char kProblematicPrograms[];
+extern const char kThirdPartyBlockingEnabled[];
 #endif
 
 extern const char kSettingsResetPromptPromptWave[];
@@ -915,12 +918,6 @@
 extern const char kSitePerProcess[];
 extern const char kWebDriverOverridesIncompatiblePolicies[];
 
-#if defined(OS_WIN)
-// Preference for controlling whether or not third party blocking is enabled on
-// Windows.
-extern const char kThirdPartyBlockingEnabled[];
-#endif
-
 }  // namespace prefs
 
 #endif  // CHROME_COMMON_PREF_NAMES_H_
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 61a1ef2..d98e164d 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -583,7 +583,8 @@
   SandboxStatusExtension::Create(render_frame);
 #endif
 
-  new NetErrorHelper(render_frame);
+  new NetErrorHelper(render_frame,
+                     chrome_observer_ ? chrome_observer_->is_online() : true);
 
   new page_load_metrics::MetricsRenderFrameObserver(render_frame);
 
diff --git a/chrome/renderer/chrome_render_thread_observer.cc b/chrome/renderer/chrome_render_thread_observer.cc
index 5966d20..67456e1b 100644
--- a/chrome/renderer/chrome_render_thread_observer.cc
+++ b/chrome/renderer/chrome_render_thread_observer.cc
@@ -296,6 +296,10 @@
       chrome::mojom::RendererConfiguration::Name_);
 }
 
+void ChromeRenderThreadObserver::NetworkStateChanged(bool online) {
+  online_ = online;
+}
+
 void ChromeRenderThreadObserver::SetInitialConfiguration(
     bool is_incognito_process) {
   is_incognito_process_ = is_incognito_process;
diff --git a/chrome/renderer/chrome_render_thread_observer.h b/chrome/renderer/chrome_render_thread_observer.h
index 2d401850..75f45a0 100644
--- a/chrome/renderer/chrome_render_thread_observer.h
+++ b/chrome/renderer/chrome_render_thread_observer.h
@@ -44,12 +44,15 @@
     return visited_link_slave_.get();
   }
 
+  bool is_online() { return online_; }
+
  private:
   // content::RenderThreadObserver:
   void RegisterMojoInterfaces(
       blink::AssociatedInterfaceRegistry* associated_interfaces) override;
   void UnregisterMojoInterfaces(
       blink::AssociatedInterfaceRegistry* associated_interfaces) override;
+  void NetworkStateChanged(bool online) override;
 
   // chrome::mojom::RendererConfiguration:
   void SetInitialConfiguration(bool is_incognito_process) override;
@@ -61,6 +64,9 @@
   void OnRendererConfigurationAssociatedRequest(
       chrome::mojom::RendererConfigurationAssociatedRequest request);
 
+  // Is the browser online? The a priori assumption.
+  bool online_ = true;
+
   static bool is_incognito_process_;
   std::unique_ptr<content::ResourceDispatcherDelegate> resource_delegate_;
   RendererContentSettingRules content_setting_rules_;
diff --git a/chrome/renderer/net/net_error_helper.cc b/chrome/renderer/net/net_error_helper.cc
index cedfbb6..40313c7 100644
--- a/chrome/renderer/net/net_error_helper.cc
+++ b/chrome/renderer/net/net_error_helper.cc
@@ -117,7 +117,7 @@
 
 }  // namespace
 
-NetErrorHelper::NetErrorHelper(RenderFrame* render_frame)
+NetErrorHelper::NetErrorHelper(RenderFrame* render_frame, bool online)
     : RenderFrameObserver(render_frame),
       content::RenderFrameObserverTracker<NetErrorHelper>(render_frame),
       weak_controller_delegate_factory_(this),
@@ -130,10 +130,9 @@
       command_line->HasSwitch(switches::kEnableOfflineAutoReloadVisibleOnly);
   // TODO(mmenke): Consider only creating a NetErrorHelperCore for main frames.
   // subframes don't need any of the NetErrorHelperCore's extra logic.
-  core_.reset(new NetErrorHelperCore(this,
-                                     auto_reload_enabled,
+  core_.reset(new NetErrorHelperCore(this, auto_reload_enabled,
                                      auto_reload_visible_only,
-                                     !render_frame->IsHidden()));
+                                     !render_frame->IsHidden(), online));
 
   render_frame->GetAssociatedInterfaceRegistry()->AddInterface(
       base::Bind(&NetErrorHelper::OnNetworkDiagnosticsClientRequest,
diff --git a/chrome/renderer/net/net_error_helper.h b/chrome/renderer/net/net_error_helper.h
index 038ebeb..a2fccfdb 100644
--- a/chrome/renderer/net/net_error_helper.h
+++ b/chrome/renderer/net/net_error_helper.h
@@ -54,7 +54,7 @@
       public chrome::mojom::NetworkDiagnosticsClient,
       public chrome::mojom::NavigationCorrector {
  public:
-  explicit NetErrorHelper(content::RenderFrame* render_frame);
+  NetErrorHelper(content::RenderFrame* render_frame, bool online);
   ~NetErrorHelper() override;
 
   // NetErrorPageController::Delegate implementation
diff --git a/chrome/renderer/net/net_error_helper_core.cc b/chrome/renderer/net/net_error_helper_core.cc
index ebd8166..c7b35341 100644
--- a/chrome/renderer/net/net_error_helper_core.cc
+++ b/chrome/renderer/net/net_error_helper_core.cc
@@ -498,7 +498,8 @@
 NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate,
                                        bool auto_reload_enabled,
                                        bool auto_reload_visible_only,
-                                       bool is_visible)
+                                       bool is_visible,
+                                       bool online)
     : delegate_(delegate),
       last_probe_status_(error_page::DNS_PROBE_POSSIBLE),
       can_show_network_diagnostics_dialog_(false),
@@ -508,8 +509,7 @@
       auto_reload_paused_(false),
       auto_reload_in_flight_(false),
       uncommitted_load_started_(false),
-      // TODO(ellyjones): Make online_ accurate at object creation.
-      online_(true),
+      online_(online),
       visible_(is_visible),
       auto_reload_count_(0),
       navigation_from_button_(NO_BUTTON) {}
diff --git a/chrome/renderer/net/net_error_helper_core.h b/chrome/renderer/net/net_error_helper_core.h
index d0d4e73..c9ca49cb 100644
--- a/chrome/renderer/net/net_error_helper_core.h
+++ b/chrome/renderer/net/net_error_helper_core.h
@@ -132,7 +132,8 @@
   NetErrorHelperCore(Delegate* delegate,
                      bool auto_reload_enabled,
                      bool auto_reload_visible_only,
-                     bool is_visible);
+                     bool is_visible,
+                     bool online);
   ~NetErrorHelperCore();
 
   // Sets values in |pending_error_page_info_|. If |error_html| is not null, it
diff --git a/chrome/renderer/net/net_error_helper_core_unittest.cc b/chrome/renderer/net/net_error_helper_core_unittest.cc
index 851f472..5934961 100644
--- a/chrome/renderer/net/net_error_helper_core_unittest.cc
+++ b/chrome/renderer/net/net_error_helper_core_unittest.cc
@@ -178,8 +178,8 @@
     // The old value of timer_, if any, will be freed by the old core_ being
     // destructed, since core_ takes ownership of the timer.
     timer_ = new base::MockTimer(false, false);
-    core_.reset(new NetErrorHelperCore(this, auto_reload_enabled,
-                                       auto_reload_visible_only, visible));
+    core_.reset(new NetErrorHelperCore(
+        this, auto_reload_enabled, auto_reload_visible_only, visible, true));
     core_->set_timer_for_testing(std::unique_ptr<base::Timer>(timer_));
   }
 
diff --git a/chrome/services/file_util/public/cpp/zip_file_creator_browsertest.cc b/chrome/services/file_util/public/cpp/zip_file_creator_browsertest.cc
index 46104a84..91b5834 100644
--- a/chrome/services/file_util/public/cpp/zip_file_creator_browsertest.cc
+++ b/chrome/services/file_util/public/cpp/zip_file_creator_browsertest.cc
@@ -116,7 +116,9 @@
       EXPECT_EQ(kRandomDataSize, entry->original_size());
 
       const base::FilePath out = dir_.GetPath().AppendASCII("archived_content");
-      EXPECT_TRUE(reader.ExtractCurrentEntryToFilePath(out));
+      zip::FilePathWriterDelegate writer(out);
+      EXPECT_TRUE(reader.ExtractCurrentEntry(
+          &writer, std::numeric_limits<uint64_t>::max()));
       EXPECT_TRUE(base::ContentsEqual(zip_base_dir().Append(kFile2), out));
     } else {
       ADD_FAILURE();
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 799bb92..34a73c7a 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2244,6 +2244,7 @@
     "../browser/conflicts/module_info_win_unittest.cc",
     "../browser/conflicts/module_inspector_win_unittest.cc",
     "../browser/conflicts/module_list_manager_win_unittest.cc",
+    "../browser/conflicts/problematic_programs_updater_win_unittest.cc",
     "../browser/content_settings/content_settings_default_provider_unittest.cc",
     "../browser/content_settings/content_settings_mock_observer.cc",
     "../browser/content_settings/content_settings_mock_observer.h",
diff --git a/chrome/test/data/extensions/platform_apps/web_view/context_menus/coordinates_with_transforms/embedder.html b/chrome/test/data/extensions/platform_apps/web_view/context_menus/coordinates_with_transforms/embedder.html
deleted file mode 100644
index 904e496..0000000
--- a/chrome/test/data/extensions/platform_apps/web_view/context_menus/coordinates_with_transforms/embedder.html
+++ /dev/null
@@ -1,11 +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.
--->
-<html>
-<body>
-  <div id="webview-tag-container" style="width: 300px; heigth: 300px;"></div>
-  <script src="embedder.js"></script>
-</body>
-</html>
diff --git a/chrome/test/data/extensions/platform_apps/web_view/context_menus/coordinates_with_transforms/embedder.js b/chrome/test/data/extensions/platform_apps/web_view/context_menus/coordinates_with_transforms/embedder.js
deleted file mode 100644
index ce62b9ea..0000000
--- a/chrome/test/data/extensions/platform_apps/web_view/context_menus/coordinates_with_transforms/embedder.js
+++ /dev/null
@@ -1,39 +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.
-
-var LOG = function(msg) { window.console.log(msg); };
-
-// window.* exported functions begin.
-window.setTransform = function(tr) {
-  LOG('Setting transform to "' + tr + '".');
-  var webview = document.body.querySelector('webview');
-  webview.style.transform = (tr !== 'NONE') ? tr : '';
-  webview.onloadstop = function() {
-    LOG('Transform "' + tr + '" is set.');
-    chrome.test.sendMessage('TRANSFORM_SET');
-  };
-  webview.reload();
-};
-// window.* exported functions end.
-
-function setUpTest(messageCallback) {
-  var guestUrl = 'data:text/html,<html><body>guest</body></html>';
-  var webview = document.createElement('webview');
-  var onLoadStop = function(e) {
-    LOG('webview has loaded.');
-    messageCallback(webview);
-  };
-  webview.addEventListener('loadstop', onLoadStop);
-
-  webview.setAttribute('src', guestUrl);
-  document.body.appendChild(webview);
-}
-
-onload = function() {
-  chrome.test.getConfig(function(config) {
-    setUpTest(function(webview) {
-      chrome.test.sendMessage('Launched');
-    });
-  });
-};
diff --git a/chrome/test/data/extensions/platform_apps/web_view/context_menus/coordinates_with_transforms/manifest.json b/chrome/test/data/extensions/platform_apps/web_view/context_menus/coordinates_with_transforms/manifest.json
deleted file mode 100644
index 3a78588..0000000
--- a/chrome/test/data/extensions/platform_apps/web_view/context_menus/coordinates_with_transforms/manifest.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "name": "Packaged App Test: <webview> context menu param coordinates",
-  "description": "Helper app to verify <webview> context menu param's coordinates",
-  "version": "1",
-  "permissions": [
-    "webview"
-  ],
-  "app": {
-    "background": {
-      "scripts": ["test.js"]
-    }
-  }
-}
diff --git a/chrome/test/data/extensions/platform_apps/web_view/context_menus/coordinates_with_transforms/test.js b/chrome/test/data/extensions/platform_apps/web_view/context_menus/coordinates_with_transforms/test.js
deleted file mode 100644
index f7d6ae1e6..0000000
--- a/chrome/test/data/extensions/platform_apps/web_view/context_menus/coordinates_with_transforms/test.js
+++ /dev/null
@@ -1,12 +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.
-
-chrome.app.runtime.onLaunched.addListener(function() {
-  chrome.app.window.create('embedder.html', {
-    outerBounds: {
-      width: 500,
-      height: 500
-    }
-  }, function () {});
-});
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc
index b1274be1..4e7aa15c 100644
--- a/chromecast/browser/cast_browser_main_parts.cc
+++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -395,7 +395,13 @@
   // the background (resources have not yet been granted to cast) since it
   // prevents the long delay the user would have seen on first rendering. Note
   // that future calls to FcInit() are safe no-ops per the FontConfig interface.
+  FcChar8 bundle_dir[] = "fonts/";
+
   FcInit();
+
+  if (FcConfigAppFontAddDir(nullptr, bundle_dir) == FcFalse) {
+    LOG(ERROR) << "Cannot load fonts from " << bundle_dir;
+  }
 #endif
 }
 
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn
index 2a56784e..72655970 100644
--- a/chromeos/BUILD.gn
+++ b/chromeos/BUILD.gn
@@ -419,6 +419,8 @@
     "network/onc/onc_merger.h",
     "network/onc/onc_normalizer.cc",
     "network/onc/onc_normalizer.h",
+    "network/onc/onc_parsed_certificates.cc",
+    "network/onc/onc_parsed_certificates.h",
     "network/onc/onc_signature.cc",
     "network/onc/onc_signature.h",
     "network/onc/onc_translation_tables.cc",
@@ -717,6 +719,7 @@
     "network/onc/onc_certificate_importer_impl_unittest.cc",
     "network/onc/onc_merger_unittest.cc",
     "network/onc/onc_normalizer_unittest.cc",
+    "network/onc/onc_parsed_certificates_unittest.cc",
     "network/onc/onc_translator_unittest.cc",
     "network/onc/onc_utils_unittest.cc",
     "network/onc/onc_validator_unittest.cc",
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index dce039c..5f1c159 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-10378.0.0
\ No newline at end of file
+10333.0.0
\ No newline at end of file
diff --git a/chromeos/dbus/fake_gsm_sms_client.cc b/chromeos/dbus/fake_gsm_sms_client.cc
index 4468251..f8b72b1 100644
--- a/chromeos/dbus/fake_gsm_sms_client.cc
+++ b/chromeos/dbus/fake_gsm_sms_client.cc
@@ -50,28 +50,31 @@
 void FakeGsmSMSClient::Delete(const std::string& service_name,
                               const dbus::ObjectPath& object_path,
                               uint32_t index,
-                              const DeleteCallback& callback) {
-  message_list_.Remove(index, NULL);
-  callback.Run();
+                              VoidDBusMethodCallback callback) {
+  message_list_.Remove(index, nullptr);
+  std::move(callback).Run(true);
 }
 
 void FakeGsmSMSClient::Get(const std::string& service_name,
                            const dbus::ObjectPath& object_path,
                            uint32_t index,
-                           const GetCallback& callback) {
-  base::DictionaryValue* dictionary = NULL;
-  if (message_list_.GetDictionary(index, &dictionary)) {
-    callback.Run(*dictionary);
+                           DBusMethodCallback<base::DictionaryValue> callback) {
+  base::DictionaryValue* dictionary = nullptr;
+  if (!message_list_.GetDictionary(index, &dictionary)) {
+    std::move(callback).Run(base::nullopt);
     return;
   }
-  base::DictionaryValue empty_dictionary;
-  callback.Run(empty_dictionary);
+
+  // TODO(crbug.com/646113): Once migration is done, this can be simplified.
+  base::DictionaryValue copy;
+  copy.MergeDictionary(dictionary);
+  std::move(callback).Run(std::move(copy));
 }
 
 void FakeGsmSMSClient::List(const std::string& service_name,
                             const dbus::ObjectPath& object_path,
-                            const ListCallback& callback) {
-  callback.Run(message_list_);
+                            DBusMethodCallback<base::ListValue> callback) {
+  std::move(callback).Run(base::ListValue(message_list_.GetList()));
 }
 
 void FakeGsmSMSClient::RequestUpdate(const std::string& service_name,
diff --git a/chromeos/dbus/fake_gsm_sms_client.h b/chromeos/dbus/fake_gsm_sms_client.h
index fb7db65..5c3c73f 100644
--- a/chromeos/dbus/fake_gsm_sms_client.h
+++ b/chromeos/dbus/fake_gsm_sms_client.h
@@ -34,14 +34,14 @@
   void Delete(const std::string& service_name,
               const dbus::ObjectPath& object_path,
               uint32_t index,
-              const DeleteCallback& callback) override;
+              VoidDBusMethodCallback callback) override;
   void Get(const std::string& service_name,
            const dbus::ObjectPath& object_path,
            uint32_t index,
-           const GetCallback& callback) override;
+           DBusMethodCallback<base::DictionaryValue> callback) override;
   void List(const std::string& service_name,
             const dbus::ObjectPath& object_path,
-            const ListCallback& callback) override;
+            DBusMethodCallback<base::ListValue> callback) override;
   void RequestUpdate(const std::string& service_name,
                      const dbus::ObjectPath& object_path) override;
 
diff --git a/chromeos/dbus/fake_media_analytics_client.cc b/chromeos/dbus/fake_media_analytics_client.cc
index e98589a..5a53657 100644
--- a/chromeos/dbus/fake_media_analytics_client.cc
+++ b/chromeos/dbus/fake_media_analytics_client.cc
@@ -4,6 +4,8 @@
 
 #include "chromeos/dbus/fake_media_analytics_client.h"
 
+#include <utility>
+
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -43,20 +45,23 @@
   media_perception_signal_handler_.Reset();
 }
 
-void FakeMediaAnalyticsClient::GetState(const StateCallback& callback) {
+void FakeMediaAnalyticsClient::GetState(
+    DBusMethodCallback<mri::State> callback) {
   if (!process_running_) {
-    callback.Run(false, current_state_);
+    std::move(callback).Run(base::nullopt);
     return;
   }
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&FakeMediaAnalyticsClient::OnState,
-                            weak_ptr_factory_.GetWeakPtr(), callback));
+      FROM_HERE,
+      base::BindOnce(&FakeMediaAnalyticsClient::OnState,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
 
-void FakeMediaAnalyticsClient::SetState(const mri::State& state,
-                                        const StateCallback& callback) {
+void FakeMediaAnalyticsClient::SetState(
+    const mri::State& state,
+    DBusMethodCallback<mri::State> callback) {
   if (!process_running_) {
-    callback.Run(false, current_state_);
+    std::move(callback).Run(base::nullopt);
     return;
   }
   DCHECK(state.has_status()) << "Trying to set state without status.";
@@ -67,8 +72,9 @@
          "RESTARTING.";
   current_state_ = state;
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&FakeMediaAnalyticsClient::OnState,
-                            weak_ptr_factory_.GetWeakPtr(), callback));
+      FROM_HERE,
+      base::BindOnce(&FakeMediaAnalyticsClient::OnState,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
 
 void FakeMediaAnalyticsClient::SetStateSuspended() {
@@ -80,25 +86,27 @@
   current_state_ = suspended;
 }
 
-void FakeMediaAnalyticsClient::OnState(const StateCallback& callback) {
-  callback.Run(true, current_state_);
+void FakeMediaAnalyticsClient::OnState(
+    DBusMethodCallback<mri::State> callback) {
+  std::move(callback).Run(current_state_);
 }
 
 void FakeMediaAnalyticsClient::GetDiagnostics(
-    const DiagnosticsCallback& callback) {
+    DBusMethodCallback<mri::Diagnostics> callback) {
   if (!process_running_) {
     LOG(ERROR) << "Fake media analytics process not running.";
-    callback.Run(false, mri::Diagnostics());
+    std::move(callback).Run(base::nullopt);
     return;
   }
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&FakeMediaAnalyticsClient::OnGetDiagnostics,
-                            weak_ptr_factory_.GetWeakPtr(), callback));
+      FROM_HERE,
+      base::BindOnce(&FakeMediaAnalyticsClient::OnGetDiagnostics,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
 
 void FakeMediaAnalyticsClient::OnGetDiagnostics(
-    const DiagnosticsCallback& callback) {
-  callback.Run(true, diagnostics_);
+    DBusMethodCallback<mri::Diagnostics> callback) {
+  std::move(callback).Run(diagnostics_);
 }
 
 void FakeMediaAnalyticsClient::OnMediaPerception(
diff --git a/chromeos/dbus/fake_media_analytics_client.h b/chromeos/dbus/fake_media_analytics_client.h
index 1f58274..ca139829 100644
--- a/chromeos/dbus/fake_media_analytics_client.h
+++ b/chromeos/dbus/fake_media_analytics_client.h
@@ -22,13 +22,13 @@
   ~FakeMediaAnalyticsClient() override;
 
   // Inherited from MediaAnalyticsClient.
-  void GetState(const StateCallback& callback) override;
+  void GetState(DBusMethodCallback<mri::State> callback) override;
   void SetState(const mri::State& state,
-                const StateCallback& callback) override;
+                DBusMethodCallback<mri::State> callback) override;
   void SetMediaPerceptionSignalHandler(
       const MediaPerceptionSignalHandler& handler) override;
   void ClearMediaPerceptionSignalHandler() override;
-  void GetDiagnostics(const DiagnosticsCallback& callback) override;
+  void GetDiagnostics(DBusMethodCallback<mri::Diagnostics> callback) override;
 
   // Inherited from DBusClient.
   void Init(dbus::Bus* bus) override;
@@ -48,10 +48,10 @@
 
  private:
   // Echoes back the previously set state.
-  void OnState(const StateCallback& callback);
+  void OnState(DBusMethodCallback<mri::State> callback);
 
   // Runs callback with the Diagnostics proto provided in SetDiagnostics.
-  void OnGetDiagnostics(const DiagnosticsCallback& callback);
+  void OnGetDiagnostics(DBusMethodCallback<mri::Diagnostics> callback);
 
   // Runs callback with a MediaPerception proto provided in
   // FireMediaPerceptionEvent.
diff --git a/chromeos/dbus/gsm_sms_client.cc b/chromeos/dbus/gsm_sms_client.cc
index 9deade5..3f20b92 100644
--- a/chromeos/dbus/gsm_sms_client.cc
+++ b/chromeos/dbus/gsm_sms_client.cc
@@ -31,9 +31,6 @@
 class SMSProxy {
  public:
   typedef GsmSMSClient::SmsReceivedHandler SmsReceivedHandler;
-  typedef GsmSMSClient::DeleteCallback DeleteCallback;
-  typedef GsmSMSClient::GetCallback GetCallback;
-  typedef GsmSMSClient::ListCallback ListCallback;
 
   SMSProxy(dbus::Bus* bus,
            const std::string& service_name,
@@ -60,7 +57,7 @@
   }
 
   // Calls Delete method.
-  void Delete(uint32_t index, const DeleteCallback& callback) {
+  void Delete(uint32_t index, VoidDBusMethodCallback callback) {
     dbus::MethodCall method_call(modemmanager::kModemManagerSMSInterface,
                                  modemmanager::kSMSDeleteFunction);
     dbus::MessageWriter writer(&method_call);
@@ -68,11 +65,11 @@
     proxy_->CallMethod(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
         base::BindOnce(&SMSProxy::OnDelete, weak_ptr_factory_.GetWeakPtr(),
-                       callback));
+                       std::move(callback)));
   }
 
   // Calls Get method.
-  void Get(uint32_t index, const GetCallback& callback) {
+  void Get(uint32_t index, DBusMethodCallback<base::DictionaryValue> callback) {
     dbus::MethodCall method_call(modemmanager::kModemManagerSMSInterface,
                                  modemmanager::kSMSGetFunction);
     dbus::MessageWriter writer(&method_call);
@@ -80,17 +77,17 @@
     proxy_->CallMethod(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
         base::BindOnce(&SMSProxy::OnGet, weak_ptr_factory_.GetWeakPtr(),
-                       callback));
+                       std::move(callback)));
   }
 
   // Calls List method.
-  void List(const ListCallback& callback) {
+  void List(DBusMethodCallback<base::ListValue> callback) {
     dbus::MethodCall method_call(modemmanager::kModemManagerSMSInterface,
                                  modemmanager::kSMSListFunction);
     proxy_->CallMethod(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
         base::BindOnce(&SMSProxy::OnList, weak_ptr_factory_.GetWeakPtr(),
-                       callback));
+                       std::move(callback)));
   }
 
  private:
@@ -117,38 +114,42 @@
   }
 
   // Handles responses of Delete method calls.
-  void OnDelete(const DeleteCallback& callback, dbus::Response* response) {
-    if (!response)
-      return;
-    callback.Run();
+  void OnDelete(VoidDBusMethodCallback callback, dbus::Response* response) {
+    std::move(callback).Run(response);
   }
 
   // Handles responses of Get method calls.
-  void OnGet(const GetCallback& callback, dbus::Response* response) {
-    if (!response)
-      return;
-    dbus::MessageReader reader(response);
-    std::unique_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
-    base::DictionaryValue* dictionary_value = NULL;
-    if (!value.get() || !value->GetAsDictionary(&dictionary_value)) {
-      LOG(WARNING) << "Invalid response: " << response->ToString();
+  void OnGet(DBusMethodCallback<base::DictionaryValue> callback,
+             dbus::Response* response) {
+    if (!response) {
+      std::move(callback).Run(base::nullopt);
       return;
     }
-    callback.Run(*dictionary_value);
+    dbus::MessageReader reader(response);
+    auto value = base::DictionaryValue::From(dbus::PopDataAsValue(&reader));
+    if (!value) {
+      LOG(WARNING) << "Invalid response: " << response->ToString();
+      std::move(callback).Run(base::nullopt);
+      return;
+    }
+    std::move(callback).Run(std::move(*value));
   }
 
   // Handles responses of List method calls.
-  void OnList(const ListCallback& callback, dbus::Response* response) {
-    if (!response)
-      return;
-    dbus::MessageReader reader(response);
-    std::unique_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
-    base::ListValue* list_value = NULL;
-    if (!value.get() || !value->GetAsList(&list_value)) {
-      LOG(WARNING) << "Invalid response: " << response->ToString();
+  void OnList(DBusMethodCallback<base::ListValue> callback,
+              dbus::Response* response) {
+    if (!response) {
+      std::move(callback).Run(base::nullopt);
       return;
     }
-    callback.Run(*list_value);
+    dbus::MessageReader reader(response);
+    auto value = base::ListValue::From(dbus::PopDataAsValue(&reader));
+    if (!value) {
+      LOG(WARNING) << "Invalid response: " << response->ToString();
+      std::move(callback).Run(base::nullopt);
+      return;
+    }
+    std::move(callback).Run(std::move(*value));
   }
 
   dbus::ObjectProxy* proxy_;
@@ -183,23 +184,23 @@
   void Delete(const std::string& service_name,
               const dbus::ObjectPath& object_path,
               uint32_t index,
-              const DeleteCallback& callback) override {
-    GetProxy(service_name, object_path)->Delete(index, callback);
+              VoidDBusMethodCallback callback) override {
+    GetProxy(service_name, object_path)->Delete(index, std::move(callback));
   }
 
   // GsmSMSClient override.
   void Get(const std::string& service_name,
            const dbus::ObjectPath& object_path,
            uint32_t index,
-           const GetCallback& callback) override {
-    GetProxy(service_name, object_path)->Get(index, callback);
+           DBusMethodCallback<base::DictionaryValue> callback) override {
+    GetProxy(service_name, object_path)->Get(index, std::move(callback));
   }
 
   // GsmSMSClient override.
   void List(const std::string& service_name,
             const dbus::ObjectPath& object_path,
-            const ListCallback& callback) override {
-    GetProxy(service_name, object_path)->List(callback);
+            DBusMethodCallback<base::ListValue> callback) override {
+    GetProxy(service_name, object_path)->List(std::move(callback));
   }
 
   // GsmSMSClient override.
diff --git a/chromeos/dbus/gsm_sms_client.h b/chromeos/dbus/gsm_sms_client.h
index 01327e7..f34b432 100644
--- a/chromeos/dbus/gsm_sms_client.h
+++ b/chromeos/dbus/gsm_sms_client.h
@@ -13,6 +13,7 @@
 #include "base/macros.h"
 #include "chromeos/chromeos_export.h"
 #include "chromeos/dbus/dbus_client.h"
+#include "chromeos/dbus/dbus_method_call_status.h"
 
 namespace base {
 class DictionaryValue;
@@ -33,9 +34,6 @@
  public:
   typedef base::Callback<void(uint32_t index, bool complete)>
       SmsReceivedHandler;
-  typedef base::Callback<void()> DeleteCallback;
-  typedef base::Callback<void(const base::DictionaryValue& sms)> GetCallback;
-  typedef base::Callback<void(const base::ListValue& result)> ListCallback;
 
   ~GsmSMSClient() override;
 
@@ -52,22 +50,22 @@
   virtual void ResetSmsReceivedHandler(const std::string& service_name,
                                        const dbus::ObjectPath& object_path) = 0;
 
-  // Calls Delete method.  |callback| is called after the method call succeeds.
+  // Calls Delete method.  |callback| is called on method call completion.
   virtual void Delete(const std::string& service_name,
                       const dbus::ObjectPath& object_path,
                       uint32_t index,
-                      const DeleteCallback& callback) = 0;
+                      VoidDBusMethodCallback callback) = 0;
 
-  // Calls Get method.  |callback| is called after the method call succeeds.
+  // Calls Get method.  |callback| is called on method call completion.
   virtual void Get(const std::string& service_name,
                    const dbus::ObjectPath& object_path,
                    uint32_t index,
-                   const GetCallback& callback) = 0;
+                   DBusMethodCallback<base::DictionaryValue> callback) = 0;
 
-  // Calls List method.  |callback| is called after the method call succeeds.
+  // Calls List method.  |callback| is called on method call completion.
   virtual void List(const std::string& service_name,
                     const dbus::ObjectPath& object_path,
-                    const ListCallback& callback) = 0;
+                    DBusMethodCallback<base::ListValue> callback) = 0;
 
   // Requests a check for new messages. In shill this does nothing. The
   // stub implementation uses it to generate a sequence of test messages.
diff --git a/chromeos/dbus/gsm_sms_client_unittest.cc b/chromeos/dbus/gsm_sms_client_unittest.cc
index 0a44a2b..0e0dee2 100644
--- a/chromeos/dbus/gsm_sms_client_unittest.cc
+++ b/chromeos/dbus/gsm_sms_client_unittest.cc
@@ -222,13 +222,16 @@
   response_ = response.get();
 
   // Call Delete.
-  bool called = false;
-  client_->Delete(kServiceName, dbus::ObjectPath(kObjectPath), kIndex,
-                  base::Bind([](bool* called) { *called = true; }, &called));
+  base::Optional<bool> success;
+  client_->Delete(
+      kServiceName, dbus::ObjectPath(kObjectPath), kIndex,
+      base::BindOnce([](base::Optional<bool>* success_out,
+                        bool success) { success_out->emplace(success); },
+                     &success));
 
   // Run the message loop.
   base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(called);
+  EXPECT_EQ(true, success);
 }
 
 TEST_F(GsmSMSClientTest, Get) {
@@ -255,32 +258,23 @@
   response_ = response.get();
 
   // Call Get.
-  base::Value raw_result;
-  client_->Get(
-      kServiceName, dbus::ObjectPath(kObjectPath), kIndex,
-      base::Bind(
-          [](base::Value* result_out, const base::DictionaryValue& result) {
-            *result_out = result.Clone();
-          },
-          &raw_result));
+  base::Optional<base::DictionaryValue> result;
+  client_->Get(kServiceName, dbus::ObjectPath(kObjectPath), kIndex,
+               base::BindOnce(
+                   [](base::Optional<base::DictionaryValue>* result_out,
+                      base::Optional<base::DictionaryValue> result) {
+                     *result_out = std::move(result);
+                   },
+                   &result));
 
   // Run the message loop.
   base::RunLoop().RunUntilIdle();
 
   // Verify the result.
-  const auto result = base::DictionaryValue::From(
-      base::Value::ToUniquePtrValue(std::move(raw_result)));
-  ASSERT_TRUE(result);
-  EXPECT_EQ(2u, result->size());
-
-  const base::Value* number =
-      result->FindKeyOfType(kNumberKey, base::Value::Type::STRING);
-  ASSERT_TRUE(number);
-  EXPECT_EQ(kExampleNumber, number->GetString());
-  const base::Value* text =
-      result->FindKeyOfType(kTextKey, base::Value::Type::STRING);
-  ASSERT_TRUE(text);
-  EXPECT_EQ(kExampleText, text->GetString());
+  base::DictionaryValue expected_result;
+  expected_result.SetKey(kNumberKey, base::Value(kExampleNumber));
+  expected_result.SetKey(kTextKey, base::Value(kExampleText));
+  EXPECT_EQ(expected_result, result);
 }
 
 TEST_F(GsmSMSClientTest, List) {
@@ -308,11 +302,12 @@
   response_ = response.get();
 
   // Call List.
-  base::Value result;
+  base::Optional<base::ListValue> result;
   client_->List(kServiceName, dbus::ObjectPath(kObjectPath),
-                base::Bind(
-                    [](base::Value* result_out, const base::ListValue& result) {
-                      *result_out = result.Clone();
+                base::BindOnce(
+                    [](base::Optional<base::ListValue>* result_out,
+                       base::Optional<base::ListValue> result) {
+                      *result_out = std::move(result);
                     },
                     &result));
 
diff --git a/chromeos/dbus/media_analytics_client.cc b/chromeos/dbus/media_analytics_client.cc
index 5dbf385c..9d8d696 100644
--- a/chromeos/dbus/media_analytics_client.cc
+++ b/chromeos/dbus/media_analytics_client.cc
@@ -6,6 +6,7 @@
 
 #include <cstdint>
 #include <string>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/logging.h"
@@ -36,17 +37,17 @@
     media_perception_signal_handler_.Reset();
   }
 
-  void GetState(const StateCallback& callback) override {
+  void GetState(DBusMethodCallback<mri::State> callback) override {
     dbus::MethodCall method_call(media_perception::kMediaPerceptionServiceName,
                                  media_perception::kStateFunction);
     dbus_proxy_->CallMethod(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
         base::BindOnce(&MediaAnalyticsClientImpl::OnState,
-                       weak_ptr_factory_.GetWeakPtr(), callback));
+                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
   }
 
   void SetState(const mri::State& state,
-                const StateCallback& callback) override {
+                DBusMethodCallback<mri::State> callback) override {
     DCHECK(state.has_status()) << "Attempting to SetState without status set.";
 
     dbus::MethodCall method_call(media_perception::kMediaPerceptionServiceName,
@@ -58,17 +59,17 @@
     dbus_proxy_->CallMethod(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
         base::BindOnce(&MediaAnalyticsClientImpl::OnState,
-                       weak_ptr_factory_.GetWeakPtr(), callback));
+                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
   }
 
-  void GetDiagnostics(const DiagnosticsCallback& callback) override {
+  void GetDiagnostics(DBusMethodCallback<mri::Diagnostics> callback) override {
     dbus::MethodCall method_call(media_perception::kMediaPerceptionServiceName,
                                  media_perception::kGetDiagnosticsFunction);
     // TODO(lasoren): Verify that this timeout setting is sufficient.
     dbus_proxy_->CallMethod(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
         base::BindOnce(&MediaAnalyticsClientImpl::OnGetDiagnostics,
-                       weak_ptr_factory_.GetWeakPtr(), callback));
+                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
   }
 
  protected:
@@ -120,11 +121,12 @@
     media_perception_signal_handler_.Run(media_perception);
   }
 
-  void OnState(const StateCallback& callback, dbus::Response* response) {
+  void OnState(DBusMethodCallback<mri::State> callback,
+               dbus::Response* response) {
     mri::State state;
     if (!response) {
       LOG(ERROR) << "Call to State failed to get response.";
-      callback.Run(false, state);
+      std::move(callback).Run(base::nullopt);
       return;
     }
 
@@ -134,25 +136,25 @@
     dbus::MessageReader reader(response);
     if (!reader.PopArrayOfBytes(&bytes, &length)) {
       LOG(ERROR) << "Invalid D-Bus response: " << response->ToString();
-      callback.Run(false, state);
+      std::move(callback).Run(base::nullopt);
       return;
     }
 
     if (!state.ParseFromArray(bytes, length)) {
       LOG(ERROR) << "Failed to parse State message.";
-      callback.Run(false, state);
+      std::move(callback).Run(base::nullopt);
       return;
     }
 
-    callback.Run(true, state);
+    std::move(callback).Run(std::move(state));
   }
 
-  void OnGetDiagnostics(const DiagnosticsCallback& callback,
+  void OnGetDiagnostics(DBusMethodCallback<mri::Diagnostics> callback,
                         dbus::Response* response) {
     mri::Diagnostics diagnostics;
     if (!response) {
       LOG(ERROR) << "Call to GetDiagnostics failed to get response.";
-      callback.Run(false, diagnostics);
+      std::move(callback).Run(base::nullopt);
       return;
     }
 
@@ -162,17 +164,17 @@
     dbus::MessageReader reader(response);
     if (!reader.PopArrayOfBytes(&bytes, &length)) {
       LOG(ERROR) << "Invalid GetDiagnostics response: " << response->ToString();
-      callback.Run(false, diagnostics);
+      std::move(callback).Run(base::nullopt);
       return;
     }
 
     if (!diagnostics.ParseFromArray(bytes, length)) {
       LOG(ERROR) << "Failed to parse Diagnostics message.";
-      callback.Run(false, diagnostics);
+      std::move(callback).Run(base::nullopt);
       return;
     }
 
-    callback.Run(true, diagnostics);
+    std::move(callback).Run(std::move(diagnostics));
   }
 
   dbus::ObjectProxy* dbus_proxy_;
diff --git a/chromeos/dbus/media_analytics_client.h b/chromeos/dbus/media_analytics_client.h
index 383d224..15908e9 100644
--- a/chromeos/dbus/media_analytics_client.h
+++ b/chromeos/dbus/media_analytics_client.h
@@ -9,6 +9,7 @@
 #include "base/macros.h"
 #include "chromeos/chromeos_export.h"
 #include "chromeos/dbus/dbus_client.h"
+#include "chromeos/dbus/dbus_method_call_status.h"
 #include "chromeos/media_perception/media_perception.pb.h"
 
 namespace chromeos {
@@ -17,27 +18,19 @@
 // running outside of Chrome.
 class CHROMEOS_EXPORT MediaAnalyticsClient : public DBusClient {
  public:
-  // Callback type for a State proto message received from the media analytics
-  // process.
-  using StateCallback =
-      base::Callback<void(bool succeeded, const mri::State& state)>;
   // Handler type for signal received from media analytics process.
   using MediaPerceptionSignalHandler =
       base::Callback<void(const mri::MediaPerception& media_perception)>;
-  // Callback type for a Diagnostics proto message received from the media
-  // analytics process.
-  using DiagnosticsCallback =
-      base::Callback<void(bool succeeded, const mri::Diagnostics& diagnostics)>;
 
   ~MediaAnalyticsClient() override;
 
   // Gets the media analytics process state.
-  virtual void GetState(const StateCallback& callback) = 0;
+  virtual void GetState(DBusMethodCallback<mri::State> callback) = 0;
 
   // Sets the media analytics process state. |state.status| is expected to be
   // set.
   virtual void SetState(const mri::State& state,
-                        const StateCallback& callback) = 0;
+                        DBusMethodCallback<mri::State> callback) = 0;
 
   // Register event handler for the MediaPerception protos received as signal
   // from the media analytics process.
@@ -50,7 +43,8 @@
 
   // API for getting diagnostic information from the media analytics process
   // over D-Bus as a Diagnostics proto message.
-  virtual void GetDiagnostics(const DiagnosticsCallback& callback) = 0;
+  virtual void GetDiagnostics(
+      DBusMethodCallback<mri::Diagnostics> callback) = 0;
 
   // Factory function, creates new instance and returns ownership.
   // For normal usage, access the singleton via DbusThreadManager::Get().
diff --git a/chromeos/network/network_sms_handler.cc b/chromeos/network/network_sms_handler.cc
index e86464c9..1bc7f20 100644
--- a/chromeos/network/network_sms_handler.cc
+++ b/chromeos/network/network_sms_handler.cc
@@ -59,10 +59,12 @@
   void RequestUpdate() override;
 
  private:
-  void ListCallback(const base::ListValue& message_list);
+  void ListCallback(base::Optional<base::ListValue> message_list);
   void SmsReceivedCallback(uint32_t index, bool complete);
-  void GetCallback(uint32_t index, const base::DictionaryValue& dictionary);
+  void GetCallback(uint32_t index,
+                   base::Optional<base::DictionaryValue> dictionary);
   void DeleteMessages();
+  void DeleteCallback(bool success);
   void MessageReceived(const base::DictionaryValue& dictionary);
 
   NetworkSmsHandler* host_;
@@ -105,13 +107,15 @@
 }
 
 void NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::ListCallback(
-    const base::ListValue& message_list) {
+    base::Optional<base::ListValue> message_list) {
+  if (!message_list.has_value())
+    return;
+
   // This receives all messages, so clear any pending deletes.
   delete_queue_.clear();
-  for (base::ListValue::const_iterator iter = message_list.begin();
-       iter != message_list.end(); ++iter) {
-    const base::DictionaryValue* message = NULL;
-    if (iter->GetAsDictionary(&message))
+  for (const auto& entry : message_list.value()) {
+    const base::DictionaryValue* message = nullptr;
+    if (entry.GetAsDictionary(&message))
       continue;
     MessageReceived(*message);
     double index = 0;
@@ -134,9 +138,16 @@
   delete_queue_.pop_back();
   DBusThreadManager::Get()->GetGsmSMSClient()->Delete(
       service_name_, object_path_, index,
-      base::Bind(&NetworkSmsHandler::
-                 ModemManagerNetworkSmsDeviceHandler::DeleteMessages,
-                 weak_ptr_factory_.GetWeakPtr()));
+      base::BindOnce(&NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::
+                         DeleteCallback,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::DeleteCallback(
+    bool success) {
+  if (!success)
+    return;
+  DeleteMessages();
 }
 
 void NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::
@@ -146,15 +157,18 @@
     return;
   DBusThreadManager::Get()->GetGsmSMSClient()->Get(
       service_name_, object_path_, index,
-      base::Bind(&NetworkSmsHandler::
-                 ModemManagerNetworkSmsDeviceHandler::GetCallback,
-                 weak_ptr_factory_.GetWeakPtr(), index));
+      base::BindOnce(
+          &NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::GetCallback,
+          weak_ptr_factory_.GetWeakPtr(), index));
 }
 
 void NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::GetCallback(
     uint32_t index,
-    const base::DictionaryValue& dictionary) {
-  MessageReceived(dictionary);
+    base::Optional<base::DictionaryValue> dictionary) {
+  if (!dictionary.has_value())
+    return;
+
+  MessageReceived(dictionary.value());
   delete_queue_.push_back(index);
   if (!deleting_messages_)
     DeleteMessages();
diff --git a/chromeos/network/onc/onc_certificate_importer.h b/chromeos/network/onc/onc_certificate_importer.h
index c83d82d..cc48dd4 100644
--- a/chromeos/network/onc/onc_certificate_importer.h
+++ b/chromeos/network/onc/onc_certificate_importer.h
@@ -8,19 +8,16 @@
 #include "base/callback_forward.h"
 #include "base/macros.h"
 #include "chromeos/chromeos_export.h"
+#include "chromeos/network/onc/onc_parsed_certificates.h"
 #include "components/onc/onc_constants.h"
 #include "net/cert/scoped_nss_types.h"
 
-namespace base {
-class ListValue;
-}
-
 namespace chromeos {
 namespace onc {
 
 class CHROMEOS_EXPORT CertificateImporter {
  public:
-  typedef base::Callback<void(
+  typedef base::OnceCallback<void(
       bool success,
       net::ScopedCERTCertificateList onc_trusted_certificates)>
       DoneCallback;
@@ -28,7 +25,7 @@
   CertificateImporter() {}
   virtual ~CertificateImporter() {}
 
-  // Import |certificates|, which must be a list of ONC Certificate objects.
+  // Import |certificates|.
   // Certificates are only imported with web trust for user imports. If the
   // "Remove" field of a certificate is enabled, then removes the certificate
   // from the store instead of importing.
@@ -37,9 +34,10 @@
   // |onc_trusted_certificates| will contain the list of certificates that
   // were imported and requested the TrustBit "Web".
   // Never calls |done_callback| after this importer is destructed.
-  virtual void ImportCertificates(const base::ListValue& certificates,
-                                  ::onc::ONCSource source,
-                                  const DoneCallback& done_callback) = 0;
+  virtual void ImportCertificates(
+      std::unique_ptr<OncParsedCertificates> certificates,
+      ::onc::ONCSource source,
+      DoneCallback done_callback) = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(CertificateImporter);
diff --git a/chromeos/network/onc/onc_certificate_importer_impl.cc b/chromeos/network/onc/onc_certificate_importer_impl.cc
index 0b74cf1a..1e4546d7 100644
--- a/chromeos/network/onc/onc_certificate_importer_impl.cc
+++ b/chromeos/network/onc/onc_certificate_importer_impl.cc
@@ -33,12 +33,12 @@
 
 void CallBackOnOriginLoop(
     const scoped_refptr<base::SingleThreadTaskRunner>& origin_loop,
-    const CertificateImporter::DoneCallback& callback,
+    CertificateImporter::DoneCallback callback,
     bool success,
     net::ScopedCERTCertificateList onc_trusted_certificates) {
-  origin_loop->PostTask(
-      FROM_HERE,
-      base::BindOnce(callback, success, std::move(onc_trusted_certificates)));
+  origin_loop->PostTask(FROM_HERE,
+                        base::BindOnce(std::move(callback), success,
+                                       std::move(onc_trusted_certificates)));
 }
 
 }  // namespace
@@ -55,160 +55,114 @@
 CertificateImporterImpl::~CertificateImporterImpl() = default;
 
 void CertificateImporterImpl::ImportCertificates(
-    const base::ListValue& certificates,
+    std::unique_ptr<OncParsedCertificates> certificates,
     ::onc::ONCSource source,
-    const DoneCallback& done_callback) {
-  VLOG(2) << "ONC file has " << certificates.GetSize() << " certificates";
+    DoneCallback done_callback) {
+  VLOG(2) << "ONC file has "
+          << certificates->server_or_authority_certificates().size()
+          << " server/authority certificates, "
+          << certificates->client_certificates().size()
+          << " client certificates";
+
   // |done_callback| must only be called as long as |this| still exists.
   // Thereforce, call back to |this|. This check of |this| must happen last and
   // on the origin thread.
   DoneCallback callback_to_this =
-      base::Bind(&CertificateImporterImpl::RunDoneCallback,
-                 weak_factory_.GetWeakPtr(),
-                 done_callback);
+      base::BindOnce(&CertificateImporterImpl::RunDoneCallback,
+                     weak_factory_.GetWeakPtr(), std::move(done_callback));
 
   // |done_callback| must be called on the origin thread.
   DoneCallback callback_on_origin_loop =
-      base::Bind(&CallBackOnOriginLoop,
-                 base::ThreadTaskRunnerHandle::Get(),
-                 callback_to_this);
+      base::BindOnce(&CallBackOnOriginLoop, base::ThreadTaskRunnerHandle::Get(),
+                     std::move(callback_to_this));
 
   // This is the actual function that imports the certificates.
-  base::Closure import_certs_callback =
-      base::Bind(&ParseAndStoreCertificates,
-                 source,
-                 callback_on_origin_loop,
-                 base::Owned(certificates.DeepCopy()),
-                 target_nssdb_);
+  base::OnceClosure import_certs_callback = base::BindOnce(
+      &StoreCertificates, source, std::move(callback_on_origin_loop),
+      std::move(certificates), target_nssdb_);
 
   // The NSSCertDatabase must be accessed on |io_task_runner_|
-  io_task_runner_->PostTask(FROM_HERE, import_certs_callback);
+  io_task_runner_->PostTask(FROM_HERE, std::move(import_certs_callback));
 }
 
 // static
-void CertificateImporterImpl::ParseAndStoreCertificates(
+void CertificateImporterImpl::StoreCertificates(
     ::onc::ONCSource source,
-    const DoneCallback& done_callback,
-    base::ListValue* certificates,
+    DoneCallback done_callback,
+    std::unique_ptr<OncParsedCertificates> certificates,
     net::NSSCertDatabase* nssdb) {
   // Web trust is only granted to certificates imported by the user.
   bool allow_trust_imports = source == ::onc::ONC_SOURCE_USER_IMPORT;
   net::ScopedCERTCertificateList onc_trusted_certificates;
-  bool success = true;
-  for (size_t i = 0; i < certificates->GetSize(); ++i) {
-    const base::DictionaryValue* certificate = NULL;
-    certificates->GetDictionary(i, &certificate);
-    DCHECK(certificate != NULL);
 
-    VLOG(2) << "Parsing certificate at index " << i << ": " << *certificate;
+  // Even if the certificate parsing had an error at some point, we try to
+  // import the certificates which could be parsed.
+  bool success = !certificates->has_error();
 
-    if (!ParseAndStoreCertificate(source, allow_trust_imports, *certificate,
-                                  nssdb, &onc_trusted_certificates)) {
+  for (const OncParsedCertificates::ServerOrAuthorityCertificate&
+           server_or_authority_cert :
+       certificates->server_or_authority_certificates()) {
+    if (!StoreServerOrCaCertificate(source, allow_trust_imports,
+                                    server_or_authority_cert, nssdb,
+                                    &onc_trusted_certificates)) {
       success = false;
-      LOG(ERROR) << "Cannot parse certificate at index " << i;
     } else {
-      VLOG(2) << "Successfully imported certificate at index " << i;
+      VLOG(2) << "Successfully imported certificate with GUID "
+              << server_or_authority_cert.guid();
     }
   }
 
-  done_callback.Run(success, std::move(onc_trusted_certificates));
+  for (const OncParsedCertificates::ClientCertificate& client_cert :
+       certificates->client_certificates()) {
+    if (!StoreClientCertificate(client_cert, nssdb)) {
+      success = false;
+    } else {
+      VLOG(2) << "Successfully imported certificate with GUID "
+              << client_cert.guid();
+    }
+  }
+
+  std::move(done_callback).Run(success, std::move(onc_trusted_certificates));
 }
 
 void CertificateImporterImpl::RunDoneCallback(
-    const CertificateImporter::DoneCallback& callback,
+    DoneCallback callback,
     bool success,
     net::ScopedCERTCertificateList onc_trusted_certificates) {
   if (!success)
     NET_LOG_ERROR("ONC Certificate Import Error", "");
-  callback.Run(success, std::move(onc_trusted_certificates));
+  std::move(callback).Run(success, std::move(onc_trusted_certificates));
 }
 
-bool CertificateImporterImpl::ParseAndStoreCertificate(
+bool CertificateImporterImpl::StoreServerOrCaCertificate(
     ::onc::ONCSource source,
     bool allow_trust_imports,
-    const base::DictionaryValue& certificate,
-    net::NSSCertDatabase* nssdb,
-    net::ScopedCERTCertificateList* onc_trusted_certificates) {
-  std::string guid;
-  certificate.GetStringWithoutPathExpansion(::onc::certificate::kGUID, &guid);
-  DCHECK(!guid.empty());
-
-  std::string cert_type;
-  certificate.GetStringWithoutPathExpansion(::onc::certificate::kType,
-                                            &cert_type);
-  if (cert_type == ::onc::certificate::kServer ||
-      cert_type == ::onc::certificate::kAuthority) {
-    return ParseServerOrCaCertificate(source, allow_trust_imports, cert_type,
-                                      guid, certificate, nssdb,
-                                      onc_trusted_certificates);
-  } else if (cert_type == ::onc::certificate::kClient) {
-    return ParseClientCertificate(guid, certificate, nssdb);
-  }
-
-  NOTREACHED();
-  return false;
-}
-
-bool CertificateImporterImpl::ParseServerOrCaCertificate(
-    ::onc::ONCSource source,
-    bool allow_trust_imports,
-    const std::string& cert_type,
-    const std::string& guid,
-    const base::DictionaryValue& certificate,
+    const OncParsedCertificates::ServerOrAuthorityCertificate& certificate,
     net::NSSCertDatabase* nssdb,
     net::ScopedCERTCertificateList* onc_trusted_certificates) {
   // Device policy can't import certificates.
   if (source == ::onc::ONC_SOURCE_DEVICE_POLICY) {
     // This isn't a parsing error.
-    LOG(WARNING) << "Refusing to import certificate from device policy:"
-                 << guid;
+    LOG(WARNING) << "Refusing to import certificate from device policy: "
+                 << certificate.guid();
     return true;
   }
 
-  bool web_trust_flag = false;
-  const base::ListValue* trust_list = NULL;
-  if (certificate.GetListWithoutPathExpansion(::onc::certificate::kTrustBits,
-                                              &trust_list)) {
-    for (base::ListValue::const_iterator it = trust_list->begin();
-         it != trust_list->end(); ++it) {
-      std::string trust_type;
-      if (!it->GetAsString(&trust_type))
-        NOTREACHED();
-
-      if (trust_type == ::onc::certificate::kWeb) {
-        // "Web" implies that the certificate is to be trusted for SSL
-        // identification.
-        web_trust_flag = true;
-      } else {
-        // Trust bits should only increase trust and never restrict. Thus,
-        // ignoring unknown bits should be safe.
-        LOG(WARNING) << "Certificate contains unknown trust type "
-                     << trust_type;
-      }
+  bool import_with_ssl_trust = false;
+  if (certificate.web_trust_requested()) {
+    if (!allow_trust_imports) {
+      LOG(WARNING) << "Web trust not granted for certificate: "
+                   << certificate.guid();
+    } else {
+      import_with_ssl_trust = true;
     }
   }
 
-  bool import_with_ssl_trust = false;
-  if (web_trust_flag) {
-    if (!allow_trust_imports)
-      LOG(WARNING) << "Web trust not granted for certificate: " << guid;
-    else
-      import_with_ssl_trust = true;
-  }
-
-  std::string x509_data;
-  if (!certificate.GetStringWithoutPathExpansion(::onc::certificate::kX509,
-                                                 &x509_data) ||
-      x509_data.empty()) {
-    LOG(ERROR) << "Certificate missing appropriate certificate data for type: "
-               << cert_type;
-    return false;
-  }
-
-  net::ScopedCERTCertificate x509_cert = DecodePEMCertificate(x509_data);
+  net::ScopedCERTCertificate x509_cert =
+      net::x509_util::CreateCERTCertificateFromX509Certificate(
+          certificate.certificate().get());
   if (!x509_cert.get()) {
-    LOG(ERROR) << "Unable to create certificate from PEM encoding, type: "
-               << cert_type;
+    LOG(ERROR) << "Unable to create certificate: " << certificate.guid();
     return false;
   }
 
@@ -218,8 +172,10 @@
 
   if (x509_cert.get()->isperm) {
     net::CertType net_cert_type =
-        cert_type == ::onc::certificate::kServer ? net::SERVER_CERT
-                                                 : net::CA_CERT;
+        certificate.type() == OncParsedCertificates::
+                                  ServerOrAuthorityCertificate::Type::kServer
+            ? net::SERVER_CERT
+            : net::CA_CERT;
     VLOG(1) << "Certificate is already installed.";
     net::NSSCertDatabase::TrustBits missing_trust_bits =
         trust & ~nssdb->GetCertTrust(x509_cert.get(), net_cert_type);
@@ -232,7 +188,7 @@
         success = nssdb->SetCertTrust(x509_cert.get(), net_cert_type, trust);
       }
       if (!success) {
-        LOG(ERROR) << "Certificate of type " << cert_type
+        LOG(ERROR) << "Certificate " << certificate.guid()
                    << " was already present, but trust couldn't be set."
                    << error_reason;
       }
@@ -242,49 +198,35 @@
     cert_list.push_back(net::x509_util::DupCERTCertificate(x509_cert.get()));
     net::NSSCertDatabase::ImportCertFailureList failures;
     bool success = false;
-    if (cert_type == ::onc::certificate::kServer)
+    if (certificate.type() ==
+        OncParsedCertificates::ServerOrAuthorityCertificate::Type::kServer)
       success = nssdb->ImportServerCert(cert_list, trust, &failures);
     else  // Authority cert
       success = nssdb->ImportCACerts(cert_list, trust, &failures);
 
     if (!failures.empty()) {
       std::string error_string = net::ErrorToString(failures[0].net_error);
-      LOG(ERROR) << "Error ( " << error_string
-                 << " ) importing certificate of type " << cert_type;
+      LOG(ERROR) << "Error ( " << error_string << " ) importing certificate "
+                 << certificate.guid();
       return false;
     }
 
     if (!success) {
-      LOG(ERROR) << "Unknown error importing " << cert_type << " certificate.";
+      LOG(ERROR) << "Unknown error importing certificate "
+                 << certificate.guid();
       return false;
     }
   }
 
-  if (web_trust_flag && onc_trusted_certificates)
+  if (certificate.web_trust_requested() && onc_trusted_certificates)
     onc_trusted_certificates->push_back(std::move(x509_cert));
 
   return true;
 }
 
-bool CertificateImporterImpl::ParseClientCertificate(
-    const std::string& guid,
-    const base::DictionaryValue& certificate,
+bool CertificateImporterImpl::StoreClientCertificate(
+    const OncParsedCertificates::ClientCertificate& certificate,
     net::NSSCertDatabase* nssdb) {
-  std::string pkcs12_data;
-  if (!certificate.GetStringWithoutPathExpansion(::onc::certificate::kPKCS12,
-                                                 &pkcs12_data) ||
-      pkcs12_data.empty()) {
-    LOG(ERROR) << "PKCS12 data is missing for client certificate.";
-    return false;
-  }
-
-  std::string decoded_pkcs12;
-  if (!base::Base64Decode(pkcs12_data, &decoded_pkcs12)) {
-    LOG(ERROR) << "Unable to base64 decode PKCS#12 data: \"" << pkcs12_data
-               << "\".";
-    return false;
-  }
-
   // Since this has a private key, always use the private module.
   crypto::ScopedPK11Slot private_slot(nssdb->GetPrivateSlot());
   if (!private_slot)
@@ -293,22 +235,24 @@
   net::ScopedCERTCertificateList imported_certs;
 
   int import_result =
-      nssdb->ImportFromPKCS12(private_slot.get(), decoded_pkcs12,
+      nssdb->ImportFromPKCS12(private_slot.get(), certificate.pkcs12_data(),
                               base::string16(), false, &imported_certs);
   if (import_result != net::OK) {
     std::string error_string = net::ErrorToString(import_result);
-    LOG(ERROR) << "Unable to import client certificate, error: "
-               << error_string;
+    LOG(ERROR) << "Unable to import client certificate with guid "
+               << certificate.guid() << ", error: " << error_string;
     return false;
   }
 
   if (imported_certs.size() == 0) {
-    LOG(WARNING) << "PKCS12 data contains no importable certificates.";
+    LOG(WARNING) << "PKCS12 data contains no importable certificates for guid "
+                 << certificate.guid();
     return true;
   }
 
   if (imported_certs.size() != 1) {
-    LOG(WARNING) << "ONC File: PKCS12 data contains more than one certificate. "
+    LOG(WARNING) << "PKCS12 data for guid " << certificate.guid()
+                 << " contains more than one certificate. "
                     "Only the first one will be imported.";
   }
 
@@ -319,10 +263,12 @@
   SECKEYPrivateKey* private_key = PK11_FindPrivateKeyFromCert(
       cert_result->slot, cert_result, nullptr /* wincx */);
   if (private_key) {
-    PK11_SetPrivateKeyNickname(private_key, const_cast<char*>(guid.c_str()));
+    PK11_SetPrivateKeyNickname(private_key,
+                               const_cast<char*>(certificate.guid().c_str()));
     SECKEY_DestroyPrivateKey(private_key);
   } else {
-    LOG(WARNING) << "Unable to find private key for certificate.";
+    LOG(WARNING) << "Unable to find private key for certificate "
+                 << certificate.guid();
   }
   return true;
 }
diff --git a/chromeos/network/onc/onc_certificate_importer_impl.h b/chromeos/network/onc/onc_certificate_importer_impl.h
index ee311e9..85e3ee0 100644
--- a/chromeos/network/onc/onc_certificate_importer_impl.h
+++ b/chromeos/network/onc/onc_certificate_importer_impl.h
@@ -15,11 +15,10 @@
 #include "base/memory/weak_ptr.h"
 #include "chromeos/chromeos_export.h"
 #include "chromeos/network/onc/onc_certificate_importer.h"
+#include "chromeos/network/onc/onc_parsed_certificates.h"
 #include "components/onc/onc_constants.h"
 
 namespace base {
-class DictionaryValue;
-class ListValue;
 class SequencedTaskRunner;
 }
 
@@ -45,47 +44,37 @@
   ~CertificateImporterImpl() override;
 
   // CertificateImporter overrides
-  void ImportCertificates(const base::ListValue& certificates,
+  void ImportCertificates(std::unique_ptr<OncParsedCertificates> certificates,
                           ::onc::ONCSource source,
-                          const DoneCallback& done_callback) override;
+                          DoneCallback done_callback) override;
 
  private:
-  void RunDoneCallback(const CertificateImporter::DoneCallback& callback,
+  void RunDoneCallback(DoneCallback callback,
                        bool success,
                        net::ScopedCERTCertificateList onc_trusted_certificates);
 
   // This is the synchronous implementation of ImportCertificates. It is
   // executed on the given |io_task_runner_|.
-  static void ParseAndStoreCertificates(::onc::ONCSource source,
-                                        const DoneCallback& done_callback,
-                                        base::ListValue* certificates,
-                                        net::NSSCertDatabase* nssdb);
-
-  // Parses and stores |certificate| in the certificate store. Returns true if
-  // the operation succeeded.
-  static bool ParseAndStoreCertificate(
+  static void StoreCertificates(
       ::onc::ONCSource source,
-      bool allow_trust_imports,
-      const base::DictionaryValue& certificate,
-      net::NSSCertDatabase* nssdb,
-      net::ScopedCERTCertificateList* onc_trusted_certificates);
+      DoneCallback done_callback,
+      std::unique_ptr<OncParsedCertificates> certificates,
+      net::NSSCertDatabase* nssdb);
 
   // Imports the Server or CA certificate |certificate|. Web trust is only
   // applied if the certificate requests the TrustBits attribute "Web" and if
   // the |allow_trust_imports| permission is granted, otherwise the attribute is
   // ignored.
-  static bool ParseServerOrCaCertificate(
+  static bool StoreServerOrCaCertificate(
       ::onc::ONCSource source,
       bool allow_trust_imports,
-      const std::string& cert_type,
-      const std::string& guid,
-      const base::DictionaryValue& certificate,
+      const OncParsedCertificates::ServerOrAuthorityCertificate& certificate,
       net::NSSCertDatabase* nssdb,
       net::ScopedCERTCertificateList* onc_trusted_certificates);
 
-  static bool ParseClientCertificate(const std::string& guid,
-                                     const base::DictionaryValue& certificate,
-                                     net::NSSCertDatabase* nssdb);
+  static bool StoreClientCertificate(
+      const OncParsedCertificates::ClientCertificate& certificate,
+      net::NSSCertDatabase* nssdb);
 
   // The task runner to use for NSSCertDatabase accesses.
   scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
diff --git a/chromeos/network/onc/onc_certificate_importer_impl_unittest.cc b/chromeos/network/onc/onc_certificate_importer_impl_unittest.cc
index 1dfa0634..c9af2b9 100644
--- a/chromeos/network/onc/onc_certificate_importer_impl_unittest.cc
+++ b/chromeos/network/onc/onc_certificate_importer_impl_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
 #include "chromeos/network/certificate_helper.h"
+#include "chromeos/network/onc/onc_parsed_certificates.h"
 #include "chromeos/network/onc/onc_test_utils.h"
 #include "components/onc/onc_constants.h"
 #include "crypto/scoped_test_nss_db.h"
@@ -76,11 +77,10 @@
     web_trust_certificates_.clear();
     CertificateImporterImpl importer(task_runner_, test_nssdb_.get());
     importer.ImportCertificates(
-        *certificates,
+        std::make_unique<chromeos::onc::OncParsedCertificates>(*certificates),
         ::onc::ONC_SOURCE_USER_IMPORT,  // allow web trust
         base::Bind(&ONCCertificateImporterImplTest::OnImportCompleted,
-                   base::Unretained(this),
-                   expected_success));
+                   base::Unretained(this), expected_success));
 
     task_runner_->RunUntilIdle();
 
diff --git a/chromeos/network/onc/onc_parsed_certificates.cc b/chromeos/network/onc/onc_parsed_certificates.cc
new file mode 100644
index 0000000..a4334562
--- /dev/null
+++ b/chromeos/network/onc/onc_parsed_certificates.cc
@@ -0,0 +1,269 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/network/onc/onc_parsed_certificates.h"
+
+#include <string>
+#include <vector>
+
+#include "base/base64.h"
+#include "base/optional.h"
+#include "base/values.h"
+#include "chromeos/network/onc/onc_utils.h"
+#include "components/onc/onc_constants.h"
+#include "net/cert/x509_certificate.h"
+
+namespace chromeos {
+namespace onc {
+
+namespace {
+
+enum class CertificateType { kServer, kAuthority, kClient };
+
+// Returns true if the certificate described by |onc_certificate| requests web
+// trust.
+bool HasWebTrustFlag(const base::Value& onc_certificate) {
+  DCHECK(onc_certificate.is_dict());
+
+  bool web_trust_flag = false;
+  const base::Value* trust_list = onc_certificate.FindKeyOfType(
+      ::onc::certificate::kTrustBits, base::Value::Type::LIST);
+  if (!trust_list)
+    return false;
+
+  for (const base::Value& trust_entry : trust_list->GetList()) {
+    DCHECK(trust_entry.is_string());
+
+    if (trust_entry.GetString() == ::onc::certificate::kWeb) {
+      // "Web" implies that the certificate is to be trusted for SSL
+      // identification.
+      web_trust_flag = true;
+    } else {
+      // Trust bits should only increase trust and never restrict. Thus,
+      // ignoring unknown bits should be safe.
+      LOG(WARNING) << "Certificate contains unknown trust type "
+                   << trust_entry.GetString();
+    }
+  }
+
+  return web_trust_flag;
+}
+
+// Converts the ONC string certificate type into the CertificateType enum.
+// Returns |base::nullopt| if the certificate type was not understood.
+base::Optional<CertificateType> GetCertTypeAsEnum(
+    const std::string& cert_type) {
+  if (cert_type == ::onc::certificate::kServer) {
+    return CertificateType::kServer;
+  }
+
+  if (cert_type == ::onc::certificate::kAuthority) {
+    return CertificateType::kAuthority;
+  }
+
+  if (cert_type == ::onc::certificate::kClient) {
+    return CertificateType::kClient;
+  }
+
+  return base::nullopt;
+}
+
+}  // namespace
+
+OncParsedCertificates::ServerOrAuthorityCertificate::
+    ServerOrAuthorityCertificate(
+        Type type,
+        const std::string& guid,
+        const scoped_refptr<net::X509Certificate>& certificate,
+        bool web_trust_requested)
+    : type_(type),
+      guid_(guid),
+      certificate_(certificate),
+      web_trust_requested_(web_trust_requested) {}
+
+OncParsedCertificates::ServerOrAuthorityCertificate::
+    ServerOrAuthorityCertificate(const ServerOrAuthorityCertificate& other) =
+        default;
+
+OncParsedCertificates::ServerOrAuthorityCertificate&
+OncParsedCertificates::ServerOrAuthorityCertificate::operator=(
+    const ServerOrAuthorityCertificate& other) = default;
+
+OncParsedCertificates::ServerOrAuthorityCertificate::
+    ServerOrAuthorityCertificate(ServerOrAuthorityCertificate&& other) =
+        default;
+
+OncParsedCertificates::ServerOrAuthorityCertificate::
+    ~ServerOrAuthorityCertificate() = default;
+
+bool OncParsedCertificates::ServerOrAuthorityCertificate::operator==(
+    const ServerOrAuthorityCertificate& other) const {
+  if (type() != other.type())
+    return false;
+
+  if (guid() != other.guid())
+    return false;
+
+  if (!certificate()->Equals(other.certificate().get()))
+    return false;
+
+  if (web_trust_requested() != other.web_trust_requested())
+    return false;
+
+  return true;
+}
+
+bool OncParsedCertificates::ServerOrAuthorityCertificate::operator!=(
+    const ServerOrAuthorityCertificate& other) const {
+  return !(*this == other);
+}
+
+OncParsedCertificates::ClientCertificate::ClientCertificate(
+    const std::string& guid,
+    const std::string& pkcs12_data)
+    : guid_(guid), pkcs12_data_(pkcs12_data) {}
+
+OncParsedCertificates::ClientCertificate::ClientCertificate(
+    const ClientCertificate& other) = default;
+
+OncParsedCertificates::ClientCertificate&
+OncParsedCertificates::ClientCertificate::operator=(
+    const ClientCertificate& other) = default;
+
+OncParsedCertificates::ClientCertificate::ClientCertificate(
+    ClientCertificate&& other) = default;
+
+OncParsedCertificates::ClientCertificate::~ClientCertificate() = default;
+
+bool OncParsedCertificates::ClientCertificate::operator==(
+    const ClientCertificate& other) const {
+  if (guid() != other.guid())
+    return false;
+
+  if (pkcs12_data() != other.pkcs12_data())
+    return false;
+
+  return true;
+}
+
+bool OncParsedCertificates::ClientCertificate::operator!=(
+    const ClientCertificate& other) const {
+  return !(*this == other);
+}
+
+OncParsedCertificates::OncParsedCertificates()
+    : OncParsedCertificates(base::ListValue()) {}
+
+OncParsedCertificates::OncParsedCertificates(
+    const base::Value& onc_certificates) {
+  if (!onc_certificates.is_list()) {
+    LOG(WARNING) << "Value is not a list";
+    has_error_ = true;
+    return;
+  }
+
+  for (size_t i = 0; i < onc_certificates.GetList().size(); ++i) {
+    const base::Value& onc_certificate = onc_certificates.GetList().at(i);
+    DCHECK(onc_certificate.is_dict());
+
+    VLOG(2) << "Parsing certificate at index " << i << ": " << onc_certificate;
+
+    if (!ParseCertificate(onc_certificate)) {
+      has_error_ = true;
+      LOG(ERROR) << "Cannot parse certificate at index " << i;
+    } else {
+      VLOG(2) << "Successfully parsed certificate at index " << i;
+    }
+  }
+}
+
+OncParsedCertificates::~OncParsedCertificates() = default;
+
+bool OncParsedCertificates::ParseCertificate(
+    const base::Value& onc_certificate) {
+  const base::Value* guid_key = onc_certificate.FindKeyOfType(
+      ::onc::certificate::kGUID, base::Value::Type::STRING);
+  DCHECK(guid_key);
+  std::string guid = guid_key->GetString();
+
+  const base::Value* type_key = onc_certificate.FindKeyOfType(
+      ::onc::certificate::kType, base::Value::Type::STRING);
+  DCHECK(type_key);
+  base::Optional<CertificateType> type_opt =
+      GetCertTypeAsEnum(type_key->GetString());
+  if (!type_opt)
+    return false;
+
+  switch (type_opt.value()) {
+    case CertificateType::kServer:
+      return ParseServerOrCaCertificate(
+          ServerOrAuthorityCertificate::Type::kServer, guid, onc_certificate);
+    case CertificateType::kAuthority:
+      return ParseServerOrCaCertificate(
+          ServerOrAuthorityCertificate::Type::kAuthority, guid,
+          onc_certificate);
+    case CertificateType::kClient:
+      return ParseClientCertificate(guid, onc_certificate);
+    default:
+      NOTREACHED();
+      return false;
+  }
+  return false;
+}
+
+bool OncParsedCertificates::ParseServerOrCaCertificate(
+    ServerOrAuthorityCertificate::Type type,
+    const std::string& guid,
+    const base::Value& onc_certificate) {
+  bool web_trust_requested = HasWebTrustFlag(onc_certificate);
+  const base::Value* x509_data_key = onc_certificate.FindKeyOfType(
+      ::onc::certificate::kX509, base::Value::Type::STRING);
+  if (!x509_data_key || x509_data_key->GetString().empty()) {
+    LOG(ERROR) << "Certificate missing " << ::onc::certificate::kX509
+               << " certificate data.";
+    return false;
+  }
+
+  std::string certificate_der_data = DecodePEM(x509_data_key->GetString());
+  if (certificate_der_data.empty()) {
+    LOG(ERROR) << "Unable to create certificate from PEM encoding.";
+    return false;
+  }
+
+  scoped_refptr<net::X509Certificate> certificate =
+      net::X509Certificate::CreateFromBytes(certificate_der_data.data(),
+                                            certificate_der_data.length());
+  if (!certificate) {
+    LOG(ERROR) << "Unable to create certificate from PEM encoding.";
+    return false;
+  }
+
+  server_or_authority_certificates_.push_back(ServerOrAuthorityCertificate(
+      type, guid, certificate, web_trust_requested));
+  return true;
+}
+
+bool OncParsedCertificates::ParseClientCertificate(
+    const std::string& guid,
+    const base::Value& onc_certificate) {
+  const base::Value* base64_pkcs12_data_key = onc_certificate.FindKeyOfType(
+      ::onc::certificate::kPKCS12, base::Value::Type::STRING);
+  if (!base64_pkcs12_data_key || base64_pkcs12_data_key->GetString().empty()) {
+    LOG(ERROR) << "PKCS12 data is missing for client certificate.";
+    return false;
+  }
+
+  std::string pkcs12_data;
+  if (!base::Base64Decode(base64_pkcs12_data_key->GetString(), &pkcs12_data)) {
+    LOG(ERROR) << "Unable to base64 decode PKCS#12 data: \""
+               << base64_pkcs12_data_key->GetString() << "\".";
+    return false;
+  }
+
+  client_certificates_.push_back(ClientCertificate(guid, pkcs12_data));
+  return true;
+}
+
+}  // namespace onc
+}  // namespace chromeos
diff --git a/chromeos/network/onc/onc_parsed_certificates.h b/chromeos/network/onc/onc_parsed_certificates.h
new file mode 100644
index 0000000..5aabb32
--- /dev/null
+++ b/chromeos/network/onc/onc_parsed_certificates.h
@@ -0,0 +1,137 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_NETWORK_ONC_ONC_PARSED_CERTIFICATES_H_
+#define CHROMEOS_NETWORK_ONC_ONC_PARSED_CERTIFICATES_H_
+
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "chromeos/chromeos_export.h"
+
+namespace base {
+class Value;
+}  // namespace base
+
+namespace net {
+class X509Certificate;
+}
+
+namespace chromeos {
+namespace onc {
+
+// Represents certificates parsed from the ONC Certificates section.
+class CHROMEOS_EXPORT OncParsedCertificates {
+ public:
+  // A Server or Authority certificate parsed from ONC. The payload is
+  // represented as a net::X509Certificate.
+  class ServerOrAuthorityCertificate {
+   public:
+    enum class Type { kServer, kAuthority };
+
+    ServerOrAuthorityCertificate(
+        Type type,
+        const std::string& guid,
+        const scoped_refptr<net::X509Certificate>& certificate,
+        bool web_trust_requested);
+
+    ServerOrAuthorityCertificate(const ServerOrAuthorityCertificate& other);
+    ServerOrAuthorityCertificate& operator=(
+        const ServerOrAuthorityCertificate& other);
+    ServerOrAuthorityCertificate(ServerOrAuthorityCertificate&& other);
+    ~ServerOrAuthorityCertificate();
+
+    bool operator==(const ServerOrAuthorityCertificate& other) const;
+    bool operator!=(const ServerOrAuthorityCertificate& other) const;
+
+    Type type() const { return type_; }
+
+    const std::string& guid() const { return guid_; }
+
+    const scoped_refptr<net::X509Certificate>& certificate() const {
+      return certificate_;
+    }
+    // Returns true if the certificate definition in ONC had the "Web" TrustBit.
+    bool web_trust_requested() const { return web_trust_requested_; }
+
+   private:
+    Type type_;
+    std::string guid_;
+    scoped_refptr<net::X509Certificate> certificate_;
+    bool web_trust_requested_;
+  };
+
+  // A Client certificate parsed from ONC. The payload is the PKCS12 payload
+  // (base64 decoded).
+  class ClientCertificate {
+   public:
+    ClientCertificate(const std::string& guid, const std::string& pkcs12_data);
+
+    ClientCertificate(const ClientCertificate& other);
+    ClientCertificate& operator=(const ClientCertificate& other);
+    ClientCertificate(ClientCertificate&& other);
+    ~ClientCertificate();
+
+    bool operator==(const ClientCertificate& other) const;
+    bool operator!=(const ClientCertificate& other) const;
+
+    const std::string& guid() const { return guid_; }
+
+    // The PKCS12 payload of the certificate. Note: Contrary to the PKCS12 field
+    // in ONC, this data is not base64-encoded.
+    const std::string& pkcs12_data() const { return pkcs12_data_; }
+
+   private:
+    std::string guid_;
+    std::string pkcs12_data_;
+  };
+
+  // Constructs an empty OncParsedCertificates. It will have no error, and the
+  // certificate lists will be empty.
+  OncParsedCertificates();
+
+  // Parses |onc_certificates|. This must be a Value of type LIST, corresponding
+  // to the Certificates part of the ONC specification.
+  explicit OncParsedCertificates(const base::Value& onc_certificates);
+  ~OncParsedCertificates();
+
+  // Returns all certificates that were successfully parsed and had the type
+  // Server or Authoriy.
+  const std::vector<ServerOrAuthorityCertificate>&
+  server_or_authority_certificates() const {
+    return server_or_authority_certificates_;
+  }
+
+  // Returns all certificates that were successfully parsed and had the type
+  // Client.
+  const std::vector<ClientCertificate>& client_certificates() const {
+    return client_certificates_;
+  }
+
+  // Returns true if any parsing error occured. Note that certificates which had
+  // no parsing errors will still be available through
+  // server_or_authority_certificates() and client_certificates().
+  bool has_error() const { return has_error_; }
+
+ private:
+  bool ParseCertificate(const base::Value& onc_certificate);
+  bool ParseServerOrCaCertificate(ServerOrAuthorityCertificate::Type type,
+                                  const std::string& guid,
+                                  const base::Value& onc_certificate);
+  bool ParseClientCertificate(const std::string& guid,
+                              const base::Value& onc_certificate);
+
+  std::vector<ServerOrAuthorityCertificate> server_or_authority_certificates_;
+  std::vector<ClientCertificate> client_certificates_;
+  bool has_error_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(OncParsedCertificates);
+};
+
+}  // namespace onc
+}  // namespace chromeos
+
+#endif  // CHROMEOS_NETWORK_ONC_ONC_PARSED_CERTIFICATES_H_
diff --git a/chromeos/network/onc/onc_parsed_certificates_unittest.cc b/chromeos/network/onc/onc_parsed_certificates_unittest.cc
new file mode 100644
index 0000000..c660f8d
--- /dev/null
+++ b/chromeos/network/onc/onc_parsed_certificates_unittest.cc
@@ -0,0 +1,434 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/network/onc/onc_parsed_certificates.h"
+
+#include <memory>
+
+#include "base/json/json_reader.h"
+#include "base/optional.h"
+#include "base/strings/string_piece.h"
+#include "base/values.h"
+#include "net/cert/x509_certificate.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace onc {
+
+class OncParsedCertificatesTest : public testing::Test {
+ public:
+  OncParsedCertificatesTest() = default;
+  ~OncParsedCertificatesTest() override = default;
+
+ protected:
+  bool ReadFromJSON(
+      base::StringPiece onc_certificates_json,
+      std::unique_ptr<OncParsedCertificates>* out_onc_parsed_certificates) {
+    std::unique_ptr<base::Value> onc_certificates =
+        base::JSONReader::Read(onc_certificates_json);
+    if (!onc_certificates)
+      return false;
+    *out_onc_parsed_certificates =
+        std::make_unique<OncParsedCertificates>(*onc_certificates);
+    return true;
+  }
+};
+
+TEST_F(OncParsedCertificatesTest, ClientCert) {
+  static const char* onc_certificates_json =
+      "["
+      "  { \"GUID\": \"{f998f760-272b-6939-4c2beffe428697ac}\","
+      "    \"PKCS12\": \"YWJj\","
+      "    \"Type\": \"Client\" }"
+      "]";
+
+  std::unique_ptr<OncParsedCertificates> onc_parsed_certificates;
+  ASSERT_TRUE(ReadFromJSON(onc_certificates_json, &onc_parsed_certificates));
+
+  EXPECT_FALSE(onc_parsed_certificates->has_error());
+  EXPECT_EQ(0u,
+            onc_parsed_certificates->server_or_authority_certificates().size());
+  EXPECT_EQ(1u, onc_parsed_certificates->client_certificates().size());
+
+  const OncParsedCertificates::ClientCertificate& client_cert =
+      onc_parsed_certificates->client_certificates()[0];
+
+  EXPECT_EQ("{f998f760-272b-6939-4c2beffe428697ac}", client_cert.guid());
+  // YWJj base64-decoded is abc
+  EXPECT_EQ("abc", client_cert.pkcs12_data());
+}
+
+TEST_F(OncParsedCertificatesTest, ClientCertAndError) {
+  static const char* onc_certificates_json =
+      "["
+      "  { \"GUID\": \"{good-client-cert}\","
+      "    \"PKCS12\": \"YWJj\","
+      "    \"Type\": \"Client\" },"
+      "  { \"GUID\": \"{bad-client-cert}\","
+      "    \"PKCS12\": \"!!!\","
+      "    \"Type\": \"Client\" }"
+      "]";
+
+  std::unique_ptr<OncParsedCertificates> onc_parsed_certificates;
+  ASSERT_TRUE(ReadFromJSON(onc_certificates_json, &onc_parsed_certificates));
+
+  EXPECT_TRUE(onc_parsed_certificates->has_error());
+  EXPECT_EQ(0u,
+            onc_parsed_certificates->server_or_authority_certificates().size());
+  EXPECT_EQ(1u, onc_parsed_certificates->client_certificates().size());
+
+  const OncParsedCertificates::ClientCertificate& client_cert =
+      onc_parsed_certificates->client_certificates()[0];
+
+  EXPECT_EQ("{good-client-cert}", client_cert.guid());
+}
+
+TEST_F(OncParsedCertificatesTest, AuthorityCerts) {
+  static const char* onc_certificates_json =
+      "["
+      "  { \"GUID\": \"{trusted-cert}\","
+      "    \"TrustBits\": ["
+      "       \"Web\""
+      "    ],"
+      "    \"Type\": \"Authority\","
+      "    \"X509\": \"-----BEGIN CERTIFICATE-----\n"
+      "MIIC8zCCAdugAwIBAgIJALF9qhLor0+aMA0GCSqGSIb3DQEBBQUAMBcxFTATBgNV\n"
+      "BAMMDFRlc3QgUm9vdCBDQTAeFw0xNDA4MTQwMzA1MjlaFw0yNDA4MTEwMzA1Mjla\n"
+      "MBcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n"
+      "ADCCAQoCggEBALZJQeNCAVGofzx6cdP7zZE1F4QajvY2x9FwHfqG8267dm/oMi43\n"
+      "/TiSPWjkin1CMxRGG9wE9pFuVEDECgn97C1i4l7huiycwbFgTNrH+CJcgiBlQh5W\n"
+      "d3VP65AsSupXDiKNbJWsEerM1+72cA0J3aY1YV3Jdm2w8h6/MIbYd1I2lZcO0UbF\n"
+      "7YE9G7DyYZU8wUA4719dumGf7yucn4WJdHBj1XboNX7OAeHzERGQHA31/Y3OEGyt\n"
+      "fFUaIW/XLfR4FeovOL2RnjwdB0b1Q8GCi68SU2UZimlpZgay2gv6KgChKhWESfEB\n"
+      "v5swBtAVoB+dUZFH4VNf717swmF5whSfxOMCAwEAAaNCMEAwDwYDVR0TAQH/BAUw\n"
+      "AwEB/zAdBgNVHQ4EFgQUvPcw0TzA8nn675/JbFyT84poq4MwDgYDVR0PAQH/BAQD\n"
+      "AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBXByn7f+j/sObYWGrDkKE4HLTzaLHs6Ikj\n"
+      "JNeo8iHDYOSkSVwAv9/HgniAKxj3rd3QYl6nsMzwqrTOcBJZZWd2BQAYmv/EKhfj\n"
+      "8VXYvlxe68rLU4cQ1QkyNqdeQfRT2n5WYNJ+TpqlCF9ddennMMsi6e8ZSYOlI6H4\n"
+      "YEzlNtU5eBjxXr/OqgtTgSx4qQpr2xMQIRR/G3A9iRpAigYsXVAZYvnHRYnyPWYF\n"
+      "PX11W1UegEJyoZp8bQp09u6mIWw6mPt3gl/ya1bm3ZuOUPDGrv3qpgUHqSYGVrOy\n"
+      "2bI3oCE+eQYfuVG+9LFJTZC1M+UOx15bQMVqBNFDepRqpE9h/ILg\n"
+      "-----END CERTIFICATE-----\" },"
+      "  { \"GUID\": \"{untrusted-cert}\","
+      "    \"Type\": \"Authority\","
+      "    \"X509\": \"-----BEGIN CERTIFICATE-----\n"
+      "MIIDvzCCAqegAwIBAgIBAzANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzET\n"
+      "MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G\n"
+      "A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTE3MDYwNTE3\n"
+      "MTA0NloXDTI3MDYwMzE3MTA0NlowYDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh\n"
+      "bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3Qg\n"
+      "Q0ExEjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\n"
+      "AQoCggEBALS/0pcz5RNbd2W9cxp1KJtHWea3MOhGM21YW9ofCv/k5C3yHfiJ6GQu\n"
+      "9sPN16OO1/fN59gOEMPnVtL85ebTTuL/gk0YY4ewo97a7wo3e6y1t0PO8gc53xTp\n"
+      "w6RBPn5oRzSbe2HEGOYTzrO0puC6A+7k6+eq9G2+l1uqBpdQAdB4uNaSsOTiuUOI\n"
+      "ta4UZH1ScNQFHAkl1eJPyaiC20Exw75EbwvU/b/B7tlivzuPtQDI0d9dShOtceRL\n"
+      "X9HZckyD2JNAv2zNL2YOBNa5QygkySX9WXD+PfKpCk7Cm8TenldeXRYl5ni2REkp\n"
+      "nfa/dPuF1g3xZVjyK9aPEEnIAC2I4i0CAwEAAaOBgDB+MAwGA1UdEwEB/wQCMAAw\n"
+      "HQYDVR0OBBYEFODc4C8HiHQ6n9Mwo3GK+dal5aZTMB8GA1UdIwQYMBaAFJsmC4qY\n"
+      "qbsduR8c4xpAM+2OF4irMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAP\n"
+      "BgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQB6FEQuUDRcC5jkX3aZ\n"
+      "uuTeZEqMVL7JXgvgFqzXsPb8zIdmxr/tEDfwXx2qDf2Dpxts7Fq4vqUwimK4qV3K\n"
+      "7heLnWV2+FBvV1eeSfZ7AQj+SURkdlyo42r41+t13QUf+Z0ftR9266LSWLKrukeI\n"
+      "Mxk73hOkm/u8enhTd00dy/FN9dOFBFHseVMspWNxIkdRILgOmiyfQNRgxNYdOf0e\n"
+      "EfELR8Hn6WjZ8wAbvO4p7RTrzu1c/RZ0M+NLkID56Brbl70GC2h5681LPwAOaZ7/\n"
+      "mWQ5kekSyJjmLfF12b+h9RVAt5MrXZgk2vNujssgGf4nbWh4KZyQ6qrs778ZdDLm\n"
+      "yfUn\n"
+      "-----END CERTIFICATE-----\" }"
+      "]";
+
+  std::unique_ptr<OncParsedCertificates> onc_parsed_certificates;
+  ASSERT_TRUE(ReadFromJSON(onc_certificates_json, &onc_parsed_certificates));
+
+  EXPECT_FALSE(onc_parsed_certificates->has_error());
+  EXPECT_EQ(2u,
+            onc_parsed_certificates->server_or_authority_certificates().size());
+  EXPECT_EQ(0u, onc_parsed_certificates->client_certificates().size());
+
+  const OncParsedCertificates::ServerOrAuthorityCertificate&
+      trusted_authority_cert =
+          onc_parsed_certificates->server_or_authority_certificates()[0];
+  EXPECT_EQ(
+      OncParsedCertificates::ServerOrAuthorityCertificate::Type::kAuthority,
+      trusted_authority_cert.type());
+  EXPECT_EQ("{trusted-cert}", trusted_authority_cert.guid());
+  EXPECT_TRUE(trusted_authority_cert.web_trust_requested());
+  EXPECT_EQ("Test Root CA",
+            trusted_authority_cert.certificate()->subject().common_name);
+
+  const OncParsedCertificates::ServerOrAuthorityCertificate&
+      untrusted_authority_cert =
+          onc_parsed_certificates->server_or_authority_certificates()[1];
+  EXPECT_EQ(
+      OncParsedCertificates::ServerOrAuthorityCertificate::Type::kAuthority,
+      trusted_authority_cert.type());
+  EXPECT_EQ("{untrusted-cert}", untrusted_authority_cert.guid());
+  EXPECT_FALSE(untrusted_authority_cert.web_trust_requested());
+  EXPECT_EQ("127.0.0.1",
+            untrusted_authority_cert.certificate()->subject().common_name);
+}
+
+TEST_F(OncParsedCertificatesTest, UnknownTrustBitsIgnored) {
+  static const char* onc_certificates_json =
+      "["
+      "  { \"GUID\": \"{trusted-cert}\","
+      "    \"TrustBits\": ["
+      "       \"Unknown1\","
+      "       \"Web\","
+      "       \"Unknown2\""
+      "    ],"
+      "    \"Type\": \"Authority\","
+      "    \"X509\": \"-----BEGIN CERTIFICATE-----\n"
+      "MIIC8zCCAdugAwIBAgIJALF9qhLor0+aMA0GCSqGSIb3DQEBBQUAMBcxFTATBgNV\n"
+      "BAMMDFRlc3QgUm9vdCBDQTAeFw0xNDA4MTQwMzA1MjlaFw0yNDA4MTEwMzA1Mjla\n"
+      "MBcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n"
+      "ADCCAQoCggEBALZJQeNCAVGofzx6cdP7zZE1F4QajvY2x9FwHfqG8267dm/oMi43\n"
+      "/TiSPWjkin1CMxRGG9wE9pFuVEDECgn97C1i4l7huiycwbFgTNrH+CJcgiBlQh5W\n"
+      "d3VP65AsSupXDiKNbJWsEerM1+72cA0J3aY1YV3Jdm2w8h6/MIbYd1I2lZcO0UbF\n"
+      "7YE9G7DyYZU8wUA4719dumGf7yucn4WJdHBj1XboNX7OAeHzERGQHA31/Y3OEGyt\n"
+      "fFUaIW/XLfR4FeovOL2RnjwdB0b1Q8GCi68SU2UZimlpZgay2gv6KgChKhWESfEB\n"
+      "v5swBtAVoB+dUZFH4VNf717swmF5whSfxOMCAwEAAaNCMEAwDwYDVR0TAQH/BAUw\n"
+      "AwEB/zAdBgNVHQ4EFgQUvPcw0TzA8nn675/JbFyT84poq4MwDgYDVR0PAQH/BAQD\n"
+      "AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBXByn7f+j/sObYWGrDkKE4HLTzaLHs6Ikj\n"
+      "JNeo8iHDYOSkSVwAv9/HgniAKxj3rd3QYl6nsMzwqrTOcBJZZWd2BQAYmv/EKhfj\n"
+      "8VXYvlxe68rLU4cQ1QkyNqdeQfRT2n5WYNJ+TpqlCF9ddennMMsi6e8ZSYOlI6H4\n"
+      "YEzlNtU5eBjxXr/OqgtTgSx4qQpr2xMQIRR/G3A9iRpAigYsXVAZYvnHRYnyPWYF\n"
+      "PX11W1UegEJyoZp8bQp09u6mIWw6mPt3gl/ya1bm3ZuOUPDGrv3qpgUHqSYGVrOy\n"
+      "2bI3oCE+eQYfuVG+9LFJTZC1M+UOx15bQMVqBNFDepRqpE9h/ILg\n"
+      "-----END CERTIFICATE-----\" }"
+      "]";
+
+  std::unique_ptr<OncParsedCertificates> onc_parsed_certificates;
+  ASSERT_TRUE(ReadFromJSON(onc_certificates_json, &onc_parsed_certificates));
+
+  EXPECT_FALSE(onc_parsed_certificates->has_error());
+  EXPECT_EQ(1u,
+            onc_parsed_certificates->server_or_authority_certificates().size());
+  EXPECT_EQ(0u, onc_parsed_certificates->client_certificates().size());
+
+  const OncParsedCertificates::ServerOrAuthorityCertificate&
+      trusted_authority_cert =
+          onc_parsed_certificates->server_or_authority_certificates()[0];
+  EXPECT_EQ(
+      OncParsedCertificates::ServerOrAuthorityCertificate::Type::kAuthority,
+      trusted_authority_cert.type());
+  EXPECT_EQ("{trusted-cert}", trusted_authority_cert.guid());
+  EXPECT_TRUE(trusted_authority_cert.web_trust_requested());
+  EXPECT_EQ("Test Root CA",
+            trusted_authority_cert.certificate()->issuer().common_name);
+}
+
+TEST_F(OncParsedCertificatesTest, ServerCertAndError) {
+  static const char* onc_certificates_json =
+      "["
+      "  { \"GUID\": \"{good-server-cert}\","
+      "    \"Type\": \"Server\","
+      "    \"X509\": \"leading junk \n"
+      "-----BEGIN CERTIFICATE-----  \n"
+      "MIICWDCCAcECAxAAATANBgkqhkiG9w0BAQQFADCBkzEVMBMGA1UEChMMR29vZ2xlLCBJbm\n"
+      "MuMREwDwYDVQQLEwhDaHJvbWVPUzEiMCAGCSqGSIb3DQEJARYTZ3NwZW5jZXJAZ29vZ2xl\n"
+      "LmNvbTEaMBgGA1UEBxMRTW91bnRhaW4gVmlldywgQ0ExCzAJBgNVBAgTAkNBMQswCQYDVQ\n"
+      "QGEwJVUzENMAsGA1UEAxMEbG1hbzAeFw0xMTAzMTYyMzQ5MzhaFw0xMjAzMTUyMzQ5Mzha\n"
+      "MFMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEChMMR29vZ2xlLCBJbmMuMR\n"
+      "EwDwYDVQQLEwhDaHJvbWVPUzENMAsGA1UEAxMEbG1hbzCBnzANBgkqhkiG9w0BAQEFAAOB\n"
+      "jQAwgYkCgYEA31WiJ9LvprrhKtDlW0RdLFAO7Qjkvs+sG6j2Vp2aBSrlhALG/0BVHUhWi4\n"
+      "F/HHJho+ncLHAg5AGO0sdAjYUdQG6tfPqjLsIALtoKEZZdFe/JhmqOEaxWsSdu2S2RdPgC\n"
+      "QOsP79EH58gXwu2gejCkJDmU22WL4YLuqOc17nxbDC8CAwEAATANBgkqhkiG9w0BAQQFAA\n"
+      "OBgQCv4vMD+PMlfnftu4/6Yf/oMLE8yCOqZTQ/dWCxB9PiJnOefiBeSzSZE6Uv3G7qnblZ\n"
+      "PVZaFeJMd+ostt0viCyPucFsFgLMyyoV1dMVPVwJT5Iq1AHehWXnTBbxUK9wioA5jOEKdr\n"
+      "oKjuSSsg/Q8Wx6cpJmttQz5olGPgstmACRWA==\n"
+      "-----END CERTIFICATE-----    \n"
+      "trailing junk\" },"
+      "  { \"GUID\": \"{bad-server-cert}\","
+      "    \"Type\": \"Server\","
+      "    \"X509\": \"leading junk \n"
+      "-----BEGIN CERTIFICATE-----  \n"
+      "!!!! "
+      "MIICWDCCAcECAxAAATANBgkqhkiG9w0BAQQFADCBkzEVMBMGA1UEChMMR29vZ2xlLCBJbm\n"
+      "MuMREwDwYDVQQLEwhDaHJvbWVPUzEiMCAGCSqGSIb3DQEJARYTZ3NwZW5jZXJAZ29vZ2xl\n"
+      "LmNvbTEaMBgGA1UEBxMRTW91bnRhaW4gVmlldywgQ0ExCzAJBgNVBAgTAkNBMQswCQYDVQ\n"
+      "QGEwJVUzENMAsGA1UEAxMEbG1hbzAeFw0xMTAzMTYyMzQ5MzhaFw0xMjAzMTUyMzQ5Mzha\n"
+      "MFMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEChMMR29vZ2xlLCBJbmMuMR\n"
+      "EwDwYDVQQLEwhDaHJvbWVPUzENMAsGA1UEAxMEbG1hbzCBnzANBgkqhkiG9w0BAQEFAAOB\n"
+      "jQAwgYkCgYEA31WiJ9LvprrhKtDlW0RdLFAO7Qjkvs+sG6j2Vp2aBSrlhALG/0BVHUhWi4\n"
+      "F/HHJho+ncLHAg5AGO0sdAjYUdQG6tfPqjLsIALtoKEZZdFe/JhmqOEaxWsSdu2S2RdPgC\n"
+      "QOsP79EH58gXwu2gejCkJDmU22WL4YLuqOc17nxbDC8CAwEAATANBgkqhkiG9w0BAQQFAA\n"
+      "OBgQCv4vMD+PMlfnftu4/6Yf/oMLE8yCOqZTQ/dWCxB9PiJnOefiBeSzSZE6Uv3G7qnblZ\n"
+      "PVZaFeJMd+ostt0viCyPucFsFgLMyyoV1dMVPVwJT5Iq1AHehWXnTBbxUK9wioA5jOEKdr\n"
+      "oKjuSSsg/Q8Wx6cpJmttQz5olGPgstmACRWA==\n"
+      "-----END CERTIFICATE-----    \n"
+      "trailing junk\" }"
+      "]";
+
+  std::unique_ptr<OncParsedCertificates> onc_parsed_certificates;
+  ASSERT_TRUE(ReadFromJSON(onc_certificates_json, &onc_parsed_certificates));
+
+  EXPECT_TRUE(onc_parsed_certificates->has_error());
+  EXPECT_EQ(1u,
+            onc_parsed_certificates->server_or_authority_certificates().size());
+  EXPECT_EQ(0u, onc_parsed_certificates->client_certificates().size());
+
+  const OncParsedCertificates::ServerOrAuthorityCertificate& server_cert =
+      onc_parsed_certificates->server_or_authority_certificates()[0];
+  EXPECT_EQ(OncParsedCertificates::ServerOrAuthorityCertificate::Type::kServer,
+            server_cert.type());
+  EXPECT_EQ("{good-server-cert}", server_cert.guid());
+  EXPECT_FALSE(server_cert.web_trust_requested());
+  EXPECT_EQ("lmao", server_cert.certificate()->issuer().common_name);
+}
+
+TEST_F(OncParsedCertificatesTest, EqualityChecks) {
+  static const char* onc_certificates_json =
+      "["
+      "  { \"GUID\": \"{f998f760-272b-6939-4c2beffe428697ac}\","
+      "    \"PKCS12\": \"YWJj\","
+      "    \"Type\": \"Client\" },"
+      "  { \"GUID\": \"{authority-cert}\","
+      "    \"TrustBits\": ["
+      "       \"Web\""
+      "    ],"
+      "    \"Type\": \"Authority\","
+      "    \"X509\": \"-----BEGIN CERTIFICATE-----\n"
+      "MIIC8zCCAdugAwIBAgIJALF9qhLor0+aMA0GCSqGSIb3DQEBBQUAMBcxFTATBgNV\n"
+      "BAMMDFRlc3QgUm9vdCBDQTAeFw0xNDA4MTQwMzA1MjlaFw0yNDA4MTEwMzA1Mjla\n"
+      "MBcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n"
+      "ADCCAQoCggEBALZJQeNCAVGofzx6cdP7zZE1F4QajvY2x9FwHfqG8267dm/oMi43\n"
+      "/TiSPWjkin1CMxRGG9wE9pFuVEDECgn97C1i4l7huiycwbFgTNrH+CJcgiBlQh5W\n"
+      "d3VP65AsSupXDiKNbJWsEerM1+72cA0J3aY1YV3Jdm2w8h6/MIbYd1I2lZcO0UbF\n"
+      "7YE9G7DyYZU8wUA4719dumGf7yucn4WJdHBj1XboNX7OAeHzERGQHA31/Y3OEGyt\n"
+      "fFUaIW/XLfR4FeovOL2RnjwdB0b1Q8GCi68SU2UZimlpZgay2gv6KgChKhWESfEB\n"
+      "v5swBtAVoB+dUZFH4VNf717swmF5whSfxOMCAwEAAaNCMEAwDwYDVR0TAQH/BAUw\n"
+      "AwEB/zAdBgNVHQ4EFgQUvPcw0TzA8nn675/JbFyT84poq4MwDgYDVR0PAQH/BAQD\n"
+      "AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBXByn7f+j/sObYWGrDkKE4HLTzaLHs6Ikj\n"
+      "JNeo8iHDYOSkSVwAv9/HgniAKxj3rd3QYl6nsMzwqrTOcBJZZWd2BQAYmv/EKhfj\n"
+      "8VXYvlxe68rLU4cQ1QkyNqdeQfRT2n5WYNJ+TpqlCF9ddennMMsi6e8ZSYOlI6H4\n"
+      "YEzlNtU5eBjxXr/OqgtTgSx4qQpr2xMQIRR/G3A9iRpAigYsXVAZYvnHRYnyPWYF\n"
+      "PX11W1UegEJyoZp8bQp09u6mIWw6mPt3gl/ya1bm3ZuOUPDGrv3qpgUHqSYGVrOy\n"
+      "2bI3oCE+eQYfuVG+9LFJTZC1M+UOx15bQMVqBNFDepRqpE9h/ILg\n"
+      "-----END CERTIFICATE-----\" }"
+      "]";
+
+  std::unique_ptr<base::Value> onc_certificates =
+      base::JSONReader::Read(onc_certificates_json);
+  ASSERT_TRUE(onc_certificates);
+
+  OncParsedCertificates master(*onc_certificates);
+  EXPECT_EQ(master.server_or_authority_certificates(),
+            master.server_or_authority_certificates());
+  EXPECT_EQ(master.client_certificates(), master.client_certificates());
+
+  // Mangle the TrustBits part and assume that authorities will not be equal
+  // anymore.
+  {
+    base::Value authority_web_trust_mangled = onc_certificates->Clone();
+    base::Value* trust_bits =
+        authority_web_trust_mangled.GetList()[1].FindKeyOfType(
+            "TrustBits", base::Value::Type::LIST);
+    ASSERT_TRUE(trust_bits);
+    trust_bits->GetList()[0] = base::Value("UnknownTrustBit");
+
+    OncParsedCertificates parsed_authority_web_trust_mangled(
+        authority_web_trust_mangled);
+    EXPECT_FALSE(parsed_authority_web_trust_mangled.has_error());
+    EXPECT_NE(
+        master.server_or_authority_certificates(),
+        parsed_authority_web_trust_mangled.server_or_authority_certificates());
+    EXPECT_EQ(master.client_certificates(),
+              parsed_authority_web_trust_mangled.client_certificates());
+  }
+
+  // Mangle the guid part of an authority certificate.
+  {
+    base::Value authority_guid_mangled = onc_certificates->Clone();
+    authority_guid_mangled.GetList()[1].SetKey("GUID",
+                                               base::Value("otherguid"));
+
+    OncParsedCertificates parsed_authority_guid_mangled(authority_guid_mangled);
+    EXPECT_FALSE(parsed_authority_guid_mangled.has_error());
+    EXPECT_NE(master.server_or_authority_certificates(),
+              parsed_authority_guid_mangled.server_or_authority_certificates());
+    EXPECT_EQ(master.client_certificates(),
+              parsed_authority_guid_mangled.client_certificates());
+  }
+
+  // Mangle the type part of an authority certificate.
+  {
+    base::Value authority_type_mangled = onc_certificates->Clone();
+    authority_type_mangled.GetList()[1].SetKey("Type", base::Value("Server"));
+
+    OncParsedCertificates parsed_authority_type_mangled(authority_type_mangled);
+    EXPECT_FALSE(parsed_authority_type_mangled.has_error());
+    EXPECT_NE(master.server_or_authority_certificates(),
+              parsed_authority_type_mangled.server_or_authority_certificates());
+    EXPECT_EQ(master.client_certificates(),
+              parsed_authority_type_mangled.client_certificates());
+  }
+
+  // Mangle the X509 payload an authority certificate.
+  {
+    base::Value authority_x509_mangled = onc_certificates->Clone();
+    authority_x509_mangled.GetList()[1].SetKey(
+        "X509", base::Value("-----BEGIN CERTIFICATE-----  \n"
+                            "MIICWDCCAcECAxAAATANBgkqhkiG9w0BAQQFADCBkzEVMBMGA1"
+                            "UEChMMR29vZ2xlLCBJbm\n"
+                            "MuMREwDwYDVQQLEwhDaHJvbWVPUzEiMCAGCSqGSIb3DQEJARYT"
+                            "Z3NwZW5jZXJAZ29vZ2xl\n"
+                            "LmNvbTEaMBgGA1UEBxMRTW91bnRhaW4gVmlldywgQ0ExCzAJBg"
+                            "NVBAgTAkNBMQswCQYDVQ\n"
+                            "QGEwJVUzENMAsGA1UEAxMEbG1hbzAeFw0xMTAzMTYyMzQ5Mzha"
+                            "Fw0xMjAzMTUyMzQ5Mzha\n"
+                            "MFMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UECh"
+                            "MMR29vZ2xlLCBJbmMuMR\n"
+                            "EwDwYDVQQLEwhDaHJvbWVPUzENMAsGA1UEAxMEbG1hbzCBnzAN"
+                            "BgkqhkiG9w0BAQEFAAOB\n"
+                            "jQAwgYkCgYEA31WiJ9LvprrhKtDlW0RdLFAO7Qjkvs+"
+                            "sG6j2Vp2aBSrlhALG/0BVHUhWi4\n"
+                            "F/HHJho+ncLHAg5AGO0sdAjYUdQG6tfPqjLsIALtoKEZZdFe/"
+                            "JhmqOEaxWsSdu2S2RdPgC\n"
+                            "QOsP79EH58gXwu2gejCkJDmU22WL4YLuqOc17nxbDC8CAwEAAT"
+                            "ANBgkqhkiG9w0BAQQFAA\n"
+                            "OBgQCv4vMD+PMlfnftu4/6Yf/oMLE8yCOqZTQ/"
+                            "dWCxB9PiJnOefiBeSzSZE6Uv3G7qnblZ\n"
+                            "PVZaFeJMd+"
+                            "ostt0viCyPucFsFgLMyyoV1dMVPVwJT5Iq1AHehWXnTBbxUK9w"
+                            "ioA5jOEKdr\n"
+                            "oKjuSSsg/Q8Wx6cpJmttQz5olGPgstmACRWA==\n"
+                            "-----END CERTIFICATE-----    \n"));
+
+    OncParsedCertificates parsed_authority_x509_mangled(authority_x509_mangled);
+    EXPECT_FALSE(parsed_authority_x509_mangled.has_error());
+    EXPECT_NE(master.server_or_authority_certificates(),
+              parsed_authority_x509_mangled.server_or_authority_certificates());
+    EXPECT_EQ(master.client_certificates(),
+              parsed_authority_x509_mangled.client_certificates());
+  }
+
+  // Mangle the GUID of a client certificate.
+  {
+    base::Value client_guid_mangled = onc_certificates->Clone();
+    client_guid_mangled.GetList()[0].SetKey("GUID", base::Value("other-guid"));
+
+    OncParsedCertificates parsed_client_guid_mangled(client_guid_mangled);
+    EXPECT_FALSE(parsed_client_guid_mangled.has_error());
+    EXPECT_EQ(master.server_or_authority_certificates(),
+              parsed_client_guid_mangled.server_or_authority_certificates());
+    EXPECT_NE(master.client_certificates(),
+              parsed_client_guid_mangled.client_certificates());
+  }
+
+  // Mangle the PKCS12 payload of a client certificate.
+  {
+    base::Value client_pkcs12_mangled = onc_certificates->Clone();
+    client_pkcs12_mangled.GetList()[0].SetKey("PKCS12", base::Value("YQ=="));
+
+    OncParsedCertificates parsed_client_pkcs12_mangled(client_pkcs12_mangled);
+    EXPECT_FALSE(parsed_client_pkcs12_mangled.has_error());
+    EXPECT_EQ(master.server_or_authority_certificates(),
+              parsed_client_pkcs12_mangled.server_or_authority_certificates());
+    EXPECT_NE(master.client_certificates(),
+              parsed_client_pkcs12_mangled.client_certificates());
+  }
+}
+
+}  // namespace onc
+}  // namespace chromeos
diff --git a/chromeos/network/onc/onc_utils.cc b/chromeos/network/onc/onc_utils.cc
index 69c80a28..c086a7ee 100644
--- a/chromeos/network/onc/onc_utils.cc
+++ b/chromeos/network/onc/onc_utils.cc
@@ -386,8 +386,6 @@
   return OncMaskValues::Mask(signature, onc_object, mask);
 }
 
-namespace {
-
 std::string DecodePEM(const std::string& pem_encoded) {
   // The PEM block header used for DER certificates
   const char kCertificateHeader[] = "CERTIFICATE";
@@ -415,6 +413,8 @@
   return decoded;
 }
 
+namespace {
+
 CertPEMsByGUIDMap GetServerAndCACertsByGUID(
     const base::ListValue& certificates) {
   CertPEMsByGUIDMap certs_by_guid;
diff --git a/chromeos/network/onc/onc_utils.h b/chromeos/network/onc/onc_utils.h
index 65ffe84..800d7686 100644
--- a/chromeos/network/onc/onc_utils.h
+++ b/chromeos/network/onc/onc_utils.h
@@ -125,6 +125,10 @@
     base::DictionaryValue* global_network_config,
     base::ListValue* certificates);
 
+// Parse the given PEM encoded certificate |pem_encoded| and return the
+// contained DER encoding. Returns an empty string on failure.
+std::string DecodePEM(const std::string& pem_encoded);
+
 // Parse the given PEM encoded certificate |pem_encoded| and create a
 // CERTCertificate from it.
 CHROMEOS_EXPORT net::ScopedCERTCertificate DecodePEMCertificate(
diff --git a/chromeos/process_proxy/process_proxy.cc b/chromeos/process_proxy/process_proxy.cc
index d672e49..64ca8996 100644
--- a/chromeos/process_proxy/process_proxy.cc
+++ b/chromeos/process_proxy/process_proxy.cc
@@ -45,7 +45,8 @@
   ClearFdPair(pt_pair_);
 }
 
-int ProcessProxy::Open(const std::string& command) {
+int ProcessProxy::Open(const std::string& command,
+                       const std::string& user_id_hash) {
   if (process_launched_)
     return -1;
 
@@ -53,7 +54,7 @@
     return -1;
   }
 
-  int process_id = LaunchProcess(command, pt_pair_[PT_SLAVE_FD]);
+  int process_id = LaunchProcess(command, user_id_hash, pt_pair_[PT_SLAVE_FD]);
   process_launched_ = process_id >= 0;
 
   if (process_launched_) {
@@ -219,7 +220,9 @@
   return true;
 }
 
-int ProcessProxy::LaunchProcess(const std::string& command, int slave_fd) {
+int ProcessProxy::LaunchProcess(const std::string& command,
+                                const std::string& user_id_hash,
+                                int slave_fd) {
   base::LaunchOptions options;
 
   // Redirect crosh  process' output and input so we can read it.
@@ -232,6 +235,7 @@
       HasSwitch(chromeos::switches::kSystemInDevMode);
   options.ctrl_terminal_fd = slave_fd;
   options.environ["TERM"] = "xterm";
+  options.environ["CROS_USER_ID_HASH"] = user_id_hash;
 
   // Launch the process.
   process_.reset(new base::Process(base::LaunchProcess(
diff --git a/chromeos/process_proxy/process_proxy.h b/chromeos/process_proxy/process_proxy.h
index 8e843171..2e0ebe7e 100644
--- a/chromeos/process_proxy/process_proxy.h
+++ b/chromeos/process_proxy/process_proxy.h
@@ -39,9 +39,9 @@
 
   ProcessProxy();
 
-  // Opens a process using command |command|. Returns process ID on success, -1
-  // on failure.
-  int Open(const std::string& command);
+  // Opens a process using command |command| for the user with hash
+  // |user_id_hash|.  Returns process ID on success, -1 on failure.
+  int Open(const std::string& command, const std::string& user_id_hash);
 
   bool StartWatchingOutput(
       const scoped_refptr<base::SingleThreadTaskRunner>& watcher_runner,
@@ -75,7 +75,9 @@
   // Launches command in a new terminal process, mapping its stdout and stdin to
   // |slave_fd|.
   // Returns launched process id, or -1 on failure.
-  int LaunchProcess(const std::string& command, int slave_fd);
+  int LaunchProcess(const std::string& command,
+                    const std::string& user_id_hash,
+                    int slave_fd);
 
   // Gets called by output watcher when the process writes something to its
   // output streams. If set, |callback| should be called when the output is
diff --git a/chromeos/process_proxy/process_proxy_registry.cc b/chromeos/process_proxy/process_proxy_registry.cc
index 76972694..fc87e67 100644
--- a/chromeos/process_proxy/process_proxy_registry.cc
+++ b/chromeos/process_proxy/process_proxy_registry.cc
@@ -80,6 +80,7 @@
 }
 
 int ProcessProxyRegistry::OpenProcess(const std::string& command,
+                                      const std::string& user_id_hash,
                                       const OutputCallback& output_callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
@@ -89,7 +90,7 @@
   // Create and open new proxy.
   scoped_refptr<ProcessProxy> proxy(new ProcessProxy());
   // TODO(tbarzic): Use a random int as an id here instead of process pid.
-  int terminal_id = proxy->Open(command);
+  int terminal_id = proxy->Open(command, user_id_hash);
   if (terminal_id < 0)
     return -1;
 
diff --git a/chromeos/process_proxy/process_proxy_registry.h b/chromeos/process_proxy/process_proxy_registry.h
index 5bb34dbf..585e206 100644
--- a/chromeos/process_proxy/process_proxy_registry.h
+++ b/chromeos/process_proxy/process_proxy_registry.h
@@ -47,7 +47,9 @@
 
   // Starts new ProcessProxy (which starts new process).
   // Returns ID used for the created process. Returns -1 on failure.
-  int OpenProcess(const std::string& command, const OutputCallback& callback);
+  int OpenProcess(const std::string& command,
+                  const std::string& user_id_hash,
+                  const OutputCallback& callback);
   // Sends data to the process identified by |id|.
   bool SendInput(int id, const std::string& data);
   // Stops the process identified by |id|.
diff --git a/chromeos/process_proxy/process_proxy_unittest.cc b/chromeos/process_proxy/process_proxy_unittest.cc
index ef22021..7cbcbd1 100644
--- a/chromeos/process_proxy/process_proxy_unittest.cc
+++ b/chromeos/process_proxy/process_proxy_unittest.cc
@@ -32,6 +32,7 @@
 const char kTestLineExpected[] = "abcdefgh\r\n";
 
 const char kCatCommand[] = "cat";
+const char kFakeUserHash[] = "0123456789abcdef";
 const char kStdoutType[] = "stdout";
 const int kTestLineNum = 100;
 
@@ -186,7 +187,7 @@
     registry_ = ProcessProxyRegistry::Get();
 
     terminal_id_ = registry_->OpenProcess(
-        kCatCommand,
+        kCatCommand, kFakeUserHash,
         base::Bind(&ProcessProxyTest::HandleRead, base::Unretained(this)));
 
     EXPECT_GE(terminal_id_, 0);
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index 24217d6..07f8b818 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -129,7 +129,7 @@
   void EnableAutofillMetadataFieldTrial() {
     field_trial_list_.reset();
     field_trial_list_.reset(new base::FieldTrialList(
-        std::make_unique<metrics::SHA1EntropyProvider>("foo")));
+        std::make_unique<variations::SHA1EntropyProvider>("foo")));
     field_trial_ = base::FieldTrialList::CreateFieldTrial(
         "AutofillFieldMetadata", "Enabled");
     field_trial_->group();
diff --git a/components/exo/pointer.cc b/components/exo/pointer.cc
index 62ccbe27..dad1bd8 100644
--- a/components/exo/pointer.cc
+++ b/components/exo/pointer.cc
@@ -398,6 +398,10 @@
   DCHECK(root_surface());
   DCHECK(focus_surface_);
 
+  // Defer capture until surface commit.
+  if (host_window()->bounds().IsEmpty())
+    return;
+
   // Submit compositor frame to be captured.
   SubmitCompositorFrame();
 
diff --git a/components/guest_view/browser/guest_view_base.cc b/components/guest_view/browser/guest_view_base.cc
index 9de066d..865dec7 100644
--- a/components/guest_view/browser/guest_view_base.cc
+++ b/components/guest_view/browser/guest_view_base.cc
@@ -391,8 +391,6 @@
   return true;
 }
 
-void GuestViewBase::SetContextMenuPosition(const gfx::Point& position) {}
-
 GuestViewManager* GuestViewBase::GetGuestViewManager() {
   return GuestViewManager::FromBrowserContext(browser_context());
 }
diff --git a/components/guest_view/browser/guest_view_base.h b/components/guest_view/browser/guest_view_base.h
index da1748a..32341e9 100644
--- a/components/guest_view/browser/guest_view_base.h
+++ b/components/guest_view/browser/guest_view_base.h
@@ -213,9 +213,6 @@
 
   ~GuestViewBase() override;
 
-  // BrowserPluginGuestDelegate implementation.
-  void SetContextMenuPosition(const gfx::Point& position) override;
-
   // TODO(ekaramad): If a guest is based on BrowserPlugin and is embedded inside
   // a cross-process frame, we need to notify the destruction of the frame so
   // that the clean-up on the browser side is done appropriately. Remove this
diff --git a/components/metrics/metrics_service_accessor.cc b/components/metrics/metrics_service_accessor.cc
index fbe98e7..f00d2e85 100644
--- a/components/metrics/metrics_service_accessor.cc
+++ b/components/metrics/metrics_service_accessor.cc
@@ -9,7 +9,7 @@
 #include "components/metrics/metrics_pref_names.h"
 #include "components/metrics/metrics_service.h"
 #include "components/prefs/pref_service.h"
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 
 namespace metrics {
 namespace {
@@ -46,7 +46,8 @@
     base::StringPiece trial_name,
     base::StringPiece group_name) {
   return RegisterSyntheticFieldTrialWithNameAndGroupHash(
-      metrics_service, HashName(trial_name), HashName(group_name));
+      metrics_service, variations::HashName(trial_name),
+      variations::HashName(group_name));
 }
 
 // static
@@ -58,7 +59,7 @@
     return false;
 
   metrics_service->synthetic_trial_registry()
-      ->RegisterSyntheticMultiGroupFieldTrial(HashName(trial_name),
+      ->RegisterSyntheticMultiGroupFieldTrial(variations::HashName(trial_name),
                                               group_name_hashes);
   return true;
 }
@@ -69,7 +70,7 @@
     uint32_t trial_name_hash,
     base::StringPiece group_name) {
   return RegisterSyntheticFieldTrialWithNameAndGroupHash(
-      metrics_service, trial_name_hash, HashName(group_name));
+      metrics_service, trial_name_hash, variations::HashName(group_name));
 }
 
 // static
diff --git a/components/metrics/metrics_state_manager.cc b/components/metrics/metrics_state_manager.cc
index 023636b..f4515c9 100644
--- a/components/metrics/metrics_state_manager.cc
+++ b/components/metrics/metrics_state_manager.cc
@@ -259,7 +259,7 @@
     const std::string high_entropy_source =
         client_id_ + base::IntToString(low_entropy_source_value);
     return std::unique_ptr<const base::FieldTrial::EntropyProvider>(
-        new SHA1EntropyProvider(high_entropy_source));
+        new variations::SHA1EntropyProvider(high_entropy_source));
   }
 
   UpdateEntropySourceReturnedValue(ENTROPY_SOURCE_LOW);
@@ -272,12 +272,12 @@
 
 #if defined(OS_ANDROID) || defined(OS_IOS)
   return std::unique_ptr<const base::FieldTrial::EntropyProvider>(
-      new CachingPermutedEntropyProvider(local_state_, low_entropy_source_value,
-                                         kMaxLowEntropySize));
+      new variations::CachingPermutedEntropyProvider(
+          local_state_, low_entropy_source_value, kMaxLowEntropySize));
 #else
   return std::unique_ptr<const base::FieldTrial::EntropyProvider>(
-      new PermutedEntropyProvider(low_entropy_source_value,
-                                  kMaxLowEntropySize));
+      new variations::PermutedEntropyProvider(low_entropy_source_value,
+                                              kMaxLowEntropySize));
 #endif
 }
 
@@ -308,7 +308,7 @@
   registry->RegisterInt64Pref(prefs::kInstallDate, 0);
 
   ClonedInstallDetector::RegisterPrefs(registry);
-  CachingPermutedEntropyProvider::RegisterPrefs(registry);
+  variations::CachingPermutedEntropyProvider::RegisterPrefs(registry);
 }
 
 void MetricsStateManager::BackUpCurrentClientInfo() {
@@ -362,7 +362,7 @@
   LogLowEntropyValue(low_entropy_source_);
   local_state_->SetInteger(prefs::kMetricsLowEntropySource,
                            low_entropy_source_);
-  CachingPermutedEntropyProvider::ClearCache(local_state_);
+  variations::CachingPermutedEntropyProvider::ClearCache(local_state_);
 }
 
 void MetricsStateManager::UpdateEntropySourceReturnedValue(
diff --git a/components/metrics/persistent_system_profile_unittest.cc b/components/metrics/persistent_system_profile_unittest.cc
index 209db88..b3a7ec6 100644
--- a/components/metrics/persistent_system_profile_unittest.cc
+++ b/components/metrics/persistent_system_profile_unittest.cc
@@ -9,7 +9,7 @@
 #include "base/logging.h"
 #include "base/metrics/persistent_memory_allocator.h"
 #include "base/rand_util.h"
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace metrics {
@@ -154,8 +154,8 @@
   ASSERT_EQ(2, fetched.field_trial_size());
   EXPECT_EQ(123U, fetched.field_trial(0).name_id());
   EXPECT_EQ(456U, fetched.field_trial(0).group_id());
-  EXPECT_EQ(metrics::HashName("sna"), fetched.field_trial(1).name_id());
-  EXPECT_EQ(metrics::HashName("foo"), fetched.field_trial(1).group_id());
+  EXPECT_EQ(variations::HashName("sna"), fetched.field_trial(1).name_id());
+  EXPECT_EQ(variations::HashName("foo"), fetched.field_trial(1).group_id());
 
   persistent_profile()->AddFieldTrial("foo", "bar");
   ASSERT_TRUE(
@@ -163,10 +163,10 @@
   ASSERT_EQ(3, fetched.field_trial_size());
   EXPECT_EQ(123U, fetched.field_trial(0).name_id());
   EXPECT_EQ(456U, fetched.field_trial(0).group_id());
-  EXPECT_EQ(metrics::HashName("sna"), fetched.field_trial(1).name_id());
-  EXPECT_EQ(metrics::HashName("foo"), fetched.field_trial(1).group_id());
-  EXPECT_EQ(metrics::HashName("foo"), fetched.field_trial(2).name_id());
-  EXPECT_EQ(metrics::HashName("bar"), fetched.field_trial(2).group_id());
+  EXPECT_EQ(variations::HashName("sna"), fetched.field_trial(1).name_id());
+  EXPECT_EQ(variations::HashName("foo"), fetched.field_trial(1).group_id());
+  EXPECT_EQ(variations::HashName("foo"), fetched.field_trial(2).name_id());
+  EXPECT_EQ(variations::HashName("bar"), fetched.field_trial(2).group_id());
 }
 
 }  // namespace metrics
diff --git a/components/ntp_snippets/breaking_news/subscription_manager_impl.cc b/components/ntp_snippets/breaking_news/subscription_manager_impl.cc
index 10404fa..9770ca5 100644
--- a/components/ntp_snippets/breaking_news/subscription_manager_impl.cc
+++ b/components/ntp_snippets/breaking_news/subscription_manager_impl.cc
@@ -14,7 +14,6 @@
 #include "components/ntp_snippets/pref_names.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
-#include "components/signin/core/browser/signin_manager_base.h"
 #include "components/variations/service/variations_service.h"
 #include "net/base/url_util.h"
 #include "services/identity/public/cpp/primary_account_access_token_fetcher.h"
@@ -34,8 +33,7 @@
     scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
     PrefService* pref_service,
     variations::VariationsService* variations_service,
-    SigninManagerBase* signin_manager,
-    OAuth2TokenService* access_token_service,
+    identity::IdentityManager* identity_manager,
     const std::string& locale,
     const std::string& api_key,
     const GURL& subscribe_url,
@@ -43,17 +41,16 @@
     : url_request_context_getter_(std::move(url_request_context_getter)),
       pref_service_(pref_service),
       variations_service_(variations_service),
-      signin_manager_(signin_manager),
-      access_token_service_(access_token_service),
+      identity_manager_(identity_manager),
       locale_(locale),
       api_key_(api_key),
       subscribe_url_(subscribe_url),
       unsubscribe_url_(unsubscribe_url) {
-  signin_manager_->AddObserver(this);
+  identity_manager_->AddObserver(this);
 }
 
 SubscriptionManagerImpl::~SubscriptionManagerImpl() {
-  signin_manager_->RemoveObserver(this);
+  identity_manager_->RemoveObserver(this);
 }
 
 void SubscriptionManagerImpl::Subscribe(const std::string& subscription_token) {
@@ -61,7 +58,7 @@
   if (request_) {
     request_ = nullptr;
   }
-  if (signin_manager_->IsAuthenticated()) {
+  if (identity_manager_->HasPrimaryAccount()) {
     StartAccessTokenRequest(subscription_token);
   } else {
     SubscribeInternal(subscription_token, /*access_token=*/std::string());
@@ -104,12 +101,13 @@
   }
 
   OAuth2TokenService::ScopeSet scopes = {kContentSuggestionsApiScope};
-  access_token_fetcher_ = std::make_unique<
-      identity::PrimaryAccountAccessTokenFetcher>(
-      "ntp_snippets", signin_manager_, access_token_service_, scopes,
-      base::BindOnce(&SubscriptionManagerImpl::AccessTokenFetchFinished,
-                     base::Unretained(this), subscription_token),
-      identity::PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable);
+  access_token_fetcher_ =
+      identity_manager_->CreateAccessTokenFetcherForPrimaryAccount(
+          "ntp_snippets", scopes,
+          base::BindOnce(&SubscriptionManagerImpl::AccessTokenFetchFinished,
+                         base::Unretained(this), subscription_token),
+          identity::PrimaryAccountAccessTokenFetcher::Mode::
+              kWaitUntilAvailable);
 }
 
 void SubscriptionManagerImpl::AccessTokenFetchFinished(
@@ -193,7 +191,7 @@
   // Check if authentication state changed after subscription.
   bool is_auth_subscribe = pref_service_->GetBoolean(
       prefs::kBreakingNewsSubscriptionDataIsAuthenticated);
-  bool is_authenticated = signin_manager_->IsAuthenticated();
+  bool is_authenticated = identity_manager_->HasPrimaryAccount();
   return is_auth_subscribe != is_authenticated;
 }
 
@@ -235,14 +233,13 @@
   }
 }
 
-void SubscriptionManagerImpl::GoogleSigninSucceeded(
-    const std::string& account_id,
-    const std::string& username) {
+void SubscriptionManagerImpl::OnPrimaryAccountSet(
+    const AccountInfo& account_info) {
   SigninStatusChanged();
 }
 
-void SubscriptionManagerImpl::GoogleSignedOut(const std::string& account_id,
-                                              const std::string& username) {
+void SubscriptionManagerImpl::OnPrimaryAccountCleared(
+    const AccountInfo& account_info) {
   SigninStatusChanged();
 }
 
diff --git a/components/ntp_snippets/breaking_news/subscription_manager_impl.h b/components/ntp_snippets/breaking_news/subscription_manager_impl.h
index 28788c74..17658d4 100644
--- a/components/ntp_snippets/breaking_news/subscription_manager_impl.h
+++ b/components/ntp_snippets/breaking_news/subscription_manager_impl.h
@@ -11,11 +11,10 @@
 #include "base/memory/ref_counted.h"
 #include "components/ntp_snippets/breaking_news/subscription_json_request.h"
 #include "components/ntp_snippets/breaking_news/subscription_manager.h"
-#include "components/signin/core/browser/signin_manager_base.h"
 #include "net/url_request/url_request_context_getter.h"
+#include "services/identity/public/cpp/identity_manager.h"
 #include "url/gurl.h"
 
-class OAuth2TokenService;
 class PrefRegistrySimple;
 class PrefService;
 
@@ -35,14 +34,13 @@
 // for subscription. Bookkeeping is required to detect any change (e.g. the
 // token render invalid), and resubscribe accordingly.
 class SubscriptionManagerImpl : public SubscriptionManager,
-                                public SigninManagerBase::Observer {
+                                public identity::IdentityManager::Observer {
  public:
   SubscriptionManagerImpl(
       scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
       PrefService* pref_service,
       variations::VariationsService* variations_service,
-      SigninManagerBase* signin_manager,
-      OAuth2TokenService* access_token_service,
+      identity::IdentityManager* identity_manager,
       const std::string& locale,
       const std::string& api_key,
       const GURL& subscribe_url,
@@ -65,11 +63,9 @@
   static void ClearProfilePrefs(PrefService* pref_service);
 
  private:
-  // SigninManagerBase::Observer implementation.
-  void GoogleSigninSucceeded(const std::string& account_id,
-                             const std::string& username) override;
-  void GoogleSignedOut(const std::string& account_id,
-                       const std::string& username) override;
+  // identity:IdentityManager::Observer implementation.
+  void OnPrimaryAccountSet(const AccountInfo& account_info) override;
+  void OnPrimaryAccountCleared(const AccountInfo& account_info) override;
 
   void SigninStatusChanged();
 
@@ -104,8 +100,7 @@
   variations::VariationsService* const variations_service_;
 
   // Authentication for signed-in users.
-  SigninManagerBase* signin_manager_;
-  OAuth2TokenService* access_token_service_;
+  identity::IdentityManager* identity_manager_;
 
   const std::string locale_;
 
diff --git a/components/ntp_snippets/breaking_news/subscription_manager_impl_unittest.cc b/components/ntp_snippets/breaking_news/subscription_manager_impl_unittest.cc
index 091022eb..31f3d9b7 100644
--- a/components/ntp_snippets/breaking_news/subscription_manager_impl_unittest.cc
+++ b/components/ntp_snippets/breaking_news/subscription_manager_impl_unittest.cc
@@ -18,6 +18,8 @@
 #include "net/base/net_errors.h"
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "net/url_request/url_request_test_util.h"
+#include "services/identity/public/cpp/identity_manager.h"
+#include "services/identity/public/cpp/identity_test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -25,7 +27,10 @@
 
 namespace ntp_snippets {
 
+#if !defined(OS_CHROMEOS)
 const char kTestEmail[] = "test@email.com";
+#endif
+
 const char kAPIKey[] = "fakeAPIkey";
 const char kSubscriptionUrl[] = "http://valid-url.test/subscribe";
 const char kSubscriptionUrlSignedIn[] = "http://valid-url.test/subscribe";
@@ -42,7 +47,8 @@
       public OAuth2TokenService::DiagnosticsObserver {
  public:
   SubscriptionManagerImplTest()
-      : request_context_getter_(
+      : identity_manager_(utils_.fake_signin_manager(), utils_.token_service()),
+        request_context_getter_(
             new net::TestURLRequestContextGetter(message_loop_.task_runner())) {
   }
 
@@ -66,13 +72,14 @@
     return utils_.token_service();
   }
 
+  identity::IdentityManager* GetIdentityManager() { return &identity_manager_; }
+
   SigninManagerBase* GetSigninManager() { return utils_.fake_signin_manager(); }
 
   std::unique_ptr<SubscriptionManagerImpl> BuildSubscriptionManager() {
     return std::make_unique<SubscriptionManagerImpl>(
         GetRequestContext(), GetPrefService(),
-        /*variations_service=*/nullptr, GetSigninManager(),
-        GetOAuth2TokenService(),
+        /*variations_service=*/nullptr, GetIdentityManager(),
         /*locale=*/"", kAPIKey, GURL(kSubscriptionUrl),
         GURL(kUnsubscriptionUrl));
   }
@@ -130,19 +137,26 @@
 
 #if !defined(OS_CHROMEOS)
   void SignIn() {
-    utils_.fake_signin_manager()->SignIn(kTestEmail, "user", "pass");
+    identity::MakePrimaryAccountAvailable(utils_.fake_signin_manager(),
+                                          GetOAuth2TokenService(),
+                                          GetIdentityManager(), kTestEmail);
   }
 
-  void SignOut() { utils_.fake_signin_manager()->ForceSignOut(); }
+  void SignOut() {
+    identity::ClearPrimaryAccount(utils_.fake_signin_manager(),
+                                  GetIdentityManager());
+  }
 #endif  // !defined(OS_CHROMEOS)
 
   void IssueRefreshToken(FakeProfileOAuth2TokenService* auth_token_service) {
-    auth_token_service->GetDelegate()->UpdateCredentials(kTestEmail, "token");
+    auth_token_service->GetDelegate()->UpdateCredentials(
+        GetIdentityManager()->GetPrimaryAccountInfo().account_id, "token");
   }
 
   void IssueAccessToken(FakeProfileOAuth2TokenService* auth_token_service) {
-    auth_token_service->IssueAllTokensForAccount(kTestEmail, "access_token",
-                                                 base::Time::Max());
+    auth_token_service->IssueAllTokensForAccount(
+        GetIdentityManager()->GetPrimaryAccountInfo().account_id,
+        "access_token", base::Time::Max());
   }
 
   void set_on_access_token_request_callback(base::OnceClosure callback) {
@@ -178,6 +192,7 @@
 
   base::MessageLoop message_loop_;
   test::RemoteSuggestionsTestUtils utils_;
+  identity::IdentityManager identity_manager_;
   scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
   net::TestURLFetcherFactory url_fetcher_factory_;
   base::OnceClosure on_access_token_request_callback_;
diff --git a/components/omnibox/browser/autocomplete_result_unittest.cc b/components/omnibox/browser/autocomplete_result_unittest.cc
index 544ad83..b792ab7 100644
--- a/components/omnibox/browser/autocomplete_result_unittest.cc
+++ b/components/omnibox/browser/autocomplete_result_unittest.cc
@@ -103,7 +103,7 @@
     // a DCHECK.
     field_trial_list_.reset();
     field_trial_list_.reset(new base::FieldTrialList(
-        std::make_unique<metrics::SHA1EntropyProvider>("foo")));
+        std::make_unique<variations::SHA1EntropyProvider>("foo")));
     variations::testing::ClearAllVariationParams();
 
     // Create the list of mock providers.  5 is enough.
diff --git a/components/omnibox/browser/keyword_provider_unittest.cc b/components/omnibox/browser/keyword_provider_unittest.cc
index 620edb0..b3c04d6 100644
--- a/components/omnibox/browser/keyword_provider_unittest.cc
+++ b/components/omnibox/browser/keyword_provider_unittest.cc
@@ -66,7 +66,7 @@
     // a DCHECK.
     field_trial_list_.reset();
     field_trial_list_.reset(new base::FieldTrialList(
-        std::make_unique<metrics::SHA1EntropyProvider>("foo")));
+        std::make_unique<variations::SHA1EntropyProvider>("foo")));
     variations::testing::ClearAllVariationParams();
   }
   ~KeywordProviderTest() override {}
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc
index 90c78f21..b1eff7db 100644
--- a/components/omnibox/browser/omnibox_field_trial.cc
+++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -23,7 +23,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/search/search.h"
 #include "components/variations/active_field_trials.h"
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 #include "components/variations/variations_associated_data.h"
 #include "third_party/metrics_proto/omnibox_event.pb.h"
 
@@ -288,7 +288,7 @@
   field_trial_hashes->clear();
   if (base::FieldTrialList::TrialExists(kBundledExperimentFieldTrialName)) {
     field_trial_hashes->push_back(
-        metrics::HashName(kBundledExperimentFieldTrialName));
+        variations::HashName(kBundledExperimentFieldTrialName));
   }
 }
 
diff --git a/components/omnibox/browser/omnibox_field_trial_unittest.cc b/components/omnibox/browser/omnibox_field_trial_unittest.cc
index 39834fd..92d89e1 100644
--- a/components/omnibox/browser/omnibox_field_trial_unittest.cc
+++ b/components/omnibox/browser/omnibox_field_trial_unittest.cc
@@ -44,7 +44,7 @@
     // a DCHECK.
     field_trial_list_.reset();
     field_trial_list_.reset(new base::FieldTrialList(
-        std::make_unique<metrics::SHA1EntropyProvider>("foo")));
+        std::make_unique<variations::SHA1EntropyProvider>("foo")));
     variations::testing::ClearAllVariationParams();
   }
 
diff --git a/components/omnibox/browser/physical_web_provider_unittest.cc b/components/omnibox/browser/physical_web_provider_unittest.cc
index ea1308f2c..8b44a65 100644
--- a/components/omnibox/browser/physical_web_provider_unittest.cc
+++ b/components/omnibox/browser/physical_web_provider_unittest.cc
@@ -95,7 +95,7 @@
     // DCHECK.
     field_trial_list_.reset();
     field_trial_list_.reset(new base::FieldTrialList(
-        std::make_unique<metrics::SHA1EntropyProvider>("foo")));
+        std::make_unique<variations::SHA1EntropyProvider>("foo")));
     variations::testing::ClearAllVariationParams();
   }
 
diff --git a/components/omnibox/browser/zero_suggest_provider_unittest.cc b/components/omnibox/browser/zero_suggest_provider_unittest.cc
index 662b9bcda..9214be1 100644
--- a/components/omnibox/browser/zero_suggest_provider_unittest.cc
+++ b/components/omnibox/browser/zero_suggest_provider_unittest.cc
@@ -213,7 +213,7 @@
   // a DCHECK.
   field_trial_list_.reset();
   field_trial_list_.reset(new base::FieldTrialList(
-      std::make_unique<metrics::SHA1EntropyProvider>("foo")));
+      std::make_unique<variations::SHA1EntropyProvider>("foo")));
   variations::testing::ClearAllVariationParams();
 }
 
diff --git a/components/password_manager/core/browser/password_generation_manager_unittest.cc b/components/password_manager/core/browser/password_generation_manager_unittest.cc
index ea862c3..75741e9 100644
--- a/components/password_manager/core/browser/password_generation_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_generation_manager_unittest.cc
@@ -296,7 +296,7 @@
     scoped_refptr<base::FieldTrial> field_trial;
     if (is_autofill_field_metadata_enabled) {
       field_trial_list.reset(new base::FieldTrialList(
-          std::make_unique<metrics::SHA1EntropyProvider>("foo")));
+          std::make_unique<variations::SHA1EntropyProvider>("foo")));
       field_trial = base::FieldTrialList::CreateFieldTrial(
           "AutofillFieldMetadata", "Enabled");
       EXPECT_CALL(*GetTestDriver(), AllowToRunFormClassifier())
diff --git a/components/variations/BUILD.gn b/components/variations/BUILD.gn
index f2256e41..ce848d82 100644
--- a/components/variations/BUILD.gn
+++ b/components/variations/BUILD.gn
@@ -25,10 +25,10 @@
     "entropy_provider.h",
     "experiment_labels.cc",
     "experiment_labels.h",
+    "hashing.cc",
+    "hashing.h",
     "metrics.cc",
     "metrics.h",
-    "metrics_util.cc",
-    "metrics_util.h",
     "platform_field_trials.h",
     "pref_names.cc",
     "pref_names.h",
@@ -128,7 +128,7 @@
     "child_process_field_trial_syncer_unittest.cc",
     "entropy_provider_unittest.cc",
     "experiment_labels_unittest.cc",
-    "metrics_util_unittest.cc",
+    "hashing_unittest.cc",
     "net/variations_command_line_unittest.cc",
     "net/variations_http_headers_unittest.cc",
     "study_filtering_unittest.cc",
diff --git a/components/variations/active_field_trials.cc b/components/variations/active_field_trials.cc
index d71d6e6..f18dfe1 100644
--- a/components/variations/active_field_trials.cc
+++ b/components/variations/active_field_trials.cc
@@ -10,7 +10,7 @@
 
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 #include "components/variations/synthetic_trials_active_group_id_provider.h"
 
 namespace variations {
@@ -45,8 +45,8 @@
 ActiveGroupId MakeActiveGroupId(base::StringPiece trial_name,
                                 base::StringPiece group_name) {
   ActiveGroupId id;
-  id.name = metrics::HashName(trial_name);
-  id.group = metrics::HashName(group_name);
+  id.name = HashName(trial_name);
+  id.group = HashName(group_name);
   return id;
 }
 
diff --git a/components/variations/active_field_trials_unittest.cc b/components/variations/active_field_trials_unittest.cc
index 40909e3..b934517 100644
--- a/components/variations/active_field_trials_unittest.cc
+++ b/components/variations/active_field_trials_unittest.cc
@@ -7,7 +7,7 @@
 #include <stddef.h>
 
 #include "base/strings/string_piece.h"
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace variations {
@@ -32,11 +32,11 @@
   // Create our expected groups of IDs.
   ActiveGroupIdSet expected_groups;
   ActiveGroupId name_group_id;
-  name_group_id.name = metrics::HashName(trial_one);
-  name_group_id.group = metrics::HashName(group_one);
+  name_group_id.name = HashName(trial_one);
+  name_group_id.group = HashName(group_one);
   expected_groups.insert(name_group_id);
-  name_group_id.name = metrics::HashName(trial_two);
-  name_group_id.group = metrics::HashName(group_two);
+  name_group_id.name = HashName(trial_two);
+  name_group_id.group = HashName(group_two);
   expected_groups.insert(name_group_id);
 
   std::vector<ActiveGroupId> active_group_ids;
@@ -68,8 +68,8 @@
                                            &active_group_ids);
   EXPECT_EQ(1U, active_group_ids.size());
 
-  uint32_t expected_name = metrics::HashName("trial onesome_suffix");
-  uint32_t expected_group = metrics::HashName("group onesome_suffix");
+  uint32_t expected_name = HashName("trial onesome_suffix");
+  uint32_t expected_group = HashName("group onesome_suffix");
   EXPECT_EQ(expected_name, active_group_ids[0].name);
   EXPECT_EQ(expected_group, active_group_ids[0].group);
 }
diff --git a/components/variations/caching_permuted_entropy_provider.cc b/components/variations/caching_permuted_entropy_provider.cc
index d1788c4..48f6b11 100644
--- a/components/variations/caching_permuted_entropy_provider.cc
+++ b/components/variations/caching_permuted_entropy_provider.cc
@@ -12,7 +12,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/variations/pref_names.h"
 
-namespace metrics {
+namespace variations {
 
 CachingPermutedEntropyProvider::CachingPermutedEntropyProvider(
     PrefService* local_state,
@@ -105,4 +105,4 @@
   return false;
 }
 
-}  // namespace metrics
+}  // namespace variations
diff --git a/components/variations/caching_permuted_entropy_provider.h b/components/variations/caching_permuted_entropy_provider.h
index ce76449..141e001c 100644
--- a/components/variations/caching_permuted_entropy_provider.h
+++ b/components/variations/caching_permuted_entropy_provider.h
@@ -17,7 +17,7 @@
 class PrefService;
 class PrefRegistrySimple;
 
-namespace metrics {
+namespace variations {
 
 // CachingPermutedEntropyProvider is an entropy provider that uses the same
 // algorithm as the PermutedEntropyProvider, but caches the results in Local
@@ -63,6 +63,6 @@
   DISALLOW_COPY_AND_ASSIGN(CachingPermutedEntropyProvider);
 };
 
-}  // namespace metrics
+}  // namespace variations
 
 #endif  // COMPONENTS_VARIATIONS_CACHING_PERMUTED_ENTROPY_PROVIDER_H_
diff --git a/components/variations/caching_permuted_entropy_provider_unittest.cc b/components/variations/caching_permuted_entropy_provider_unittest.cc
index c7139d8..5d55e109 100644
--- a/components/variations/caching_permuted_entropy_provider_unittest.cc
+++ b/components/variations/caching_permuted_entropy_provider_unittest.cc
@@ -12,7 +12,7 @@
 #include "components/prefs/testing_pref_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace metrics {
+namespace variations {
 
 // Size of the low entropy source to use for the permuted entropy provider
 // in tests.
@@ -51,4 +51,4 @@
   }
 }
 
-}  // namespace metrics
+}  // namespace variations
diff --git a/components/variations/entropy_provider.cc b/components/variations/entropy_provider.cc
index 64c3cfc8..b6aece8 100644
--- a/components/variations/entropy_provider.cc
+++ b/components/variations/entropy_provider.cc
@@ -13,9 +13,9 @@
 #include "base/sha1.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/sys_byteorder.h"
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 
-namespace metrics {
+namespace variations {
 
 namespace internal {
 
@@ -133,4 +133,4 @@
   return mapping[low_entropy_source_];
 }
 
-}  // namespace metrics
+}  // namespace variations
diff --git a/components/variations/entropy_provider.h b/components/variations/entropy_provider.h
index 41276019..d39b6f8 100644
--- a/components/variations/entropy_provider.h
+++ b/components/variations/entropy_provider.h
@@ -17,7 +17,7 @@
 #include "base/metrics/field_trial.h"
 #include "third_party/mt19937ar/mt19937ar.h"
 
-namespace metrics {
+namespace variations {
 
 // Internals of entropy_provider.cc exposed for testing.
 namespace internal {
@@ -92,6 +92,6 @@
   DISALLOW_COPY_AND_ASSIGN(PermutedEntropyProvider);
 };
 
-}  // namespace metrics
+}  // namespace variations
 
 #endif  // COMPONENTS_VARIATIONS_ENTROPY_PROVIDER_H_
diff --git a/components/variations/entropy_provider_unittest.cc b/components/variations/entropy_provider_unittest.cc
index 6d032a9..79439eb 100644
--- a/components/variations/entropy_provider_unittest.cc
+++ b/components/variations/entropy_provider_unittest.cc
@@ -16,10 +16,10 @@
 #include "base/macros.h"
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace metrics {
+namespace variations {
 
 namespace {
 
@@ -396,4 +396,4 @@
   }
 }
 
-}  // namespace metrics
+}  // namespace variations
diff --git a/components/variations/metrics_util.cc b/components/variations/hashing.cc
similarity index 88%
rename from components/variations/metrics_util.cc
rename to components/variations/hashing.cc
index e6e713c..3383201f 100644
--- a/components/variations/metrics_util.cc
+++ b/components/variations/hashing.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 
 #include <string.h>
 
 #include "base/sha1.h"
 #include "base/sys_byteorder.h"
 
-namespace metrics {
+namespace variations {
 
 uint32_t HashName(base::StringPiece name) {
   // SHA-1 is designed to produce a uniformly random spread in its output space,
@@ -25,4 +25,4 @@
   return base::ByteSwapToLE32(bits);
 }
 
-}  // namespace metrics
+}  // namespace variations
diff --git a/components/variations/metrics_util.h b/components/variations/hashing.h
similarity index 61%
rename from components/variations/metrics_util.h
rename to components/variations/hashing.h
index 76254d4..149813f 100644
--- a/components/variations/metrics_util.h
+++ b/components/variations/hashing.h
@@ -2,20 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_VARIATIONS_METRICS_UTIL_H_
-#define COMPONENTS_VARIATIONS_METRICS_UTIL_H_
+#ifndef COMPONENTS_VARIATIONS_HASHING_H_
+#define COMPONENTS_VARIATIONS_HASHING_H_
 
 #include <stdint.h>
 
 #include "base/strings/string_piece.h"
 
-// TODO(rkaplow): Move to variations namespace and rename file hashing.h.
-namespace metrics {
+namespace variations {
 
 // Computes a uint32_t hash of a given string based on its SHA1 hash. Suitable
 // for uniquely identifying field trial names and group names.
 uint32_t HashName(base::StringPiece name);
 
-}  // namespace metrics
+}  // namespace variations
 
-#endif  // COMPONENTS_VARIATIONS_METRICS_UTIL_H_
+#endif  // COMPONENTS_VARIATIONS_HASHING_H_
diff --git a/components/variations/hashing_unittest.cc b/components/variations/hashing_unittest.cc
new file mode 100644
index 0000000..58592df
--- /dev/null
+++ b/components/variations/hashing_unittest.cc
@@ -0,0 +1,34 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/variations/hashing.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace variations {
+
+TEST(HashingTest, HashName) {
+  // Checks that hashing is stable on all platforms.
+  struct {
+    const char* name;
+    uint32_t hash_value;
+  } known_hashes[] = {{"a", 937752454u},
+                      {"1", 723085877u},
+                      {"Trial Name", 2713117220u},
+                      {"Group Name", 3201815843u},
+                      {"My Favorite Experiment", 3722155194u},
+                      {"My Awesome Group Name", 4109503236u},
+                      {"abcdefghijklmonpqrstuvwxyz", 787728696u},
+                      {"0123456789ABCDEF", 348858318U}};
+
+  for (size_t i = 0; i < arraysize(known_hashes); ++i) {
+    EXPECT_EQ(known_hashes[i].hash_value, HashName(known_hashes[i].name));
+  }
+}
+
+}  // namespace variations
diff --git a/components/variations/metrics_util_unittest.cc b/components/variations/metrics_util_unittest.cc
deleted file mode 100644
index 953e139..0000000
--- a/components/variations/metrics_util_unittest.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/variations/metrics_util.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace metrics {
-
-TEST(MetricsUtilTest, HashName) {
-  // Checks that hashing is stable on all platforms.
-  struct {
-    const char* name;
-    uint32_t hash_value;
-  } known_hashes[] = {
-    {"a", 937752454u},
-    {"1", 723085877u},
-    {"Trial Name", 2713117220u},
-    {"Group Name", 3201815843u},
-    {"My Favorite Experiment", 3722155194u},
-    {"My Awesome Group Name", 4109503236u},
-    {"abcdefghijklmonpqrstuvwxyz", 787728696u},
-    {"0123456789ABCDEF", 348858318U}
-  };
-
-  for (size_t i = 0; i < arraysize(known_hashes); ++i)
-    EXPECT_EQ(known_hashes[i].hash_value, HashName(known_hashes[i].name));
-}
-
-}  // namespace metrics
diff --git a/components/variations/pref_names.cc b/components/variations/pref_names.cc
index 29ae37e..6e01e80 100644
--- a/components/variations/pref_names.cc
+++ b/components/variations/pref_names.cc
@@ -93,4 +93,4 @@
 const char kVariationsSeedSignature[] = "variations_seed_signature";
 
 }  // namespace prefs
-}  // namespace metrics
+}  // namespace variations
diff --git a/components/variations/pref_names.h b/components/variations/pref_names.h
index 8cc76f30..a058a544 100644
--- a/components/variations/pref_names.h
+++ b/components/variations/pref_names.h
@@ -30,6 +30,6 @@
 extern const char kVariationsSeedSignature[];
 
 }  // namespace prefs
-}  // namespace metrics
+}  // namespace variations
 
 #endif  // COMPONENTS_VARIATIONS_PREF_NAMES_H_
diff --git a/components/variations/proto/permuted_entropy_cache.proto b/components/variations/proto/permuted_entropy_cache.proto
index fb78a06..5bba6d1 100644
--- a/components/variations/proto/permuted_entropy_cache.proto
+++ b/components/variations/proto/permuted_entropy_cache.proto
@@ -6,7 +6,7 @@
 
 option optimize_for = LITE_RUNTIME;
 
-package metrics;
+package variations;
 
 // Represents a cache of permuted entropy mappings, where each entry maps from
 // a |randomization_seed| to a |value|.
diff --git a/components/variations/synthetic_trial_registry_unittest.cc b/components/variations/synthetic_trial_registry_unittest.cc
index 632aa3f..e7ef847 100644
--- a/components/variations/synthetic_trial_registry_unittest.cc
+++ b/components/variations/synthetic_trial_registry_unittest.cc
@@ -6,7 +6,7 @@
 
 #include "base/strings/stringprintf.h"
 #include "components/variations/active_field_trials.h"
-#include "components/variations/metrics_util.h"
+#include "components/variations/hashing.h"
 #include "components/variations/synthetic_trials_active_group_id_provider.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -21,8 +21,8 @@
   bool HasSyntheticTrial(const std::vector<ActiveGroupId>& synthetic_trials,
                          const std::string& trial_name,
                          const std::string& trial_group) {
-    uint32_t trial_name_hash = metrics::HashName(trial_name);
-    uint32_t trial_group_hash = metrics::HashName(trial_group);
+    uint32_t trial_name_hash = HashName(trial_name);
+    uint32_t trial_group_hash = HashName(trial_group);
     for (const ActiveGroupId& trial : synthetic_trials) {
       if (trial.name == trial_name_hash && trial.group == trial_group_hash)
         return true;
@@ -45,12 +45,10 @@
   SyntheticTrialRegistry registry;
 
   // Add two synthetic trials and confirm that they show up in the list.
-  SyntheticTrialGroup trial1(metrics::HashName("TestTrial1"),
-                             metrics::HashName("Group1"));
+  SyntheticTrialGroup trial1(HashName("TestTrial1"), HashName("Group1"));
   registry.RegisterSyntheticFieldTrial(trial1);
 
-  SyntheticTrialGroup trial2(metrics::HashName("TestTrial2"),
-                             metrics::HashName("Group2"));
+  SyntheticTrialGroup trial2(HashName("TestTrial2"), HashName("Group2"));
   registry.RegisterSyntheticFieldTrial(trial2);
   // Ensure that time has advanced by at least a tick before proceeding.
   WaitUntilTimeChanges(base::TimeTicks::Now());
@@ -71,16 +69,14 @@
   WaitUntilTimeChanges(begin_log_time);
 
   // Change the group for the first trial after the log started.
-  SyntheticTrialGroup trial3(metrics::HashName("TestTrial1"),
-                             metrics::HashName("Group2"));
+  SyntheticTrialGroup trial3(HashName("TestTrial1"), HashName("Group2"));
   registry.RegisterSyntheticFieldTrial(trial3);
   registry.GetSyntheticFieldTrialsOlderThan(begin_log_time, &synthetic_trials);
   EXPECT_EQ(1U, synthetic_trials.size());
   EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
 
   // Add a new trial after the log started and confirm that it doesn't show up.
-  SyntheticTrialGroup trial4(metrics::HashName("TestTrial3"),
-                             metrics::HashName("Group3"));
+  SyntheticTrialGroup trial4(HashName("TestTrial3"), HashName("Group3"));
   registry.RegisterSyntheticFieldTrial(trial4);
   registry.GetSyntheticFieldTrialsOlderThan(begin_log_time, &synthetic_trials);
   EXPECT_EQ(1U, synthetic_trials.size());
@@ -102,9 +98,8 @@
   SyntheticTrialRegistry registry;
 
   // Register a synthetic trial TestTrial1 with groups A and B.
-  uint32_t trial_name_hash = metrics::HashName("TestTrial1");
-  std::vector<uint32_t> group_name_hashes = {metrics::HashName("A"),
-                                             metrics::HashName("B")};
+  uint32_t trial_name_hash = HashName("TestTrial1");
+  std::vector<uint32_t> group_name_hashes = {HashName("A"), HashName("B")};
   registry.RegisterSyntheticMultiGroupFieldTrial(trial_name_hash,
                                                  group_name_hashes);
   // Ensure that time has advanced by at least a tick before proceeding.
@@ -118,7 +113,7 @@
   EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial1", "B"));
 
   // Change the group for the trial to a single group.
-  group_name_hashes = {metrics::HashName("X")};
+  group_name_hashes = {HashName("X")};
   registry.RegisterSyntheticMultiGroupFieldTrial(trial_name_hash,
                                                  group_name_hashes);
   // Ensure that time has advanced by at least a tick before proceeding.
@@ -149,12 +144,10 @@
       SyntheticTrialsActiveGroupIdProvider::GetInstance());
 
   // Add two synthetic trials and confirm that they show up in the list.
-  SyntheticTrialGroup trial1(metrics::HashName("TestTrial1"),
-                             metrics::HashName("Group1"));
+  SyntheticTrialGroup trial1(HashName("TestTrial1"), HashName("Group1"));
   registry.RegisterSyntheticFieldTrial(trial1);
 
-  SyntheticTrialGroup trial2(metrics::HashName("TestTrial2"),
-                             metrics::HashName("Group2"));
+  SyntheticTrialGroup trial2(HashName("TestTrial2"), HashName("Group2"));
   registry.RegisterSyntheticFieldTrial(trial2);
 
   // Ensure that time has advanced by at least a tick before proceeding.
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc
index 9d022c6..80dae11 100644
--- a/components/viz/service/display/direct_renderer.cc
+++ b/components/viz/service/display/direct_renderer.cc
@@ -635,8 +635,7 @@
 
   BindFramebufferToTexture(render_pass->id);
   InitializeViewport(current_frame(), render_pass->output_rect,
-                     gfx::Rect(render_pass->output_rect.size()),
-                     GetRenderPassTextureSize(render_pass->id));
+                     gfx::Rect(render_pass->output_rect.size()), enlarged_size);
 }
 
 gfx::Rect DirectRenderer::ComputeScissorRectForRenderPass(
diff --git a/components/viz/service/display/direct_renderer.h b/components/viz/service/display/direct_renderer.h
index ef89a16f..dfb3b5a 100644
--- a/components/viz/service/display/direct_renderer.h
+++ b/components/viz/service/display/direct_renderer.h
@@ -166,8 +166,6 @@
       const RenderPassRequirements& requirements) = 0;
   virtual bool IsRenderPassResourceAllocated(
       const RenderPassId& render_pass_id) const = 0;
-  virtual gfx::Size GetRenderPassTextureSize(
-      const RenderPassId& render_pass_id) = 0;
   virtual void BindFramebufferToOutputSurface() = 0;
   virtual void BindFramebufferToTexture(const RenderPassId render_pass_id) = 0;
   virtual void SetScissorTestRect(const gfx::Rect& scissor_rect) = 0;
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
index c154eff1..86051841 100644
--- a/components/viz/service/display/gl_renderer.cc
+++ b/components/viz/service/display/gl_renderer.cc
@@ -3814,11 +3814,4 @@
   return texture_it != render_pass_textures_.end();
 }
 
-gfx::Size GLRenderer::GetRenderPassTextureSize(
-    const RenderPassId& render_pass_id) {
-  auto texture_it = render_pass_textures_.find(render_pass_id);
-  DCHECK(texture_it != render_pass_textures_.end());
-  return texture_it->second.size();
-}
-
 }  // namespace viz
diff --git a/components/viz/service/display/gl_renderer.h b/components/viz/service/display/gl_renderer.h
index b3ddb34..5630cdb 100644
--- a/components/viz/service/display/gl_renderer.h
+++ b/components/viz/service/display/gl_renderer.h
@@ -104,8 +104,6 @@
       const RenderPassRequirements& requirements) override;
   bool IsRenderPassResourceAllocated(
       const RenderPassId& render_pass_id) const override;
-  gfx::Size GetRenderPassTextureSize(
-      const RenderPassId& render_pass_id) override;
   void BindFramebufferToOutputSurface() override;
   void BindFramebufferToTexture(const RenderPassId render_pass_id) override;
   void SetScissorTestRect(const gfx::Rect& scissor_rect) override;
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc
index 8aa3917..b8e5af3 100644
--- a/components/viz/service/display/skia_renderer.cc
+++ b/components/viz/service/display/skia_renderer.cc
@@ -742,8 +742,9 @@
 
     const RenderPassRequirements& requirements = render_pass_it->second;
     const RenderPassBacking& backing = pair.second;
-    bool size_appropriate = backing.size.width() >= requirements.size.width() &&
-                            backing.size.height() >= requirements.size.height();
+    bool size_appropriate =
+        backing.render_pass_surface->width() >= requirements.size.width() &&
+        backing.render_pass_surface->height() >= requirements.size.height();
     bool mipmap_appropriate = !requirements.mipmap || backing.mipmap;
     if (!size_appropriate || !mipmap_appropriate)
       passes_to_delete.push_back(pair.first);
@@ -784,7 +785,7 @@
     bool mipmap,
     bool capability_bgra8888,
     const gfx::ColorSpace& color_space)
-    : size(size), mipmap(mipmap), color_space(color_space) {
+    : mipmap(mipmap), color_space(color_space) {
   ResourceFormat format;
   if (color_space.IsHDR()) {
     // If a platform does not support half-float renderbuffers then it should
@@ -812,14 +813,13 @@
 
 SkiaRenderer::RenderPassBacking::RenderPassBacking(
     SkiaRenderer::RenderPassBacking&& other)
-    : size(other.size), mipmap(other.mipmap), color_space(other.color_space) {
+    : mipmap(other.mipmap), color_space(other.color_space) {
   render_pass_surface = other.render_pass_surface;
   other.render_pass_surface = nullptr;
 }
 
 SkiaRenderer::RenderPassBacking& SkiaRenderer::RenderPassBacking::operator=(
     SkiaRenderer::RenderPassBacking&& other) {
-  size = other.size;
   mipmap = other.mipmap;
   color_space = other.color_space;
   render_pass_surface = other.render_pass_surface;
@@ -833,11 +833,4 @@
   return it != render_pass_backings_.end();
 }
 
-gfx::Size SkiaRenderer::GetRenderPassTextureSize(
-    const RenderPassId& render_pass_id) {
-  auto it = render_pass_backings_.find(render_pass_id);
-  DCHECK(it != render_pass_backings_.end());
-  return it->second.size;
-}
-
 }  // namespace viz
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h
index 32aa19d..888ba6d 100644
--- a/components/viz/service/display/skia_renderer.h
+++ b/components/viz/service/display/skia_renderer.h
@@ -51,8 +51,6 @@
       const RenderPassRequirements& requirements) override;
   bool IsRenderPassResourceAllocated(
       const RenderPassId& render_pass_id) const override;
-  gfx::Size GetRenderPassTextureSize(
-      const RenderPassId& render_pass_id) override;
   void BindFramebufferToOutputSurface() override;
   void BindFramebufferToTexture(const RenderPassId render_pass_id) override;
   void SetScissorTestRect(const gfx::Rect& scissor_rect) override;
@@ -102,7 +100,6 @@
   // A map from RenderPass id to the texture used to draw the RenderPass from.
   struct RenderPassBacking {
     sk_sp<SkSurface> render_pass_surface;
-    gfx::Size size;
     bool mipmap;
     gfx::ColorSpace color_space;
     RenderPassBacking(GrContext* gr_context,
diff --git a/components/viz/service/display/software_renderer.cc b/components/viz/service/display/software_renderer.cc
index fead1e77..fd17d35b 100644
--- a/components/viz/service/display/software_renderer.cc
+++ b/components/viz/service/display/software_renderer.cc
@@ -818,12 +818,4 @@
   return it != render_pass_bitmaps_.end();
 }
 
-gfx::Size SoftwareRenderer::GetRenderPassTextureSize(
-    const RenderPassId& render_pass_id) {
-  auto it = render_pass_bitmaps_.find(render_pass_id);
-  DCHECK(it != render_pass_bitmaps_.end());
-  SkBitmap& bitmap = it->second;
-  return gfx::Size(bitmap.width(), bitmap.height());
-}
-
 }  // namespace viz
diff --git a/components/viz/service/display/software_renderer.h b/components/viz/service/display/software_renderer.h
index adfc0c0..6a0e6b8 100644
--- a/components/viz/service/display/software_renderer.h
+++ b/components/viz/service/display/software_renderer.h
@@ -49,8 +49,6 @@
       const RenderPassRequirements& requirements) override;
   bool IsRenderPassResourceAllocated(
       const RenderPassId& render_pass_id) const override;
-  gfx::Size GetRenderPassTextureSize(
-      const RenderPassId& render_pass_id) override;
   void BindFramebufferToOutputSurface() override;
   void BindFramebufferToTexture(const RenderPassId render_pass_id) override;
   void SetScissorTestRect(const gfx::Rect& scissor_rect) override;
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
index 5cc401b..3cd774c 100644
--- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
+++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
@@ -30,7 +30,8 @@
     scoped_refptr<RasterContextProvider> worker_context_provider,
     scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
     gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-    SharedBitmapManager* shared_bitmap_manager)
+    SharedBitmapManager* shared_bitmap_manager,
+    bool use_viz_hit_test)
     : LayerTreeFrameSink(std::move(context_provider),
                          std::move(worker_context_provider),
                          std::move(compositor_task_runner),
@@ -40,7 +41,8 @@
       support_manager_(support_manager),
       frame_sink_manager_(frame_sink_manager),
       display_(display),
-      display_client_(display_client) {
+      display_client_(display_client),
+      use_viz_hit_test_(use_viz_hit_test) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   capabilities_.must_always_swap = true;
   // Display and DirectLayerTreeFrameSink share a GL context, so sync
@@ -54,13 +56,15 @@
     FrameSinkManagerImpl* frame_sink_manager,
     Display* display,
     mojom::DisplayClient* display_client,
-    scoped_refptr<VulkanContextProvider> vulkan_context_provider)
+    scoped_refptr<VulkanContextProvider> vulkan_context_provider,
+    bool use_viz_hit_test)
     : LayerTreeFrameSink(std::move(vulkan_context_provider)),
       frame_sink_id_(frame_sink_id),
       support_manager_(support_manager),
       frame_sink_manager_(frame_sink_manager),
       display_(display),
-      display_client_(display_client) {
+      display_client_(display_client),
+      use_viz_hit_test_(use_viz_hit_test) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   capabilities_.must_always_swap = true;
 }
@@ -80,8 +84,8 @@
   support_ = support_manager_->CreateCompositorFrameSinkSupport(
       this, frame_sink_id_, is_root,
       capabilities_.delegated_sync_points_required);
-  // TODO(riajiang): Check if viz hit-test is enabled and do setup work if it
-  // is turned on.
+  if (use_viz_hit_test_)
+    support_->SetUpHitTest();
   begin_frame_source_ = std::make_unique<ExternalBeginFrameSource>(this);
   client_->SetBeginFrameSource(begin_frame_source_.get());
 
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h
index 10f408b..7a6fce8 100644
--- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h
+++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h
@@ -45,14 +45,16 @@
       scoped_refptr<RasterContextProvider> worker_context_provider,
       scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
       gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-      SharedBitmapManager* shared_bitmap_manager);
+      SharedBitmapManager* shared_bitmap_manager,
+      bool use_viz_hit_test);
   DirectLayerTreeFrameSink(
       const FrameSinkId& frame_sink_id,
       CompositorFrameSinkSupportManager* support_manager,
       FrameSinkManagerImpl* frame_sink_manager,
       Display* display,
       mojom::DisplayClient* display_client,
-      scoped_refptr<VulkanContextProvider> vulkan_context_provider);
+      scoped_refptr<VulkanContextProvider> vulkan_context_provider,
+      bool use_viz_hit_test);
   ~DirectLayerTreeFrameSink() override;
 
   // LayerTreeFrameSink implementation.
@@ -105,6 +107,7 @@
   Display* display_;
   // |display_client_| may be nullptr on platforms that do not use it.
   mojom::DisplayClient* display_client_ = nullptr;
+  bool use_viz_hit_test_ = false;
   gfx::Size last_swap_frame_size_;
   float device_scale_factor_ = 1.f;
   bool is_lost_ = false;
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
index d332132..1ff9eb9 100644
--- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
+++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
@@ -85,7 +85,8 @@
     layer_tree_frame_sink_ = std::make_unique<TestDirectLayerTreeFrameSink>(
         kArbitraryFrameSinkId, &support_manager_, &frame_sink_manager_,
         display_.get(), nullptr /* display_client */, context_provider_,
-        nullptr, task_runner_, &gpu_memory_buffer_manager_, &bitmap_manager_);
+        nullptr, task_runner_, &gpu_memory_buffer_manager_, &bitmap_manager_,
+        false /* use_viz_hit_test */);
     layer_tree_frame_sink_->BindToClient(&layer_tree_frame_sink_client_);
     display_->Resize(display_size_);
     display_->SetVisible(true);
diff --git a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc
index 412a8e4..b49dc46 100644
--- a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc
+++ b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc
@@ -449,6 +449,7 @@
         VideoCaptureOracle::EventAsString(event), "atten_util_percent",
         base::saturated_cast<int>(utilization * 100.0f + 0.5f));
     oracle_.RecordWillNotCapture(utilization);
+    ScheduleRefreshFrame();
     return;
   }
 
diff --git a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc
index acedd423..4ece515 100644
--- a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc
+++ b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc
@@ -609,12 +609,15 @@
   ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
 
   // Notifying the capturer of new compositor updates should cause no new copy
-  // requests to be issued at this point.
+  // requests to be issued at this point. However, the refresh timer should be
+  // scheduled to account for the capture of changed content that could not take
+  // place.
   const int first_uncaptured_frame = num_frames;
   AdvanceClockToNextVsync();
   NotifyBeginFrame(1, first_uncaptured_frame);
   NotifyFrameDamaged(1, first_uncaptured_frame);
   ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
+  EXPECT_TRUE(IsRefreshRetryTimerRunning());
 
   // Complete the first copy request. When notifying the capturer of another
   // compositor update, no new copy requests should be issued because the first
@@ -626,10 +629,12 @@
   NotifyBeginFrame(1, second_uncaptured_frame);
   NotifyFrameDamaged(1, second_uncaptured_frame);
   ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
+  EXPECT_TRUE(IsRefreshRetryTimerRunning());
 
   // Notify the capturer that the first frame has been consumed. Then, with
   // another compositor update, the capturer should issue another new copy
-  // request.
+  // request. The refresh timer should no longer be running because the next
+  // capture will satisfy the need to send updated content to the consumer.
   EXPECT_TRUE(consumer.TakeFrame(0));
   consumer.SendDoneNotification(0);
   const int first_capture_resumed_frame = second_uncaptured_frame + 1;
@@ -638,14 +643,17 @@
   NotifyFrameDamaged(1, first_capture_resumed_frame);
   ++num_frames;
   ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
+  EXPECT_FALSE(IsRefreshRetryTimerRunning());
 
   // With yet another compositor update, no new copy requests should be issued
-  // because the pipeline became saturated again.
+  // because the pipeline became saturated again. Once again, the refresh timer
+  // should be started to account for the need to capture at some future point.
   const int third_uncaptured_frame = first_capture_resumed_frame + 1;
   AdvanceClockToNextVsync();
   NotifyBeginFrame(1, third_uncaptured_frame);
   NotifyFrameDamaged(1, third_uncaptured_frame);
   ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
+  EXPECT_TRUE(IsRefreshRetryTimerRunning());
 
   // Complete all pending copy requests. Another compositor update should not
   // cause any new copy requests to be issued because all frames are being
@@ -660,6 +668,7 @@
   NotifyBeginFrame(1, fourth_uncaptured_frame);
   NotifyFrameDamaged(1, fourth_uncaptured_frame);
   ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
+  EXPECT_TRUE(IsRefreshRetryTimerRunning());
 
   // Notify the capturer that all frames have been consumed. Finally, with
   // another compositor update, capture should resume.
@@ -676,6 +685,7 @@
   ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
   frame_sink_.SendCopyOutputResult(frame_sink_.num_copy_results() - 1);
   ASSERT_EQ(frame_sink_.num_copy_results(), consumer.num_frames_received());
+  EXPECT_FALSE(IsRefreshRetryTimerRunning());
 
   StopCapture();
 }
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
index 4210aff..3e01e37 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -1150,9 +1150,4 @@
 }
 #endif
 
-void BrowserPluginGuest::SetContextMenuPosition(const gfx::Point& position) {
-  if (delegate_)
-    delegate_->SetContextMenuPosition(position);
-}
-
 }  // namespace content
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h
index acb30a5..fc5bd0e 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -202,17 +202,6 @@
 
   gfx::Point GetScreenCoordinates(const gfx::Point& relative_position) const;
 
-  // This method is called by the RenderWidgetHostViewGuest to inform the
-  // BrowserPlugin of the potential location of the context menu event (to
-  // come). The need for this (hack) is that the input events when passed on to
-  // the BrowserPlugin are modified by any CSS transforms applied on the plugin.
-  // Therefore, the coordinates of the context menu event with respect to the
-  // container window are modifed with the guest renderer process beiung unaware
-  // of the change. Then eventually, when the context menu event arrives at the
-  // browser, it contains the wrong coordinates (BUG=470087).
-  // TODO(ekaramad): Find a more fundamental solution and remove this later.
-  void SetContextMenuPosition(const gfx::Point& position);
-
   // Helper to send messages to embedder. If this guest is not yet attached,
   // then IPCs will be queued until attachment.
   void SendMessageToEmbedder(std::unique_ptr<IPC::Message> msg);
diff --git a/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc b/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc
index 8c0b946..c65e260 100644
--- a/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc
+++ b/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc
@@ -12,7 +12,6 @@
 #include "content/public/browser/browsing_data_remover.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/common/simple_url_loader.h"
 #include "content/public/test/browsing_data_remover_test_util.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/simple_url_loader_test_helper.h"
@@ -23,6 +22,7 @@
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "services/network/public/cpp/simple_url_loader.h"
 #include "services/network/public/interfaces/network_service.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
@@ -84,8 +84,9 @@
     request->url = ssl_server_.GetURL("localhost", kHstsPath);
 
     SimpleURLLoaderTestHelper loader_helper;
-    std::unique_ptr<SimpleURLLoader> loader = SimpleURLLoader::Create(
-        std::move(request), TRAFFIC_ANNOTATION_FOR_TESTS);
+    std::unique_ptr<network::SimpleURLLoader> loader =
+        network::SimpleURLLoader::Create(std::move(request),
+                                         TRAFFIC_ANNOTATION_FOR_TESTS);
     loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
         url_loader_factory(), loader_helper.GetCallback());
     loader_helper.WaitForCallback();
@@ -109,8 +110,9 @@
         std::make_unique<network::ResourceRequest>();
     request->url = url;
 
-    std::unique_ptr<SimpleURLLoader> loader = SimpleURLLoader::Create(
-        std::move(request), TRAFFIC_ANNOTATION_FOR_TESTS);
+    std::unique_ptr<network::SimpleURLLoader> loader =
+        network::SimpleURLLoader::Create(std::move(request),
+                                         TRAFFIC_ANNOTATION_FOR_TESTS);
     SimpleURLLoaderTestHelper loader_helper;
     loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
         url_loader_factory(), loader_helper.GetCallback());
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index 33b9aa7..8583c56 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -21,6 +21,7 @@
 #include "cc/base/switches.h"
 #include "cc/raster/single_thread_task_graph_runner.h"
 #include "cc/raster/task_graph_runner.h"
+#include "components/viz/common/features.h"
 #include "components/viz/common/frame_sinks/begin_frame_args.h"
 #include "components/viz/common/frame_sinks/begin_frame_source.h"
 #include "components/viz/common/frame_sinks/delay_based_time_source.h"
@@ -640,14 +641,16 @@
                 GetFrameSinkManager(), data->display.get(),
                 data->display_client.get(),
                 static_cast<scoped_refptr<viz::VulkanContextProvider>>(
-                    vulkan_context_provider))
+                    vulkan_context_provider),
+                features::IsVizHitTestingEnabled())
           : std::make_unique<viz::DirectLayerTreeFrameSink>(
                 compositor->frame_sink_id(), GetHostFrameSinkManager(),
                 GetFrameSinkManager(), data->display.get(),
                 data->display_client.get(), context_provider,
                 shared_worker_context_provider_, compositor->task_runner(),
                 GetGpuMemoryBufferManager(),
-                viz::ServerSharedBitmapManager::current());
+                viz::ServerSharedBitmapManager::current(),
+                features::IsVizHitTestingEnabled());
   data->display->Resize(compositor->size());
   data->display->SetOutputIsSecure(data->output_is_secure);
   compositor->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index c188b46..1a7d824 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -131,37 +131,86 @@
   return last_entry && last_entry->GetIsOverridingUserAgent();
 }
 
-// Returns true if the PageTransition in the |entry| require this navigation to
-// be treated as a reload. For e.g. navigating to the last committed url via
-// the address bar or clicking on a link which results in a navigation to the
-// last committed or pending navigation, etc.
-bool ShouldTreatNavigationAsReload(const NavigationEntry* entry) {
-  if (!entry)
+// Returns true this navigation should be treated as a reload. For e.g.
+// navigating to the last committed url via the address bar or clicking on a
+// link which results in a navigation to the last committed or pending
+// navigation, etc.
+// |url|, |virtual_url|, |base_url_for_data_url|, |transition_type| correspond
+// to the new navigation (i.e. the pending NavigationEntry).
+// |last_committed_entry| is the last navigation that committed.
+bool ShouldTreatNavigationAsReload(
+    const GURL& url,
+    const GURL& virtual_url,
+    const GURL& base_url_for_data_url,
+    ui::PageTransition transition_type,
+    bool is_main_frame,
+    bool is_post,
+    bool is_reload,
+    bool is_navigation_to_existing_entry,
+    bool has_interstitial,
+    const NavigationEntryImpl* last_committed_entry) {
+  // Don't convert when an interstitial is showing.
+  if (has_interstitial)
+    return false;
+
+  // Only convert main frame navigations to a new entry.
+  if (!is_main_frame || is_reload || is_navigation_to_existing_entry)
+    return false;
+
+  // Only convert to reload if at least one navigation committed.
+  if (!last_committed_entry)
     return false;
 
   // Skip navigations initiated by external applications.
-  if (entry->GetTransitionType() & ui::PAGE_TRANSITION_FROM_API)
+  if (transition_type & ui::PAGE_TRANSITION_FROM_API)
     return false;
 
   // We treat (PAGE_TRANSITION_RELOAD | PAGE_TRANSITION_FROM_ADDRESS_BAR),
   // PAGE_TRANSITION_TYPED or PAGE_TRANSITION_LINK transitions as navigations
   // which should be treated as reloads.
-  if ((ui::PageTransitionCoreTypeIs(entry->GetTransitionType(),
-                                    ui::PAGE_TRANSITION_RELOAD) &&
-       (entry->GetTransitionType() & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR))) {
-    return true;
+  bool transition_type_can_be_converted = false;
+  if (ui::PageTransitionCoreTypeIs(transition_type,
+                                   ui::PAGE_TRANSITION_RELOAD) &&
+      (transition_type & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR)) {
+    transition_type_can_be_converted = true;
   }
-
-  if (ui::PageTransitionCoreTypeIs(entry->GetTransitionType(),
+  if (ui::PageTransitionCoreTypeIs(transition_type,
                                    ui::PAGE_TRANSITION_TYPED)) {
-    return true;
+    transition_type_can_be_converted = true;
+  }
+  if (ui::PageTransitionCoreTypeIs(transition_type, ui::PAGE_TRANSITION_LINK))
+    transition_type_can_be_converted = true;
+  if (!transition_type_can_be_converted)
+    return false;
+
+  // This check is required for cases like view-source:, etc. Here the URL of
+  // the navigation entry would contain the url of the page, while the virtual
+  // URL contains the full URL including the view-source prefix.
+  if (virtual_url != last_committed_entry->GetVirtualURL())
+    return false;
+
+  // Check that the URL match.
+  if (url != last_committed_entry->GetURL())
+    return false;
+
+  // This check is required for Android WebView loadDataWithBaseURL. Apps
+  // can pass in anything in the base URL and we need to ensure that these
+  // match before classifying it as a reload.
+  if (url.SchemeIs(url::kDataScheme) && base_url_for_data_url.is_valid()) {
+    if (base_url_for_data_url != last_committed_entry->GetBaseURLForDataURL())
+      return false;
   }
 
-  if (ui::PageTransitionCoreTypeIs(entry->GetTransitionType(),
-                                   ui::PAGE_TRANSITION_LINK)) {
-    return true;
-  }
-  return false;
+  // Skip entries with SSL errors.
+  if (last_committed_entry->ssl_error())
+    return false;
+
+  // Don't convert to a reload when the last navigation was a POST or the new
+  // navigation is a POST.
+  if (last_committed_entry->GetHasPostData() || is_post)
+    return false;
+
+  return true;
 }
 
 // See replaced_navigation_entry_data.h for details: this information is meant
@@ -256,13 +305,10 @@
     BrowserContext* browser_context)
     : browser_context_(browser_context),
       pending_entry_(nullptr),
-      last_pending_entry_(nullptr),
       failed_pending_entry_id_(0),
       last_committed_entry_index_(-1),
       pending_entry_index_(-1),
       transient_entry_index_(-1),
-      last_pending_entry_index_(-1),
-      last_transient_entry_index_(-1),
       delegate_(delegate),
       ssl_manager_(this),
       needs_reload_(false),
@@ -456,16 +502,8 @@
 
 void NavigationControllerImpl::LoadEntry(
     std::unique_ptr<NavigationEntryImpl> entry) {
-  // Remember the last pending entry for which we haven't received a response
-  // yet. This will be deleted in the NavigateToPendingEntry() function.
-  DCHECK_EQ(nullptr, last_pending_entry_);
-  DCHECK_EQ(-1, last_pending_entry_index_);
-  last_pending_entry_ = pending_entry_;
-  last_pending_entry_index_ = pending_entry_index_;
-  last_transient_entry_index_ = transient_entry_index_;
+  DiscardPendingEntry(false);
 
-  pending_entry_ = nullptr;
-  pending_entry_index_ = -1;
   // When navigating to a new page, we don't know for sure if we will actually
   // end up leaving the current page.  The new page load could for example
   // result in a download or a 'no content' response (e.g., a mailto: URL).
@@ -1998,54 +2036,20 @@
         ->CancelForNavigation();
   }
 
-  // The last navigation is the last pending navigation which hasn't been
-  // committed yet, or the last committed navigation.
-  NavigationEntryImpl* last_navigation =
-      last_pending_entry_ ? last_pending_entry_ : GetLastCommittedEntry();
-
-  // Convert Enter-in-omnibox to a reload. This is what Blink does in
-  // FrameLoader, but we want to handle it here so that if the navigation is
-  // redirected or handled purely on the browser side in PlzNavigate we have the
-  // same behaviour as Blink would.
-  if (reload_type == ReloadType::NONE && last_navigation &&
-      // When |pending_entry_index_| is different from -1, it means this is an
-      // history navigation. History navigation mustn't be converted to a
-      // reload.
-      pending_entry_index_ == -1 &&
-      // Please refer to the ShouldTreatNavigationAsReload() function for info
-      // on which navigations are treated as reloads. In general navigating to
-      // the last committed or pending entry via the address bar, clicking on
-      // a link, etc would be treated as reloads.
-      ShouldTreatNavigationAsReload(pending_entry_) &&
-      // Skip entries with SSL errors.
-      !last_navigation->ssl_error() &&
-      // Ignore interstitial pages
-      last_transient_entry_index_ == -1 &&
-      pending_entry_->frame_tree_node_id() == -1 &&
-      pending_entry_->GetURL() == last_navigation->GetURL() &&
-      !pending_entry_->GetHasPostData() && !last_navigation->GetHasPostData() &&
-      // This check is required for cases like view-source:, etc. Here the URL
-      // of the navigation entry would contain the url of the page, while the
-      // virtual URL contains the full URL including the view-source prefix.
-      last_navigation->GetVirtualURL() == pending_entry_->GetVirtualURL() &&
-      // This check is required for Android WebView loadDataWithBaseURL. Apps
-      // can pass in anything in the base URL and we need to ensure that these
-      // match before classifying it as a reload.
-      (pending_entry_->GetURL().SchemeIs(url::kDataScheme) &&
-               pending_entry_->GetBaseURLForDataURL().is_valid()
-           ? pending_entry_->GetBaseURLForDataURL() ==
-                 last_navigation->GetBaseURLForDataURL()
-           : true)) {
+  // Convert navigations to the current URL to a reload.
+  if (ShouldTreatNavigationAsReload(
+          pending_entry_->GetURL(), pending_entry_->GetVirtualURL(),
+          pending_entry_->GetBaseURLForDataURL(),
+          pending_entry_->GetTransitionType(),
+          pending_entry_->frame_tree_node_id() == -1 /* is_main_frame */,
+          pending_entry_->GetHasPostData() /* is _post */,
+          reload_type != ReloadType::NONE /* is_reload */,
+          pending_entry_index_ != -1 /* is_navigation_to_existing_entry */,
+          transient_entry_index_ != -1 /* has_interstitial */,
+          GetLastCommittedEntry())) {
     reload_type = ReloadType::NORMAL;
   }
 
-  if (last_pending_entry_index_ == -1 && last_pending_entry_)
-    delete last_pending_entry_;
-
-  last_transient_entry_index_ = -1;
-  last_pending_entry_ = nullptr;
-  last_pending_entry_index_ = -1;
-
   // Any renderer-side debug URLs or javascript: URLs should be ignored if the
   // renderer process is not live, unless it is the initial navigation of the
   // tab.
diff --git a/content/browser/frame_host/navigation_controller_impl.h b/content/browser/frame_host/navigation_controller_impl.h
index 58f807e..202b0fd7 100644
--- a/content/browser/frame_host/navigation_controller_impl.h
+++ b/content/browser/frame_host/navigation_controller_impl.h
@@ -367,10 +367,6 @@
   // the memory management.
   NavigationEntryImpl* pending_entry_;
 
-  // Navigations could occur in succession. This field holds the last pending
-  // entry for which we haven't received a response yet.
-  NavigationEntryImpl* last_pending_entry_;
-
   // If a new entry fails loading, details about it are temporarily held here
   // until the error page is shown (or 0 otherwise).
   //
@@ -395,13 +391,6 @@
   // after the transient entry will become invalid if you navigate forward.
   int transient_entry_index_;
 
-  // The index of the last pending entry if it is in entries, or -1 if it was
-  // created by LoadURL.
-  int last_pending_entry_index_;
-
-  // The index of the last transient entry. Defaults to -1.
-  int last_transient_entry_index_;
-
   // The delegate associated with the controller. Possibly NULL during
   // setup.
   NavigationControllerDelegate* delegate_;
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc
index 0455bd6d..ce3db368 100644
--- a/content/browser/frame_host/navigation_controller_impl_unittest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -5215,14 +5215,16 @@
 
   // Test 4.
   // A navigation to url_1 while the previous navigation to url_1 is pending
-  // should be marked as reload.
+  // should not be marked as reload. Even though the URL is the same as the
+  // previous navigation, the previous navigation did not commit. We can only
+  // reload navigations that committed. See https://crbug.com/809040.
   controller.LoadURL(url_1, Referrer(), ui::PAGE_TRANSITION_TYPED,
                      std::string());
 
   EXPECT_EQ(url_1, controller.GetVisibleEntry()->GetURL());
   main_test_rfh()->SimulateNavigationStart(url_1);
   EXPECT_EQ(url_1, controller.GetVisibleEntry()->GetURL());
-  EXPECT_EQ(ReloadType::NORMAL, last_reload_type_);
+  EXPECT_EQ(ReloadType::NONE, last_reload_type_);
 
   main_test_rfh()->SimulateNavigationCommit(initial_url);
 
diff --git a/content/browser/frame_host/render_widget_host_view_guest.cc b/content/browser/frame_host/render_widget_host_view_guest.cc
index 49077ce6..f50119c 100644
--- a/content/browser/frame_host/render_widget_host_view_guest.cc
+++ b/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -758,24 +758,7 @@
 
   ScopedInputScaleDisabler disable(host_, current_device_scale_factor());
   if (blink::WebInputEvent::IsMouseEventType(event->GetType())) {
-    // The mouse events for BrowserPlugin are modified by all
-    // the CSS transforms applied on the <object> and embedder. As a result of
-    // this, the coordinates passed on to the guest renderer are potentially
-    // incorrect to determine the position of the context menu(they are not the
-    // actual X, Y of the window). As a hack, we report the last location of a
-    // right mouse up to the BrowserPluginGuest to inform it of the next
-    // potential location for context menu (BUG=470087).
-    // TODO(ekaramad): Find a better and more fundamental solution. Could the
-    // ContextMenuParams be based on global X, Y?
-    const blink::WebMouseEvent& mouse_event =
-        static_cast<const blink::WebMouseEvent&>(*event);
-    // A MouseDown on the ButtonRight could suggest a ContextMenu.
-    if (guest_ && mouse_event.GetType() == blink::WebInputEvent::kMouseDown &&
-        mouse_event.button == blink::WebPointerProperties::Button::kRight)
-      guest_->SetContextMenuPosition(
-          gfx::Point(mouse_event.PositionInScreen().x - GetViewBounds().x(),
-                     mouse_event.PositionInScreen().y - GetViewBounds().y()));
-    host_->ForwardMouseEvent(mouse_event);
+    host_->ForwardMouseEvent(*static_cast<const blink::WebMouseEvent*>(event));
     return;
   }
 
diff --git a/content/browser/generic_sensor_browsertest.cc b/content/browser/generic_sensor_browsertest.cc
index e0aecc40..86577a5 100644
--- a/content/browser/generic_sensor_browsertest.cc
+++ b/content/browser/generic_sensor_browsertest.cc
@@ -253,7 +253,8 @@
 };
 
 // Flakily crashes on Linux ASAN/TSAN bots.  https://crbug.com/789515
-#if defined(OS_LINUX)
+// Flakily times out on Windows bots.  https://crbug.com/809537
+#if defined(OS_LINUX) || defined(OS_WIN)
 #define MAYBE_AmbientLightSensorTest DISABLED_AmbientLightSensorTest
 #else
 #define MAYBE_AmbientLightSensorTest AmbientLightSensorTest
diff --git a/content/browser/locks/lock_manager.cc b/content/browser/locks/lock_manager.cc
index 033ac3b..11bb952 100644
--- a/content/browser/locks/lock_manager.cc
+++ b/content/browser/locks/lock_manager.cc
@@ -21,19 +21,23 @@
 
 namespace {
 
+// Guaranteed to be smaller than any result of LockManager::NextLockId().
+constexpr int64_t kPreemptiveLockId = 0;
+
 // A LockHandle is passed to the client when a lock is granted. As long as the
 // handle is held, the lock is held. Dropping the handle - either explicitly
-// by script or by process termination - causes the lock to be released.
+// by script or by process termination - causes the lock to be released. The
+// connection can also be closed here when a lock is stolen.
 class LockHandleImpl final : public blink::mojom::LockHandle {
  public:
-  static blink::mojom::LockHandlePtr Create(base::WeakPtr<LockManager> context,
-                                            const url::Origin& origin,
-                                            int64_t lock_id) {
-    blink::mojom::LockHandlePtr ptr;
-    mojo::MakeStrongBinding(
+  static mojo::StrongBindingPtr<blink::mojom::LockHandle> Create(
+      base::WeakPtr<LockManager> context,
+      const url::Origin& origin,
+      int64_t lock_id,
+      blink::mojom::LockHandlePtr* ptr) {
+    return mojo::MakeStrongBinding(
         std::make_unique<LockHandleImpl>(std::move(context), origin, lock_id),
-        mojo::MakeRequest(&ptr));
-    return ptr;
+        mojo::MakeRequest(ptr));
   }
 
   LockHandleImpl(base::WeakPtr<LockManager> context,
@@ -46,6 +50,10 @@
       context_->ReleaseLock(origin_, lock_id_);
   }
 
+  // Called when the handle will be released from this end of the pipe. It
+  // nulls out the context so that the lock will not be double-released.
+  void Close() { context_.reset(); }
+
  private:
   base::WeakPtr<LockManager> context_;
   const url::Origin origin_;
@@ -59,25 +67,86 @@
 // A requested or held lock. When granted, a LockHandle will be minted
 // and passed to the held callback. Eventually the client will drop the
 // handle, which will notify the context and remove this.
-struct LockManager::Lock {
+class LockManager::Lock {
+ public:
   Lock(const std::string& name,
        LockMode mode,
        int64_t lock_id,
        const std::string& client_id,
        blink::mojom::LockRequestPtr request)
-      : name(name),
-        mode(mode),
-        lock_id(lock_id),
-        client_id(client_id),
-        request(std::move(request)) {}
+      : name_(name),
+        mode_(mode),
+        client_id_(client_id),
+        lock_id_(lock_id),
+        request_(std::move(request)) {}
 
   ~Lock() = default;
 
-  const std::string name;
-  const LockMode mode;
-  const int64_t lock_id;
-  const std::string client_id;
-  blink::mojom::LockRequestPtr request;
+  // Abort a lock request.
+  void Abort(const std::string& message) {
+    DCHECK(request_);
+    DCHECK(!handle_);
+
+    request_->Abort(message);
+    request_ = nullptr;
+  }
+
+  // Grant a lock request. This mints a LockHandle and returns it over the
+  // request pipe.
+  void Grant(base::WeakPtr<LockManager> context, const url::Origin& origin) {
+    DCHECK(context);
+    DCHECK(request_);
+    DCHECK(!handle_);
+
+    // Get a new ID when granted, to maintain map in grant order.
+    lock_id_ = context->NextLockId();
+
+    blink::mojom::LockHandlePtr ptr;
+    handle_ =
+        LockHandleImpl::Create(std::move(context), origin, lock_id_, &ptr);
+    request_->Granted(std::move(ptr));
+    request_ = nullptr;
+  }
+
+  // Break a granted lock. This terminates the connection, signaling an error
+  // on the other end of the pipe.
+  void Break() {
+    DCHECK(!request_);
+    DCHECK(handle_);
+
+    LockHandleImpl* impl = static_cast<LockHandleImpl*>(handle_->impl());
+    // Explicitly close the LockHandle first; this ensures that when the
+    // connection is subsequently closed it will not re-entrantly try to drop
+    // the lock.
+    impl->Close();
+    handle_->Close();
+  }
+
+  const std::string& name() const { return name_; }
+  LockMode mode() const { return mode_; }
+  int64_t lock_id() const { return lock_id_; }
+  const std::string& client_id() const { return client_id_; }
+
+ private:
+  const std::string name_;
+  const LockMode mode_;
+  const std::string client_id_;
+
+  // |lock_id_| is assigned when the request is arrives, and serves as the key
+  // in an ordered request map. If it is a PREEMPT request, it is given the
+  // special kPreemptiveLockId value which precedes all others, and is
+  // processed immediately. When the lock is granted, a new id is generated to
+  // be the key in the ordered map of held locks.
+  int64_t lock_id_;
+
+  // Exactly one of the following is non-null at any given time.
+
+  // |request_| is valid until the lock is granted (or failure).
+  blink::mojom::LockRequestPtr request_;
+
+  // Once granted, |handle_| holds this end of the pipe that lets us monitor
+  // for the other end going away.
+  mojo::StrongBindingPtr<blink::mojom::LockHandle> handle_;
 };
 
 LockManager::LockManager() : weak_ptr_factory_(this) {}
@@ -89,14 +158,17 @@
   OriginState() = default;
   ~OriginState() = default;
 
-  void AddRequest(int64_t lock_id,
-                  const std::string& name,
-                  LockMode mode,
-                  const std::string& client_id,
-                  blink::mojom::LockRequestPtr request) {
-    requested_.emplace(std::make_pair(
+  const Lock* AddRequest(int64_t lock_id,
+                         const std::string& name,
+                         LockMode mode,
+                         const std::string& client_id,
+                         blink::mojom::LockRequestPtr request) {
+    auto it = requested_.emplace(
         lock_id, std::make_unique<Lock>(name, mode, lock_id, client_id,
-                                        std::move(request))));
+                                        std::move(request)));
+
+    DCHECK(it.second) << "Insertion should have taken place";
+    return it.first->second.get();
   }
 
   bool EraseLock(int64_t lock_id) {
@@ -105,6 +177,10 @@
 
   bool IsEmpty() const { return requested_.empty() && held_.empty(); }
 
+#if DCHECK_IS_ON()
+  bool IsHeld(int64_t lock_id) { return held_.find(lock_id) != held_.end(); }
+#endif
+
   bool IsGrantable(const std::string& name, LockMode mode) const {
     if (mode == LockMode::EXCLUSIVE) {
       return !shared_.count(name) && !exclusive_.count(name);
@@ -113,6 +189,22 @@
     }
   }
 
+  // Break any held locks by that name.
+  void Break(const std::string& name) {
+    for (auto it = held_.begin(); it != held_.end();) {
+      if (it->second->name() == name) {
+        std::unique_ptr<Lock> lock = std::move(it->second);
+        it = held_.erase(it);
+
+        // Deleting the LockHandleImpl will signal an error on the other end
+        // of the pipe, which will notify script that the lock was broken.
+        lock->Break();
+      } else {
+        ++it;
+      }
+    }
+  }
+
   void ProcessRequests(LockManager* lock_manager, const url::Origin& origin) {
     if (requested_.empty())
       return;
@@ -121,24 +213,21 @@
     exclusive_.clear();
     for (const auto& id_lock_pair : held_) {
       const auto& lock = id_lock_pair.second;
-      MergeLockState(lock->name, lock->mode);
+      MergeLockState(lock->name(), lock->mode());
     }
 
     for (auto it = requested_.begin(); it != requested_.end();) {
       auto& lock = it->second;
 
-      bool granted = IsGrantable(lock->name, lock->mode);
+      bool granted = IsGrantable(lock->name(), lock->mode());
 
-      MergeLockState(lock->name, lock->mode);
+      MergeLockState(lock->name(), lock->mode());
 
       if (granted) {
         std::unique_ptr<Lock> grantee = std::move(lock);
         it = requested_.erase(it);
-        grantee->request->Granted(
-            LockHandleImpl::Create(lock_manager->weak_ptr_factory_.GetWeakPtr(),
-                                   origin, grantee->lock_id));
-        grantee->request = nullptr;
-        held_.insert(std::make_pair(grantee->lock_id, std::move(grantee)));
+        grantee->Grant(lock_manager->weak_ptr_factory_.GetWeakPtr(), origin);
+        held_.insert(std::make_pair(grantee->lock_id(), std::move(grantee)));
       } else {
         ++it;
       }
@@ -150,7 +239,8 @@
     out.reserve(requested_.size());
     for (const auto& id_lock_pair : requested_) {
       const auto& lock = id_lock_pair.second;
-      out.emplace_back(base::in_place, lock->name, lock->mode, lock->client_id);
+      out.emplace_back(base::in_place, lock->name(), lock->mode(),
+                       lock->client_id());
     }
     return out;
   }
@@ -160,7 +250,8 @@
     out.reserve(held_.size());
     for (const auto& id_lock_pair : held_) {
       const auto& lock = id_lock_pair.second;
-      out.emplace_back(base::in_place, lock->name, lock->mode, lock->client_id);
+      out.emplace_back(base::in_place, lock->name(), lock->mode(),
+                       lock->client_id());
     }
     return out;
   }
@@ -198,19 +289,38 @@
                               blink::mojom::LockRequestPtr request) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
+  if (wait == WaitMode::PREEMPT && mode != LockMode::EXCLUSIVE) {
+    mojo::ReportBadMessage("Invalid option combinaton");
+    return;
+  }
+
   const auto& context = bindings_.dispatch_context();
-  if (wait == WaitMode::NO_WAIT && !IsGrantable(context.origin, name, mode)) {
+  int64_t lock_id =
+      (wait == WaitMode::PREEMPT) ? kPreemptiveLockId : NextLockId();
+
+  if (wait == WaitMode::PREEMPT) {
+    Break(context.origin, name);
+  } else if (wait == WaitMode::NO_WAIT &&
+             !IsGrantable(context.origin, name, mode)) {
     request->Failed();
     return;
   }
 
-  int64_t lock_id = next_lock_id++;
   request.set_connection_error_handler(base::BindOnce(&LockManager::ReleaseLock,
                                                       base::Unretained(this),
                                                       context.origin, lock_id));
-  origins_[context.origin].AddRequest(lock_id, name, mode, context.client_id,
-                                      std::move(request));
+  const Lock* lock = origins_[context.origin].AddRequest(
+      lock_id, name, mode, context.client_id, std::move(request));
   ProcessRequests(context.origin);
+
+  DCHECK_GT(lock->lock_id(), kPreemptiveLockId)
+      << "Preemptive lock should be assigned a new id";
+
+#if DCHECK_IS_ON()
+  DCHECK(wait != WaitMode::PREEMPT ||
+         origins_[context.origin].IsHeld(lock->lock_id()))
+      << "Preemptive lock should be granted immediately";
+#endif
 }
 
 void LockManager::ReleaseLock(const url::Origin& origin, int64_t lock_id) {
@@ -252,6 +362,19 @@
   return it->second.IsGrantable(name, mode);
 }
 
+int64_t LockManager::NextLockId() {
+  int64_t lock_id = ++next_lock_id_;
+  DCHECK_GT(lock_id, kPreemptiveLockId);
+  return lock_id;
+}
+
+void LockManager::Break(const url::Origin& origin, const std::string& name) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  auto it = origins_.find(origin);
+  if (it != origins_.end())
+    it->second.Break(name);
+}
+
 void LockManager::ProcessRequests(const url::Origin& origin) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!base::ContainsKey(origins_, origin))
diff --git a/content/browser/locks/lock_manager.h b/content/browser/locks/lock_manager.h
index 9662601..177a810 100644
--- a/content/browser/locks/lock_manager.h
+++ b/content/browser/locks/lock_manager.h
@@ -48,7 +48,7 @@
 
  private:
   // Internal representation of a lock request or held lock.
-  struct Lock;
+  class Lock;
 
   // State for a particular origin.
   class OriginState;
@@ -63,13 +63,19 @@
                    const std::string& name,
                    blink::mojom::LockMode mode) const;
 
+  // Mints a monotonically increasing identifier. Used both for lock requests
+  // and granted locks as keys in ordered maps.
+  int64_t NextLockId();
+
+  void Break(const url::Origin& origin, const std::string& name);
+
   // Called when a lock is requested and optionally when a lock is released,
   // to process outstanding requests within the origin.
   void ProcessRequests(const url::Origin& origin);
 
   mojo::BindingSet<blink::mojom::LockManager, BindingState> bindings_;
 
-  int64_t next_lock_id = 1;
+  int64_t next_lock_id_ = 0;
   std::map<url::Origin, OriginState> origins_;
 
   SEQUENCE_CHECKER(sequence_checker_);
diff --git a/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc b/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc
index cd2181c..a7c7bc7 100644
--- a/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc
@@ -10,6 +10,7 @@
 #include <cmath>
 #include <tuple>
 
+#include "base/compiler_specific.h"
 #include "base/containers/circular_deque.h"
 #include "base/containers/flat_map.h"
 #include "base/run_loop.h"
@@ -331,19 +332,22 @@
   virtual bool use_fixed_aspect_ratio() const { return false; }
 
   void SetUp() override {
-#if defined(OS_CHROMEOS)
     // Enable use of the GPU, where available, to greatly speed these tests up.
+    auto* const command_line = base::CommandLine::ForCurrentProcess();
+#if defined(MEMORY_SANITIZER)
+    // Don't append any switches. This will cause the MSAN-instrumented software
+    // GL implementation to be used. http://crbug.com/806715
+    ALLOW_UNUSED_LOCAL(command_line);
+#elif defined(OS_CHROMEOS)
     // As of this writing, enabling this flag on ChromeOS bots with Mus enabled
     // causes a CHECK failure in GpuProcessTransportFactory::EstablishedGpuCh()
     // for a false "use_gpu_compositing".
-    if (!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kMus)) {
-      base::CommandLine::ForCurrentProcess()->AppendSwitch(
-          switches::kUseGpuInTests);
+    if (!command_line->HasSwitch(switches::kMus)) {
+      command_line->AppendSwitch(switches::kUseGpuInTests);
     }
 #else
-    base::CommandLine::ForCurrentProcess()->AppendSwitch(
-        switches::kUseGpuInTests);
-#endif  // defined(OS_CHROMEOS)
+    command_line->AppendSwitch(switches::kUseGpuInTests);
+#endif
 
     // Screen capture requires readback from compositor output.
     EnablePixelOutput();
@@ -468,17 +472,8 @@
 
 // Tests that the device refuses to start if the WebContents target was
 // destroyed before the device could start.
-// TODO(crbug/806715): On CrOS+MSAN, the platform OpenGL library triggers MSAN
-// use-of-uninit-value errors.
-#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER)
-#define MAYBE_ErrorsOutIfWebContentsHasGoneBeforeDeviceStart \
-  DISABLED_ErrorsOutIfWebContentsHasGoneBeforeDeviceStart
-#else
-#define MAYBE_ErrorsOutIfWebContentsHasGoneBeforeDeviceStart \
-  ErrorsOutIfWebContentsHasGoneBeforeDeviceStart
-#endif
 IN_PROC_BROWSER_TEST_F(WebContentsVideoCaptureDeviceBrowserTest,
-                       MAYBE_ErrorsOutIfWebContentsHasGoneBeforeDeviceStart) {
+                       ErrorsOutIfWebContentsHasGoneBeforeDeviceStart) {
   auto* const main_frame = shell()->web_contents()->GetMainFrame();
   const auto render_process_id = main_frame->GetProcess()->GetID();
   const auto render_frame_id = main_frame->GetRoutingID();
@@ -510,17 +505,8 @@
 
 // Tests that the device starts, captures a frame, and then gracefully
 // errors-out because the WebContents is destroyed before the device is stopped.
-// TODO(crbug/806715): On CrOS+MSAN, the platform OpenGL library triggers MSAN
-// use-of-uninit-value errors.
-#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER)
-#define MAYBE_ErrorsOutWhenWebContentsIsDestroyed \
-  DISABLED_ErrorsOutWhenWebContentsIsDestroyed
-#else
-#define MAYBE_ErrorsOutWhenWebContentsIsDestroyed \
-  ErrorsOutWhenWebContentsIsDestroyed
-#endif
 IN_PROC_BROWSER_TEST_F(WebContentsVideoCaptureDeviceBrowserTest,
-                       MAYBE_ErrorsOutWhenWebContentsIsDestroyed) {
+                       ErrorsOutWhenWebContentsIsDestroyed) {
   AllocateAndStartAndWaitForFirstFrame();
 
   // Initially, the device captures any content changes normally.
@@ -540,15 +526,8 @@
 // Tests that the device stops delivering frames while suspended. When resumed,
 // any content changes that occurred during the suspend should cause a new frame
 // to be delivered, to ensure the client is up-to-date.
-// TODO(crbug/806715): On CrOS+MSAN, the platform OpenGL library triggers MSAN
-// use-of-uninit-value errors.
-#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER)
-#define MAYBE_SuspendsAndResumes DISABLED_SuspendsAndResumes
-#else
-#define MAYBE_SuspendsAndResumes SuspendsAndResumes
-#endif
 IN_PROC_BROWSER_TEST_F(WebContentsVideoCaptureDeviceBrowserTest,
-                       MAYBE_SuspendsAndResumes) {
+                       SuspendsAndResumes) {
   AllocateAndStartAndWaitForFirstFrame();
 
   // Initially, the device captures any content changes normally.
@@ -580,16 +559,8 @@
 
 // Tests that the device delivers refresh frames when asked, while the source
 // content is not changing.
-// TODO(crbug/806715): On CrOS+MSAN, the platform OpenGL library triggers MSAN
-// use-of-uninit-value errors.
-#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER)
-#define MAYBE_DeliversRefreshFramesUponRequest \
-  DISABLED_DeliversRefreshFramesUponRequest
-#else
-#define MAYBE_DeliversRefreshFramesUponRequest DeliversRefreshFramesUponRequest
-#endif
 IN_PROC_BROWSER_TEST_F(WebContentsVideoCaptureDeviceBrowserTest,
-                       MAYBE_DeliversRefreshFramesUponRequest) {
+                       DeliversRefreshFramesUponRequest) {
   AllocateAndStartAndWaitForFirstFrame();
 
   // Set the page content to a known color.
@@ -643,15 +614,8 @@
 // whether the browser is running with software compositing or GPU-accelerated
 // compositing, and whether the WebContents is visible/hidden or
 // occluded/unoccluded.
-// TODO(crbug/806715): On CrOS+MSAN, the platform OpenGL library triggers MSAN
-// use-of-uninit-value errors.
-#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER)
-#define MAYBE_CapturesContentChanges DISABLED_CapturesContentChanges
-#else
-#define MAYBE_CapturesContentChanges CapturesContentChanges
-#endif
 IN_PROC_BROWSER_TEST_P(WebContentsVideoCaptureDeviceBrowserTestP,
-                       MAYBE_CapturesContentChanges) {
+                       CapturesContentChanges) {
   SCOPED_TRACE(testing::Message()
                << "Test parameters: "
                << (use_software_compositing() ? "Software Compositing"
diff --git a/content/browser/network_service_restart_browsertest.cc b/content/browser/network_service_restart_browsertest.cc
index e4f5a758..4bb4701b 100644
--- a/content/browser/network_service_restart_browsertest.cc
+++ b/content/browser/network_service_restart_browsertest.cc
@@ -11,7 +11,6 @@
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_switches.h"
-#include "content/public/common/simple_url_loader.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
@@ -21,6 +20,7 @@
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "services/network/public/cpp/features.h"
+#include "services/network/public/cpp/simple_url_loader.h"
 #include "services/network/public/interfaces/network_service.mojom.h"
 
 namespace content {
@@ -47,8 +47,8 @@
   // Wait for callback on UI thread to avoid nesting IO message loops.
   simple_loader_helper.SetRunLoopQuitThread(BrowserThread::UI);
 
-  std::unique_ptr<content::SimpleURLLoader> simple_loader =
-      content::SimpleURLLoader::Create(std::move(request),
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
                                        TRAFFIC_ANNOTATION_FOR_TESTS);
 
   // |URLLoaderFactoryGetter::GetNetworkFactory()| can only be accessed on IO
@@ -56,9 +56,10 @@
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
       base::BindOnce(
-          [](content::SimpleURLLoader* loader,
+          [](network::SimpleURLLoader* loader,
              URLLoaderFactoryGetter* factory_getter,
-             SimpleURLLoader::BodyAsStringCallback body_as_string_callback) {
+             network::SimpleURLLoader::BodyAsStringCallback
+                 body_as_string_callback) {
             loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
                 factory_getter->GetNetworkFactory(),
                 std::move(body_as_string_callback));
diff --git a/content/browser/notifications/notification_id_generator.cc b/content/browser/notifications/notification_id_generator.cc
index f84f0ae6..f7e2d25 100644
--- a/content/browser/notifications/notification_id_generator.cc
+++ b/content/browser/notifications/notification_id_generator.cc
@@ -14,24 +14,24 @@
 namespace content {
 namespace {
 
-const char kNotificationTagSeparator[] = "#";
-const char kPersistentNotificationPrefix[] = "p";
-const char kNonPersistentNotificationPrefix[] = "n";
+const char kNotificationTagSeparator = '#';
+const char kPersistentNotificationPrefix = 'p';
+const char kNonPersistentNotificationPrefix = 'n';
 
 }  // namespace
 
 // static
 bool NotificationIdGenerator::IsPersistentNotification(
     const base::StringPiece& notification_id) {
-  return notification_id.starts_with(
-      std::string(kPersistentNotificationPrefix));
+  return notification_id.length() > 0 &&
+         notification_id.front() == kPersistentNotificationPrefix;
 }
 
 // static
 bool NotificationIdGenerator::IsNonPersistentNotification(
     const base::StringPiece& notification_id) {
-  return notification_id.starts_with(
-      std::string(kNonPersistentNotificationPrefix));
+  return notification_id.length() > 0 &&
+         notification_id.front() == kNonPersistentNotificationPrefix;
 }
 
 // Notification Id is of the following format:
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 848147aa..5c7b20d 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -35,6 +35,7 @@
 #include "cc/resources/ui_resource_manager.h"
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_settings.h"
+#include "components/viz/common/features.h"
 #include "components/viz/common/gl_helper.h"
 #include "components/viz/common/gpu/context_provider.h"
 #include "components/viz/common/gpu/vulkan_in_process_context_provider.h"
@@ -858,13 +859,14 @@
           ? std::make_unique<viz::DirectLayerTreeFrameSink>(
                 frame_sink_id_, GetHostFrameSinkManager(), manager,
                 display_.get(), nullptr /* display_client */,
-                vulkan_context_provider)
+                vulkan_context_provider, features::IsVizHitTestingEnabled())
           : std::make_unique<viz::DirectLayerTreeFrameSink>(
                 frame_sink_id_, GetHostFrameSinkManager(), manager,
                 display_.get(), nullptr /* display_client */, context_provider,
                 nullptr /* worker_context_provider */, task_runner,
                 gpu_memory_buffer_manager,
-                viz::ServerSharedBitmapManager::current());
+                viz::ServerSharedBitmapManager::current(),
+                features::IsVizHitTestingEnabled());
 
   display_->SetVisible(true);
   display_->Resize(size_);
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index cc655f5..d05bb57 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -10533,7 +10533,14 @@
 
 // Create an out-of-process iframe that causes itself to be detached during
 // its layout/animate phase. See https://crbug.com/802932.
-IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, OOPIFDetachDuringAnimation) {
+// Disabled on Android due to flakiness, https://crbug.com/809580.
+#if defined(OS_ANDROID)
+#define MAYBE_OOPIFDetachDuringAnimation DISABLED_OOPIFDetachDuringAnimation
+#else
+#define MAYBE_OOPIFDetachDuringAnimation OOPIFDetachDuringAnimation
+#endif
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+                       MAYBE_OOPIFDetachDuringAnimation) {
   GURL main_url(embedded_test_server()->GetURL(
       "a.com", "/frame_tree/frame-detached-in-animationstart-event.html"));
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index c8f8336..2d82c0d 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -345,29 +345,6 @@
   return (blink::WebDragOperationsMask) web_drag_op;
 }
 
-int ConvertAuraEventFlagsToWebInputEventModifiers(int aura_event_flags) {
-  int web_input_event_modifiers = 0;
-  if (aura_event_flags & ui::EF_SHIFT_DOWN)
-    web_input_event_modifiers |= blink::WebInputEvent::kShiftKey;
-  if (aura_event_flags & ui::EF_CONTROL_DOWN)
-    web_input_event_modifiers |= blink::WebInputEvent::kControlKey;
-  if (aura_event_flags & ui::EF_ALT_DOWN)
-    web_input_event_modifiers |= blink::WebInputEvent::kAltKey;
-  if (aura_event_flags & ui::EF_COMMAND_DOWN)
-    web_input_event_modifiers |= blink::WebInputEvent::kMetaKey;
-  if (aura_event_flags & ui::EF_LEFT_MOUSE_BUTTON)
-    web_input_event_modifiers |= blink::WebInputEvent::kLeftButtonDown;
-  if (aura_event_flags & ui::EF_MIDDLE_MOUSE_BUTTON)
-    web_input_event_modifiers |= blink::WebInputEvent::kMiddleButtonDown;
-  if (aura_event_flags & ui::EF_RIGHT_MOUSE_BUTTON)
-    web_input_event_modifiers |= blink::WebInputEvent::kRightButtonDown;
-  if (aura_event_flags & ui::EF_BACK_MOUSE_BUTTON)
-    web_input_event_modifiers |= blink::WebInputEvent::kBackButtonDown;
-  if (aura_event_flags & ui::EF_FORWARD_MOUSE_BUTTON)
-    web_input_event_modifiers |= blink::WebInputEvent::kForwardButtonDown;
-  return web_input_event_modifiers;
-}
-
 GlobalRoutingID GetRenderViewHostID(RenderViewHost* rvh) {
   return GlobalRoutingID(rvh->GetProcess()->GetID(), rvh->GetRoutingID());
 }
@@ -1237,7 +1214,7 @@
   gfx::PointF screen_pt(display::Screen::GetScreen()->GetCursorScreenPoint());
   current_rwh_for_drag_->DragTargetDragEnter(
       *current_drop_data_, transformed_pt, screen_pt, op,
-      ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
+      ui::EventFlagsToWebEventModifiers(event.flags()));
 
   if (drag_dest_delegate_) {
     drag_dest_delegate_->OnReceiveDragData(event.data());
@@ -1285,7 +1262,7 @@
   blink::WebDragOperationsMask op = ConvertToWeb(event.source_operations());
   target_rwh->DragTargetDragOver(
       transformed_pt, screen_pt, op,
-      ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
+      ui::EventFlagsToWebEventModifiers(event.flags()));
 
   if (drag_dest_delegate_)
     drag_dest_delegate_->OnDragOver();
@@ -1334,7 +1311,7 @@
   target_rwh->DragTargetDrop(
       *current_drop_data_, transformed_pt,
       gfx::PointF(display::Screen::GetScreen()->GetCursorScreenPoint()),
-      ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
+      ui::EventFlagsToWebEventModifiers(event.flags()));
   if (drag_dest_delegate_)
     drag_dest_delegate_->OnDrop();
   current_drop_data_.reset();
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc
index bb4cd2f1..2d55dc3 100644
--- a/content/browser/webauth/authenticator_impl_unittest.cc
+++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -9,6 +9,8 @@
 #include <utility>
 #include <vector>
 
+#include "base/json/json_parser.h"
+#include "base/json/json_writer.h"
 #include "base/logging.h"
 #include "base/run_loop.h"
 #include "base/test/gtest_util.h"
@@ -373,15 +375,45 @@
             cb.GetResponseStatus());
 }
 
+// Parses its arguments as JSON and expects that all the keys in the first are
+// also in the second, and with the same value.
+void CheckJSONIsSubsetOfJSON(base::StringPiece subset_str,
+                             base::StringPiece test_str) {
+  std::unique_ptr<base::Value> subset(base::JSONReader::Read(subset_str));
+  ASSERT_TRUE(subset);
+  ASSERT_TRUE(subset->is_dict());
+  std::unique_ptr<base::Value> test(base::JSONReader::Read(test_str));
+  ASSERT_TRUE(test);
+  ASSERT_TRUE(test->is_dict());
+
+  for (const auto& item : subset->DictItems()) {
+    base::Value* test_value = test->FindKey(item.first);
+    if (test_value == nullptr) {
+      ADD_FAILURE() << item.first << " does not exist in the test dictionary";
+      continue;
+    }
+
+    if (!item.second.Equals(test_value)) {
+      std::string want, got;
+      ASSERT_TRUE(base::JSONWriter::Write(item.second, &want));
+      ASSERT_TRUE(base::JSONWriter::Write(*test_value, &got));
+      ADD_FAILURE() << "Value of " << item.first << " is unequal: want " << want
+                    << " got " << got;
+    }
+  }
+}
+
 // Test that client data serializes to JSON properly.
 TEST_F(AuthenticatorImplTest, TestSerializedRegisterClientData) {
-  EXPECT_EQ(kTestRegisterClientDataJsonString,
-            GetTestClientData(client_data::kCreateType).SerializeToJson());
+  CheckJSONIsSubsetOfJSON(
+      kTestRegisterClientDataJsonString,
+      GetTestClientData(client_data::kCreateType).SerializeToJson());
 }
 
 TEST_F(AuthenticatorImplTest, TestSerializedSignClientData) {
-  EXPECT_EQ(kTestSignClientDataJsonString,
-            GetTestClientData(client_data::kGetType).SerializeToJson());
+  CheckJSONIsSubsetOfJSON(
+      kTestSignClientDataJsonString,
+      GetTestClientData(client_data::kGetType).SerializeToJson());
 }
 
 TEST_F(AuthenticatorImplTest, TestMakeCredentialTimeout) {
diff --git a/content/browser/webauth/client_data_json.md b/content/browser/webauth/client_data_json.md
new file mode 100644
index 0000000..0e7cab1
--- /dev/null
+++ b/content/browser/webauth/client_data_json.md
@@ -0,0 +1,9 @@
+# Advice to sites regarding `clientDataJSON`
+
+When performing a registration or authentication with webauthn, it's critical that sites confirm that the returned [`clientDataJSON`](https://w3c.github.io/webauthn/#dom-authenticatorresponse-clientdatajson) contains the [challenge](https://w3c.github.io/webauthn/#cryptographic-challenges) originally provided. Otherwise old messages can be replayed. Likewise, sites must check the `origin` member to confirm that the action is not being proxied by another site.
+
+In order to implement this, sites should parse the JSON as a [`CollectedClientData`](https://w3c.github.io/webauthn/#dictdef-collectedclientdata) structure and confirm that the `type`, `challenge`, and `origin` members (at least) are as expected.
+
+Sites should _not_ implement this by comparing the unparsed value of `clientDataJSON` against a template with the `challenge` value filled in. This would fail when new members are added to `CollectedClientData` in the future as the template would no longer be correct.
+
+In order to guide sites away from doing this, Chromium will sometimes, randomly insert an extra member into `clientDataJSON` which references this documentation.
diff --git a/content/browser/webauth/collected_client_data.cc b/content/browser/webauth/collected_client_data.cc
index 418d2e6..178ea01 100644
--- a/content/browser/webauth/collected_client_data.cc
+++ b/content/browser/webauth/collected_client_data.cc
@@ -8,6 +8,7 @@
 
 #include "base/base64url.h"
 #include "base/json/json_writer.h"
+#include "base/rand_util.h"
 #include "base/strings/string_piece.h"
 #include "base/values.h"
 
@@ -67,6 +68,16 @@
   client_data.SetKey(kTypeKey, base::Value(type_));
   client_data.SetKey(kChallengeKey, base::Value(base64_encoded_challenge_));
 
+  if (base::RandDouble() < 0.2) {
+    // An extra key is sometimes added to ensure that RPs do not make
+    // unreasonably specific assumptions about the clientData JSON. This is
+    // done in the fashion of
+    // https://tools.ietf.org/html/draft-davidben-tls-grease-01
+    client_data.SetKey("new_keys_may_be_added_here",
+                       base::Value("do not compare clientDataJSON against a "
+                                   "template. See https://goo.gl/yabPex"));
+  }
+
   // The serialization of callerOrigin.
   client_data.SetKey(kOriginKey, base::Value(origin_));
 
diff --git a/content/public/browser/browser_plugin_guest_delegate.h b/content/public/browser/browser_plugin_guest_delegate.h
index 9a3c237..d05dd54 100644
--- a/content/public/browser/browser_plugin_guest_delegate.h
+++ b/content/public/browser/browser_plugin_guest_delegate.h
@@ -67,12 +67,6 @@
   // content module.
   virtual void SetGuestHost(GuestHost* guest_host) {}
 
-  // Sets the position of the context menu for the guest contents. The value
-  // reported from the guest renderer should be ignored. The reported value
-  // from the guest renderer is incorrect in situations where BrowserPlugin is
-  // subject to CSS transforms.
-  virtual void SetContextMenuPosition(const gfx::Point& position) {}
-
   // TODO(ekaramad): A short workaround to force some types of guests to use
   // a BrowserPlugin even when we are using cross process frames for guests. It
   // should be removed after resolving https://crbug.com/642826).
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn
index 6b00fb009..df0e56e 100644
--- a/content/public/common/BUILD.gn
+++ b/content/public/common/BUILD.gn
@@ -219,9 +219,6 @@
     "shared_url_loader_factory.h",
     "simple_connection_filter.cc",
     "simple_connection_filter.h",
-    "simple_url_loader.cc",
-    "simple_url_loader.h",
-    "simple_url_loader_stream_consumer.h",
     "socket_permission_request.h",
     "speech_recognition_error.h",
     "speech_recognition_grammar.h",
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h
index 7d82f722..b4fb17f 100644
--- a/content/public/common/common_param_traits_macros.h
+++ b/content/public/common/common_param_traits_macros.h
@@ -224,7 +224,7 @@
   IPC_STRUCT_TRAITS_MEMBER(video_rotate_to_fullscreen_enabled)
   IPC_STRUCT_TRAITS_MEMBER(video_fullscreen_detection_enabled)
   IPC_STRUCT_TRAITS_MEMBER(embedded_media_experience_enabled)
-  IPC_STRUCT_TRAITS_MEMBER(immersive_mode_enabled)
+  IPC_STRUCT_TRAITS_MEMBER(page_popups_suppressed)
   IPC_STRUCT_TRAITS_MEMBER(css_hex_alpha_color_enabled)
   IPC_STRUCT_TRAITS_MEMBER(enable_media_download_in_product_help)
   IPC_STRUCT_TRAITS_MEMBER(scroll_top_left_interop_enabled)
diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc
index fb8481a..06069a57 100644
--- a/content/public/common/web_preferences.cc
+++ b/content/public/common/web_preferences.cc
@@ -186,7 +186,7 @@
       animation_policy(IMAGE_ANIMATION_POLICY_ALLOWED),
       user_gesture_required_for_presentation(true),
       text_track_margin_percentage(0.0f),
-      immersive_mode_enabled(false),
+      page_popups_suppressed(false),
 #if defined(OS_ANDROID)
       text_autosizing_enabled(true),
       font_scale_factor(1.0f),
diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h
index e4b9ee9..49be57cd 100644
--- a/content/public/common/web_preferences.h
+++ b/content/public/common/web_preferences.h
@@ -222,7 +222,7 @@
   // Cues will not be placed in this margin area.
   float text_track_margin_percentage;
 
-  bool immersive_mode_enabled;
+  bool page_popups_suppressed;
 
 #if defined(OS_ANDROID)
   bool text_autosizing_enabled;
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index af4e6698..5615de4 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -72,7 +72,6 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/service_names.mojom.h"
-#include "content/public/common/simple_url_loader.h"
 #include "content/public/test/simple_url_loader_test_helper.h"
 #include "content/public/test/test_fileapi_operation_waiter.h"
 #include "content/public/test/test_navigation_observer.h"
@@ -93,6 +92,7 @@
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "services/network/public/cpp/features.h"
+#include "services/network/public/cpp/simple_url_loader.h"
 #include "services/network/public/interfaces/cookie_manager.mojom.h"
 #include "services/network/public/interfaces/network_service.mojom.h"
 #include "services/network/public/interfaces/network_service_test.mojom.h"
@@ -2435,8 +2435,8 @@
   request->render_frame_id = render_frame_id;
 
   content::SimpleURLLoaderTestHelper simple_loader_helper;
-  std::unique_ptr<content::SimpleURLLoader> simple_loader =
-      content::SimpleURLLoader::Create(std::move(request),
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
                                        TRAFFIC_ANNOTATION_FOR_TESTS);
 
   simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
diff --git a/content/public/test/simple_url_loader_test_helper.cc b/content/public/test/simple_url_loader_test_helper.cc
index 5745901a..5dac16c 100644
--- a/content/public/test/simple_url_loader_test_helper.cc
+++ b/content/public/test/simple_url_loader_test_helper.cc
@@ -15,7 +15,8 @@
 
 SimpleURLLoaderTestHelper::~SimpleURLLoaderTestHelper() {}
 
-SimpleURLLoader::BodyAsStringCallback SimpleURLLoaderTestHelper::GetCallback() {
+network::SimpleURLLoader::BodyAsStringCallback
+SimpleURLLoaderTestHelper::GetCallback() {
   DCHECK(!callback_created_);
   callback_created_ = true;
 
diff --git a/content/public/test/simple_url_loader_test_helper.h b/content/public/test/simple_url_loader_test_helper.h
index 97f71a1..21fa0232 100644
--- a/content/public/test/simple_url_loader_test_helper.h
+++ b/content/public/test/simple_url_loader_test_helper.h
@@ -14,7 +14,7 @@
 #include "base/optional.h"
 #include "base/run_loop.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/common/simple_url_loader.h"
+#include "services/network/public/cpp/simple_url_loader.h"
 
 namespace content {
 
@@ -27,7 +27,7 @@
 
   // Returns a BodyAsStringCallback for use with a SimpleURLLoader. May be
   // called only once.
-  SimpleURLLoader::BodyAsStringCallback GetCallback();
+  network::SimpleURLLoader::BodyAsStringCallback GetCallback();
 
   // Waits until the callback returned by GetCallback() is invoked.
   void WaitForCallback();
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index c7238f80..8938cf5 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -912,7 +912,7 @@
       prefs.video_fullscreen_detection_enabled);
   settings->SetEmbeddedMediaExperienceEnabled(
       prefs.embedded_media_experience_enabled);
-  settings->SetImmersiveModeEnabled(prefs.immersive_mode_enabled);
+  settings->SetPagePopupsSuppressed(prefs.page_popups_suppressed);
   settings->SetMediaDownloadInProductHelpEnabled(
       prefs.enable_media_download_in_product_help);
   settings->SetDoNotUpdateSelectionOnMutatingSelectionRange(
diff --git a/content/renderer/service_worker/controller_service_worker_connector.cc b/content/renderer/service_worker/controller_service_worker_connector.cc
index 4f4645d4..c8a8881 100644
--- a/content/renderer/service_worker/controller_service_worker_connector.cc
+++ b/content/renderer/service_worker/controller_service_worker_connector.cc
@@ -74,7 +74,8 @@
 
 void ControllerServiceWorkerConnector::ResetControllerConnection(
     mojom::ControllerServiceWorkerPtr controller_ptr) {
-  DCHECK_NE(State::kNoContainerHost, state_);
+  if (state_ == State::kNoContainerHost)
+    return;
   controller_service_worker_ = std::move(controller_ptr);
   if (controller_service_worker_) {
     state_ = State::kConnected;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 42279f6..0d010eb 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1531,7 +1531,6 @@
     # TODO(jam): move these network/ tests to services/network.
     "../public/common/drop_data_unittest.cc",
     "../public/common/network_connection_tracker_unittest.cc",
-    "../public/common/simple_url_loader_unittest.cc",
     "../public/common/url_utils_unittest.cc",
     "../public/test/referrer_unittest.cc",
     "../public/test/test_browser_thread_bundle_unittest.cc",
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
index 29f0f6d6..c575988 100644
--- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -89,6 +89,8 @@
 
     self.Fail('conformance2/textures/misc/copy-texture-image-same-texture.html',
         ['mac', 'linux'], bug=809233)
+    self.Fail('conformance2/textures/misc/copy-texture-image-same-texture.html',
+        ['win', 'nvidia', 'opengl'], bug=809594)
     self.Fail('conformance2/transform_feedback/simultaneous_binding.html',
         bug=696345)
     self.Fail('conformance2/uniforms/' +
@@ -1196,6 +1198,8 @@
         ['linux', 'amd'], bug=658844)
     self.Fail('conformance2/uniforms/uniform-blocks-with-arrays.html',
         ['linux', 'amd'], bug=2103) # angle bug ID
+    self.Fail('conformance2/uniforms/simple-buffer-change.html',
+        ['linux', 'amd', 'no_angle'], bug=809595)
 
     # Linux AMD R7 240
     self.Fail('conformance2/textures/canvas/' +
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_revision.txt b/content/test/gpu/gpu_tests/webgl_conformance_revision.txt
index c2c4cf58..1155e5d 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_revision.txt
+++ b/content/test/gpu/gpu_tests/webgl_conformance_revision.txt
@@ -1,3 +1,3 @@
 # AUTOGENERATED FILE - DO NOT EDIT
 # SEE roll_webgl_conformance.py
-Current webgl revision 98a3d3b4355644bb1187a858fdd2aff6b2bc84ec
+Current webgl revision a182a9ad3078aca566d8355eabf2d9f56f70ee82
diff --git a/crypto/signature_verifier.cc b/crypto/signature_verifier.cc
index e715ef7..2e242837 100644
--- a/crypto/signature_verifier.cc
+++ b/crypto/signature_verifier.cc
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/logging.h"
-#include "base/numerics/safe_conversions.h"
 #include "crypto/openssl_util.h"
 #include "third_party/boringssl/src/include/openssl/bytestring.h"
 #include "third_party/boringssl/src/include/openssl/digest.h"
@@ -19,20 +18,6 @@
 
 namespace crypto {
 
-namespace {
-
-const EVP_MD* ToOpenSSLDigest(SignatureVerifier::HashAlgorithm hash_alg) {
-  switch (hash_alg) {
-    case SignatureVerifier::SHA1:
-      return EVP_sha1();
-    case SignatureVerifier::SHA256:
-      return EVP_sha256();
-  }
-  return nullptr;
-}
-
-}  // namespace
-
 struct SignatureVerifier::VerifyContext {
   bssl::ScopedEVP_MD_CTX ctx;
 };
@@ -46,6 +31,8 @@
                                    size_t signature_len,
                                    const uint8_t* public_key_info,
                                    size_t public_key_info_len) {
+  OpenSSLErrStackTracer err_tracer(FROM_HERE);
+
   int pkey_type = EVP_PKEY_NONE;
   const EVP_MD* digest = nullptr;
   switch (signature_algorithm) {
@@ -54,6 +41,7 @@
       digest = EVP_sha1();
       break;
     case RSA_PKCS1_SHA256:
+    case RSA_PSS_SHA256:
       pkey_type = EVP_PKEY_RSA;
       digest = EVP_sha256();
       break;
@@ -65,41 +53,36 @@
   DCHECK_NE(EVP_PKEY_NONE, pkey_type);
   DCHECK(digest);
 
-  return CommonInit(pkey_type, digest, signature, signature_len,
-                    public_key_info, public_key_info_len, nullptr);
-}
+  if (verify_context_)
+    return false;
 
-bool SignatureVerifier::VerifyInitRSAPSS(HashAlgorithm hash_alg,
-                                         HashAlgorithm mask_hash_alg,
-                                         size_t salt_len,
-                                         const uint8_t* signature,
-                                         size_t signature_len,
-                                         const uint8_t* public_key_info,
-                                         size_t public_key_info_len) {
-  OpenSSLErrStackTracer err_tracer(FROM_HERE);
-  const EVP_MD* const digest = ToOpenSSLDigest(hash_alg);
-  DCHECK(digest);
-  if (!digest) {
+  verify_context_.reset(new VerifyContext);
+  signature_.assign(signature, signature + signature_len);
+
+  CBS cbs;
+  CBS_init(&cbs, public_key_info, public_key_info_len);
+  bssl::UniquePtr<EVP_PKEY> public_key(EVP_parse_public_key(&cbs));
+  if (!public_key || CBS_len(&cbs) != 0 ||
+      EVP_PKEY_id(public_key.get()) != pkey_type) {
     return false;
   }
 
   EVP_PKEY_CTX* pkey_ctx;
-  if (!CommonInit(EVP_PKEY_RSA, digest, signature, signature_len,
-                  public_key_info, public_key_info_len, &pkey_ctx)) {
+  if (!EVP_DigestVerifyInit(verify_context_->ctx.get(), &pkey_ctx, digest,
+                            nullptr, public_key.get())) {
     return false;
   }
 
-  int rv = EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING);
-  if (rv != 1)
-    return false;
-  const EVP_MD* const mgf_digest = ToOpenSSLDigest(mask_hash_alg);
-  DCHECK(mgf_digest);
-  if (!mgf_digest) {
-    return false;
+  if (signature_algorithm == RSA_PSS_SHA256) {
+    if (!EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) ||
+        !EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, digest) ||
+        !EVP_PKEY_CTX_set_rsa_pss_saltlen(
+            pkey_ctx, -1 /* match digest and salt length */)) {
+      return false;
+    }
   }
-  return EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf_digest) &&
-         EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx,
-                                          base::checked_cast<int>(salt_len));
+
+  return true;
 }
 
 void SignatureVerifier::VerifyUpdate(const uint8_t* data_part,
@@ -121,33 +104,6 @@
   return rv == 1;
 }
 
-bool SignatureVerifier::CommonInit(int pkey_type,
-                                   const EVP_MD* digest,
-                                   const uint8_t* signature,
-                                   size_t signature_len,
-                                   const uint8_t* public_key_info,
-                                   size_t public_key_info_len,
-                                   EVP_PKEY_CTX** pkey_ctx) {
-  if (verify_context_)
-    return false;
-
-  verify_context_.reset(new VerifyContext);
-
-  signature_.assign(signature, signature + signature_len);
-
-  CBS cbs;
-  CBS_init(&cbs, public_key_info, public_key_info_len);
-  bssl::UniquePtr<EVP_PKEY> public_key(EVP_parse_public_key(&cbs));
-  if (!public_key || CBS_len(&cbs) != 0 ||
-      EVP_PKEY_id(public_key.get()) != pkey_type) {
-    return false;
-  }
-
-  int rv = EVP_DigestVerifyInit(verify_context_->ctx.get(), pkey_ctx,
-                                digest, nullptr, public_key.get());
-  return rv == 1;
-}
-
 void SignatureVerifier::Reset() {
   verify_context_.reset();
   signature_.clear();
diff --git a/crypto/signature_verifier.h b/crypto/signature_verifier.h
index e9d5fe7..3b1a830 100644
--- a/crypto/signature_verifier.h
+++ b/crypto/signature_verifier.h
@@ -13,26 +13,20 @@
 #include "build/build_config.h"
 #include "crypto/crypto_export.h"
 
-typedef struct env_md_st EVP_MD;
-typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
-
 namespace crypto {
 
 // The SignatureVerifier class verifies a signature using a bare public key
 // (as opposed to a certificate).
 class CRYPTO_EXPORT SignatureVerifier {
  public:
-  // The set of supported hash functions. Extend as required.
-  enum HashAlgorithm {
-    SHA1,
-    SHA256,
-  };
-
   // The set of supported signature algorithms. Extend as required.
   enum SignatureAlgorithm {
     RSA_PKCS1_SHA1,
     RSA_PKCS1_SHA256,
     ECDSA_SHA256,
+    // This is RSA-PSS with SHA-256 as both signing hash and MGF-1 hash, and the
+    // salt length matching the hash length.
+    RSA_PSS_SHA256,
   };
 
   SignatureVerifier();
@@ -42,7 +36,6 @@
 
   // Initiates a signature verification operation.  This should be followed
   // by one or more VerifyUpdate calls and a VerifyFinal call.
-  // NOTE: for RSA-PSS signatures, use VerifyInitRSAPSS instead.
   //
   // The signature is encoded according to the signature algorithm.
   //
@@ -58,30 +51,6 @@
                   const uint8_t* public_key_info,
                   size_t public_key_info_len);
 
-  // Initiates a RSA-PSS signature verification operation.  This should be
-  // followed by one or more VerifyUpdate calls and a VerifyFinal call.
-  //
-  // The RSA-PSS signature algorithm parameters are specified with the
-  // |hash_alg|, |mask_hash_alg|, and |salt_len| arguments.
-  //
-  // An RSA-PSS signature is a nonnegative integer encoded as a byte string
-  // (of the same length as the RSA modulus) in big-endian byte order. It
-  // must not be further encoded in an ASN.1 BIT STRING.
-  //
-  // The public key is specified as a DER encoded ASN.1 SubjectPublicKeyInfo
-  // structure, which contains not only the public key but also its type
-  // (algorithm):
-  //   SubjectPublicKeyInfo  ::=  SEQUENCE  {
-  //       algorithm            AlgorithmIdentifier,
-  //       subjectPublicKey     BIT STRING  }
-  bool VerifyInitRSAPSS(HashAlgorithm hash_alg,
-                        HashAlgorithm mask_hash_alg,
-                        size_t salt_len,
-                        const uint8_t* signature,
-                        size_t signature_len,
-                        const uint8_t* public_key_info,
-                        size_t public_key_info_len);
-
   // Feeds a piece of the data to the signature verifier.
   void VerifyUpdate(const uint8_t* data_part, size_t data_part_len);
 
@@ -91,14 +60,6 @@
   bool VerifyFinal();
 
  private:
-  bool CommonInit(int pkey_type,
-                  const EVP_MD* digest,
-                  const uint8_t* signature,
-                  size_t signature_len,
-                  const uint8_t* public_key_info,
-                  size_t public_key_info_len,
-                  EVP_PKEY_CTX** pkey_ctx);
-
   void Reset();
 
   std::vector<uint8_t> signature_;
diff --git a/crypto/signature_verifier_unittest.cc b/crypto/signature_verifier_unittest.cc
index 2cda459..090af34 100644
--- a/crypto/signature_verifier_unittest.cc
+++ b/crypto/signature_verifier_unittest.cc
@@ -259,887 +259,179 @@
   EXPECT_FALSE(ok);
 }
 
-//////////////////////////////////////////////////////////////////////
+// The following RSA-PSS tests were generated via the following OpenSSL
+// commands:
 //
-// RSA-PSS signature verification known answer test
+// clang-format off
+// openssl genrsa -f4 -out key.pem 2048
+// openssl rsa -in key.pem -pubout -outform der | xxd -i > spki.txt
+// openssl rand -out message 50
+// xxd -i message > message.txt
+// openssl dgst -sign key.pem -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 < message | xxd -i > sig-good.txt
+// openssl dgst -sign key.pem -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:33 < message | xxd -i > sig-bad-saltlen.txt
+// clang-format on
+
+namespace {
+
+// This is the public key corresponding to the following private key.
 //
-//////////////////////////////////////////////////////////////////////
-
-// The following RSA-PSS signature test vectors come from the pss-vect.txt
-// file downloaded from
-// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip.
-//
-// For each key, 6 random messages of length between 1 and 256 octets have
-// been RSASSA-PSS signed.
-//
-// Hash function: SHA-1
-// Mask generation function: MGF1 with SHA-1
-// Salt length: 20 octets
-
-// Example 1: A 1024-bit RSA Key Pair"
-
-// RSA modulus n:
-static const char rsa_modulus_n_1[] =
-  "a5 6e 4a 0e 70 10 17 58 9a 51 87 dc 7e a8 41 d1 "
-  "56 f2 ec 0e 36 ad 52 a4 4d fe b1 e6 1f 7a d9 91 "
-  "d8 c5 10 56 ff ed b1 62 b4 c0 f2 83 a1 2a 88 a3 "
-  "94 df f5 26 ab 72 91 cb b3 07 ce ab fc e0 b1 df "
-  "d5 cd 95 08 09 6d 5b 2b 8b 6d f5 d6 71 ef 63 77 "
-  "c0 92 1c b2 3c 27 0a 70 e2 59 8e 6f f8 9d 19 f1 "
-  "05 ac c2 d3 f0 cb 35 f2 92 80 e1 38 6b 6f 64 c4 "
-  "ef 22 e1 e1 f2 0d 0c e8 cf fb 22 49 bd 9a 21 37 ";
-// RSA public exponent e: "
-static const char rsa_public_exponent_e_1[] =
-  "01 00 01 ";
-
-// RSASSA-PSS Signature Example 1.1
-// Message to be signed:
-static const char message_1_1[] =
-  "cd c8 7d a2 23 d7 86 df 3b 45 e0 bb bc 72 13 26 "
-  "d1 ee 2a f8 06 cc 31 54 75 cc 6f 0d 9c 66 e1 b6 "
-  "23 71 d4 5c e2 39 2e 1a c9 28 44 c3 10 10 2f 15 "
-  "6a 0d 8d 52 c1 f4 c4 0b a3 aa 65 09 57 86 cb 76 "
-  "97 57 a6 56 3b a9 58 fe d0 bc c9 84 e8 b5 17 a3 "
-  "d5 f5 15 b2 3b 8a 41 e7 4a a8 67 69 3f 90 df b0 "
-  "61 a6 e8 6d fa ae e6 44 72 c0 0e 5f 20 94 57 29 "
-  "cb eb e7 7f 06 ce 78 e0 8f 40 98 fb a4 1f 9d 61 "
-  "93 c0 31 7e 8b 60 d4 b6 08 4a cb 42 d2 9e 38 08 "
-  "a3 bc 37 2d 85 e3 31 17 0f cb f7 cc 72 d0 b7 1c "
-  "29 66 48 b3 a4 d1 0f 41 62 95 d0 80 7a a6 25 ca "
-  "b2 74 4f d9 ea 8f d2 23 c4 25 37 02 98 28 bd 16 "
-  "be 02 54 6f 13 0f d2 e3 3b 93 6d 26 76 e0 8a ed "
-  "1b 73 31 8b 75 0a 01 67 d0 ";
-// Salt:
-static const char salt_1_1[] =
-  "de e9 59 c7 e0 64 11 36 14 20 ff 80 18 5e d5 7f "
-  "3e 67 76 af ";
-// Signature:
-static const char signature_1_1[] =
-  "90 74 30 8f b5 98 e9 70 1b 22 94 38 8e 52 f9 71 "
-  "fa ac 2b 60 a5 14 5a f1 85 df 52 87 b5 ed 28 87 "
-  "e5 7c e7 fd 44 dc 86 34 e4 07 c8 e0 e4 36 0b c2 "
-  "26 f3 ec 22 7f 9d 9e 54 63 8e 8d 31 f5 05 12 15 "
-  "df 6e bb 9c 2f 95 79 aa 77 59 8a 38 f9 14 b5 b9 "
-  "c1 bd 83 c4 e2 f9 f3 82 a0 d0 aa 35 42 ff ee 65 "
-  "98 4a 60 1b c6 9e b2 8d eb 27 dc a1 2c 82 c2 d4 "
-  "c3 f6 6c d5 00 f1 ff 2b 99 4d 8a 4e 30 cb b3 3c ";
-
-// RSASSA-PSS Signature Example 1.2
-// Message to be signed:
-static const char message_1_2[] =
-  "85 13 84 cd fe 81 9c 22 ed 6c 4c cb 30 da eb 5c "
-  "f0 59 bc 8e 11 66 b7 e3 53 0c 4c 23 3e 2b 5f 8f "
-  "71 a1 cc a5 82 d4 3e cc 72 b1 bc a1 6d fc 70 13 "
-  "22 6b 9e ";
-// Salt:
-static const char salt_1_2[] =
-  "ef 28 69 fa 40 c3 46 cb 18 3d ab 3d 7b ff c9 8f "
-  "d5 6d f4 2d ";
-// Signature:
-static const char signature_1_2[] =
-  "3e f7 f4 6e 83 1b f9 2b 32 27 41 42 a5 85 ff ce "
-  "fb dc a7 b3 2a e9 0d 10 fb 0f 0c 72 99 84 f0 4e "
-  "f2 9a 9d f0 78 07 75 ce 43 73 9b 97 83 83 90 db "
-  "0a 55 05 e6 3d e9 27 02 8d 9d 29 b2 19 ca 2c 45 "
-  "17 83 25 58 a5 5d 69 4a 6d 25 b9 da b6 60 03 c4 "
-  "cc cd 90 78 02 19 3b e5 17 0d 26 14 7d 37 b9 35 "
-  "90 24 1b e5 1c 25 05 5f 47 ef 62 75 2c fb e2 14 "
-  "18 fa fe 98 c2 2c 4d 4d 47 72 4f db 56 69 e8 43 ";
-
-// RSASSA-PSS Signature Example 1.3
-// Message to be signed:
-static const char message_1_3[] =
-  "a4 b1 59 94 17 61 c4 0c 6a 82 f2 b8 0d 1b 94 f5 "
-  "aa 26 54 fd 17 e1 2d 58 88 64 67 9b 54 cd 04 ef "
-  "8b d0 30 12 be 8d c3 7f 4b 83 af 79 63 fa ff 0d "
-  "fa 22 54 77 43 7c 48 01 7f f2 be 81 91 cf 39 55 "
-  "fc 07 35 6e ab 3f 32 2f 7f 62 0e 21 d2 54 e5 db "
-  "43 24 27 9f e0 67 e0 91 0e 2e 81 ca 2c ab 31 c7 "
-  "45 e6 7a 54 05 8e b5 0d 99 3c db 9e d0 b4 d0 29 "
-  "c0 6d 21 a9 4c a6 61 c3 ce 27 fa e1 d6 cb 20 f4 "
-  "56 4d 66 ce 47 67 58 3d 0e 5f 06 02 15 b5 90 17 "
-  "be 85 ea 84 89 39 12 7b d8 c9 c4 d4 7b 51 05 6c "
-  "03 1c f3 36 f1 7c 99 80 f3 b8 f5 b9 b6 87 8e 8b "
-  "79 7a a4 3b 88 26 84 33 3e 17 89 3f e9 ca a6 aa "
-  "29 9f 7e d1 a1 8e e2 c5 48 64 b7 b2 b9 9b 72 61 "
-  "8f b0 25 74 d1 39 ef 50 f0 19 c9 ee f4 16 97 13 "
-  "38 e7 d4 70 ";
-// Salt:
-static const char salt_1_3[] =
-  "71 0b 9c 47 47 d8 00 d4 de 87 f1 2a fd ce 6d f1 "
-  "81 07 cc 77 ";
-// Signature:
-static const char signature_1_3[] =
-  "66 60 26 fb a7 1b d3 e7 cf 13 15 7c c2 c5 1a 8e "
-  "4a a6 84 af 97 78 f9 18 49 f3 43 35 d1 41 c0 01 "
-  "54 c4 19 76 21 f9 62 4a 67 5b 5a bc 22 ee 7d 5b "
-  "aa ff aa e1 c9 ba ca 2c c3 73 b3 f3 3e 78 e6 14 "
-  "3c 39 5a 91 aa 7f ac a6 64 eb 73 3a fd 14 d8 82 "
-  "72 59 d9 9a 75 50 fa ca 50 1e f2 b0 4e 33 c2 3a "
-  "a5 1f 4b 9e 82 82 ef db 72 8c c0 ab 09 40 5a 91 "
-  "60 7c 63 69 96 1b c8 27 0d 2d 4f 39 fc e6 12 b1 ";
-
-// RSASSA-PSS Signature Example 1.4
-// Message to be signed:
-static const char message_1_4[] =
-  "bc 65 67 47 fa 9e af b3 f0 ";
-// Salt:
-static const char salt_1_4[] =
-  "05 6f 00 98 5d e1 4d 8e f5 ce a9 e8 2f 8c 27 be "
-  "f7 20 33 5e ";
-// Signature:
-static const char signature_1_4[] =
-  "46 09 79 3b 23 e9 d0 93 62 dc 21 bb 47 da 0b 4f "
-  "3a 76 22 64 9a 47 d4 64 01 9b 9a ea fe 53 35 9c "
-  "17 8c 91 cd 58 ba 6b cb 78 be 03 46 a7 bc 63 7f "
-  "4b 87 3d 4b ab 38 ee 66 1f 19 96 34 c5 47 a1 ad "
-  "84 42 e0 3d a0 15 b1 36 e5 43 f7 ab 07 c0 c1 3e "
-  "42 25 b8 de 8c ce 25 d4 f6 eb 84 00 f8 1f 7e 18 "
-  "33 b7 ee 6e 33 4d 37 09 64 ca 79 fd b8 72 b4 d7 "
-  "52 23 b5 ee b0 81 01 59 1f b5 32 d1 55 a6 de 87 ";
-
-// RSASSA-PSS Signature Example 1.5
-// Message to be signed:
-static const char message_1_5[] =
-  "b4 55 81 54 7e 54 27 77 0c 76 8e 8b 82 b7 55 64 "
-  "e0 ea 4e 9c 32 59 4d 6b ff 70 65 44 de 0a 87 76 "
-  "c7 a8 0b 45 76 55 0e ee 1b 2a ca bc 7e 8b 7d 3e "
-  "f7 bb 5b 03 e4 62 c1 10 47 ea dd 00 62 9a e5 75 "
-  "48 0a c1 47 0f e0 46 f1 3a 2b f5 af 17 92 1d c4 "
-  "b0 aa 8b 02 be e6 33 49 11 65 1d 7f 85 25 d1 0f "
-  "32 b5 1d 33 be 52 0d 3d df 5a 70 99 55 a3 df e7 "
-  "82 83 b9 e0 ab 54 04 6d 15 0c 17 7f 03 7f dc cc "
-  "5b e4 ea 5f 68 b5 e5 a3 8c 9d 7e dc cc c4 97 5f "
-  "45 5a 69 09 b4 ";
-// Salt:
-static const char salt_1_5[] =
-  "80 e7 0f f8 6a 08 de 3e c6 09 72 b3 9b 4f bf dc "
-  "ea 67 ae 8e ";
-// Signature:
-static const char signature_1_5[] =
-  "1d 2a ad 22 1c a4 d3 1d df 13 50 92 39 01 93 98 "
-  "e3 d1 4b 32 dc 34 dc 5a f4 ae ae a3 c0 95 af 73 "
-  "47 9c f0 a4 5e 56 29 63 5a 53 a0 18 37 76 15 b1 "
-  "6c b9 b1 3b 3e 09 d6 71 eb 71 e3 87 b8 54 5c 59 "
-  "60 da 5a 64 77 6e 76 8e 82 b2 c9 35 83 bf 10 4c "
-  "3f db 23 51 2b 7b 4e 89 f6 33 dd 00 63 a5 30 db "
-  "45 24 b0 1c 3f 38 4c 09 31 0e 31 5a 79 dc d3 d6 "
-  "84 02 2a 7f 31 c8 65 a6 64 e3 16 97 8b 75 9f ad ";
-
-// RSASSA-PSS Signature Example 1.6
-// Message to be signed:
-static const char message_1_6[] =
-  "10 aa e9 a0 ab 0b 59 5d 08 41 20 7b 70 0d 48 d7 "
-  "5f ae dd e3 b7 75 cd 6b 4c c8 8a e0 6e 46 94 ec "
-  "74 ba 18 f8 52 0d 4f 5e a6 9c bb e7 cc 2b eb a4 "
-  "3e fd c1 02 15 ac 4e b3 2d c3 02 a1 f5 3d c6 c4 "
-  "35 22 67 e7 93 6c fe bf 7c 8d 67 03 57 84 a3 90 "
-  "9f a8 59 c7 b7 b5 9b 8e 39 c5 c2 34 9f 18 86 b7 "
-  "05 a3 02 67 d4 02 f7 48 6a b4 f5 8c ad 5d 69 ad "
-  "b1 7a b8 cd 0c e1 ca f5 02 5a f4 ae 24 b1 fb 87 "
-  "94 c6 07 0c c0 9a 51 e2 f9 91 13 11 e3 87 7d 00 "
-  "44 c7 1c 57 a9 93 39 50 08 80 6b 72 3a c3 83 73 "
-  "d3 95 48 18 18 52 8c 1e 70 53 73 92 82 05 35 29 "
-  "51 0e 93 5c d0 fa 77 b8 fa 53 cc 2d 47 4b d4 fb "
-  "3c c5 c6 72 d6 ff dc 90 a0 0f 98 48 71 2c 4b cf "
-  "e4 6c 60 57 36 59 b1 1e 64 57 e8 61 f0 f6 04 b6 "
-  "13 8d 14 4f 8c e4 e2 da 73 ";
-// Salt:
-static const char salt_1_6[] =
-  "a8 ab 69 dd 80 1f 00 74 c2 a1 fc 60 64 98 36 c6 "
-  "16 d9 96 81 ";
-// Signature:
-static const char signature_1_6[] =
-  "2a 34 f6 12 5e 1f 6b 0b f9 71 e8 4f bd 41 c6 32 "
-  "be 8f 2c 2a ce 7d e8 b6 92 6e 31 ff 93 e9 af 98 "
-  "7f bc 06 e5 1e 9b e1 4f 51 98 f9 1f 3f 95 3b d6 "
-  "7d a6 0a 9d f5 97 64 c3 dc 0f e0 8e 1c be f0 b7 "
-  "5f 86 8d 10 ad 3f ba 74 9f ef 59 fb 6d ac 46 a0 "
-  "d6 e5 04 36 93 31 58 6f 58 e4 62 8f 39 aa 27 89 "
-  "82 54 3b c0 ee b5 37 dc 61 95 80 19 b3 94 fb 27 "
-  "3f 21 58 58 a0 a0 1a c4 d6 50 b9 55 c6 7f 4c 58 ";
-
-// Example 9: A 1536-bit RSA Key Pair
-
-// RSA modulus n:
-static const char rsa_modulus_n_9[] =
-  "e6 bd 69 2a c9 66 45 79 04 03 fd d0 f5 be b8 b9 "
-  "bf 92 ed 10 00 7f c3 65 04 64 19 dd 06 c0 5c 5b "
-  "5b 2f 48 ec f9 89 e4 ce 26 91 09 97 9c bb 40 b4 "
-  "a0 ad 24 d2 24 83 d1 ee 31 5a d4 cc b1 53 42 68 "
-  "35 26 91 c5 24 f6 dd 8e 6c 29 d2 24 cf 24 69 73 "
-  "ae c8 6c 5b f6 b1 40 1a 85 0d 1b 9a d1 bb 8c bc "
-  "ec 47 b0 6f 0f 8c 7f 45 d3 fc 8f 31 92 99 c5 43 "
-  "3d db c2 b3 05 3b 47 de d2 ec d4 a4 ca ef d6 14 "
-  "83 3d c8 bb 62 2f 31 7e d0 76 b8 05 7f e8 de 3f "
-  "84 48 0a d5 e8 3e 4a 61 90 4a 4f 24 8f b3 97 02 "
-  "73 57 e1 d3 0e 46 31 39 81 5c 6f d4 fd 5a c5 b8 "
-  "17 2a 45 23 0e cb 63 18 a0 4f 14 55 d8 4e 5a 8b ";
-// RSA public exponent e:
-static const char rsa_public_exponent_e_9[] =
-  "01 00 01 ";
-
-// RSASSA-PSS Signature Example 9.1
-// Message to be signed:
-static const char message_9_1[] =
-  "a8 8e 26 58 55 e9 d7 ca 36 c6 87 95 f0 b3 1b 59 "
-  "1c d6 58 7c 71 d0 60 a0 b3 f7 f3 ea ef 43 79 59 "
-  "22 02 8b c2 b6 ad 46 7c fc 2d 7f 65 9c 53 85 aa "
-  "70 ba 36 72 cd de 4c fe 49 70 cc 79 04 60 1b 27 "
-  "88 72 bf 51 32 1c 4a 97 2f 3c 95 57 0f 34 45 d4 "
-  "f5 79 80 e0 f2 0d f5 48 46 e6 a5 2c 66 8f 12 88 "
-  "c0 3f 95 00 6e a3 2f 56 2d 40 d5 2a f9 fe b3 2f "
-  "0f a0 6d b6 5b 58 8a 23 7b 34 e5 92 d5 5c f9 79 "
-  "f9 03 a6 42 ef 64 d2 ed 54 2a a8 c7 7d c1 dd 76 "
-  "2f 45 a5 93 03 ed 75 e5 41 ca 27 1e 2b 60 ca 70 "
-  "9e 44 fa 06 61 13 1e 8d 5d 41 63 fd 8d 39 85 66 "
-  "ce 26 de 87 30 e7 2f 9c ca 73 76 41 c2 44 15 94 "
-  "20 63 70 28 df 0a 18 07 9d 62 08 ea 8b 47 11 a2 "
-  "c7 50 f5 ";
-// Salt:
-static const char salt_9_1[] =
-  "c0 a4 25 31 3d f8 d7 56 4b d2 43 4d 31 15 23 d5 "
-  "25 7e ed 80 ";
-// Signature:
-static const char signature_9_1[] =
-  "58 61 07 22 6c 3c e0 13 a7 c8 f0 4d 1a 6a 29 59 "
-  "bb 4b 8e 20 5b a4 3a 27 b5 0f 12 41 11 bc 35 ef "
-  "58 9b 03 9f 59 32 18 7c b6 96 d7 d9 a3 2c 0c 38 "
-  "30 0a 5c dd a4 83 4b 62 d2 eb 24 0a f3 3f 79 d1 "
-  "3d fb f0 95 bf 59 9e 0d 96 86 94 8c 19 64 74 7b "
-  "67 e8 9c 9a ba 5c d8 50 16 23 6f 56 6c c5 80 2c "
-  "b1 3e ad 51 bc 7c a6 be f3 b9 4d cb db b1 d5 70 "
-  "46 97 71 df 0e 00 b1 a8 a0 67 77 47 2d 23 16 27 "
-  "9e da e8 64 74 66 8d 4e 1e ff f9 5f 1d e6 1c 60 "
-  "20 da 32 ae 92 bb f1 65 20 fe f3 cf 4d 88 f6 11 "
-  "21 f2 4b bd 9f e9 1b 59 ca f1 23 5b 2a 93 ff 81 "
-  "fc 40 3a dd f4 eb de a8 49 34 a9 cd af 8e 1a 9e ";
-
-// RSASSA-PSS Signature Example 9.2
-// Message to be signed:
-static const char message_9_2[] =
-  "c8 c9 c6 af 04 ac da 41 4d 22 7e f2 3e 08 20 c3 "
-  "73 2c 50 0d c8 72 75 e9 5b 0d 09 54 13 99 3c 26 "
-  "58 bc 1d 98 85 81 ba 87 9c 2d 20 1f 14 cb 88 ce "
-  "d1 53 a0 19 69 a7 bf 0a 7b e7 9c 84 c1 48 6b c1 "
-  "2b 3f a6 c5 98 71 b6 82 7c 8c e2 53 ca 5f ef a8 "
-  "a8 c6 90 bf 32 6e 8e 37 cd b9 6d 90 a8 2e ba b6 "
-  "9f 86 35 0e 18 22 e8 bd 53 6a 2e ";
-// Salt:
-static const char salt_9_2[] =
-  "b3 07 c4 3b 48 50 a8 da c2 f1 5f 32 e3 78 39 ef "
-  "8c 5c 0e 91 ";
-// Signature:
-static const char signature_9_2[] =
-  "80 b6 d6 43 25 52 09 f0 a4 56 76 38 97 ac 9e d2 "
-  "59 d4 59 b4 9c 28 87 e5 88 2e cb 44 34 cf d6 6d "
-  "d7 e1 69 93 75 38 1e 51 cd 7f 55 4f 2c 27 17 04 "
-  "b3 99 d4 2b 4b e2 54 0a 0e ca 61 95 1f 55 26 7f "
-  "7c 28 78 c1 22 84 2d ad b2 8b 01 bd 5f 8c 02 5f "
-  "7e 22 84 18 a6 73 c0 3d 6b c0 c7 36 d0 a2 95 46 "
-  "bd 67 f7 86 d9 d6 92 cc ea 77 8d 71 d9 8c 20 63 "
-  "b7 a7 10 92 18 7a 4d 35 af 10 81 11 d8 3e 83 ea "
-  "e4 6c 46 aa 34 27 7e 06 04 45 89 90 37 88 f1 d5 "
-  "e7 ce e2 5f b4 85 e9 29 49 11 88 14 d6 f2 c3 ee "
-  "36 14 89 01 6f 32 7f b5 bc 51 7e b5 04 70 bf fa "
-  "1a fa 5f 4c e9 aa 0c e5 b8 ee 19 bf 55 01 b9 58 ";
-
-// RSASSA-PSS Signature Example 9.3
-// Message to be signed:
-static const char message_9_3[] =
-  "0a fa d4 2c cd 4f c6 06 54 a5 50 02 d2 28 f5 2a "
-  "4a 5f e0 3b 8b bb 08 ca 82 da ca 55 8b 44 db e1 "
-  "26 6e 50 c0 e7 45 a3 6d 9d 29 04 e3 40 8a bc d1 "
-  "fd 56 99 94 06 3f 4a 75 cc 72 f2 fe e2 a0 cd 89 "
-  "3a 43 af 1c 5b 8b 48 7d f0 a7 16 10 02 4e 4f 6d "
-  "df 9f 28 ad 08 13 c1 aa b9 1b cb 3c 90 64 d5 ff "
-  "74 2d ef fe a6 57 09 41 39 36 9e 5e a6 f4 a9 63 "
-  "19 a5 cc 82 24 14 5b 54 50 62 75 8f ef d1 fe 34 "
-  "09 ae 16 92 59 c6 cd fd 6b 5f 29 58 e3 14 fa ec "
-  "be 69 d2 ca ce 58 ee 55 17 9a b9 b3 e6 d1 ec c1 "
-  "4a 55 7c 5f eb e9 88 59 52 64 fc 5d a1 c5 71 46 "
-  "2e ca 79 8a 18 a1 a4 94 0c da b4 a3 e9 20 09 cc "
-  "d4 2e 1e 94 7b 13 14 e3 22 38 a2 de ce 7d 23 a8 "
-  "9b 5b 30 c7 51 fd 0a 4a 43 0d 2c 54 85 94 ";
-// Salt:
-static const char salt_9_3[] =
-  "9a 2b 00 7e 80 97 8b bb 19 2c 35 4e b7 da 9a ed "
-  "fc 74 db f5 ";
-// Signature:
-static const char signature_9_3[] =
-  "48 44 08 f3 89 8c d5 f5 34 83 f8 08 19 ef bf 27 "
-  "08 c3 4d 27 a8 b2 a6 fa e8 b3 22 f9 24 02 37 f9 "
-  "81 81 7a ca 18 46 f1 08 4d aa 6d 7c 07 95 f6 e5 "
-  "bf 1a f5 9c 38 e1 85 84 37 ce 1f 7e c4 19 b9 8c "
-  "87 36 ad f6 dd 9a 00 b1 80 6d 2b d3 ad 0a 73 77 "
-  "5e 05 f5 2d fe f3 a5 9a b4 b0 81 43 f0 df 05 cd "
-  "1a d9 d0 4b ec ec a6 da a4 a2 12 98 03 e2 00 cb "
-  "c7 77 87 ca f4 c1 d0 66 3a 6c 59 87 b6 05 95 20 "
-  "19 78 2c af 2e c1 42 6d 68 fb 94 ed 1d 4b e8 16 "
-  "a7 ed 08 1b 77 e6 ab 33 0b 3f fc 07 38 20 fe cd "
-  "e3 72 7f cb e2 95 ee 61 a0 50 a3 43 65 86 37 c3 "
-  "fd 65 9c fb 63 73 6d e3 2d 9f 90 d3 c2 f6 3e ca ";
-
-// RSASSA-PSS Signature Example 9.4
-// Message to be signed:
-static const char message_9_4[] =
-  "1d fd 43 b4 6c 93 db 82 62 9b da e2 bd 0a 12 b8 "
-  "82 ea 04 c3 b4 65 f5 cf 93 02 3f 01 05 96 26 db "
-  "be 99 f2 6b b1 be 94 9d dd d1 6d c7 f3 de bb 19 "
-  "a1 94 62 7f 0b 22 44 34 df 7d 87 00 e9 e9 8b 06 "
-  "e3 60 c1 2f db e3 d1 9f 51 c9 68 4e b9 08 9e cb "
-  "b0 a2 f0 45 03 99 d3 f5 9e ac 72 94 08 5d 04 4f "
-  "53 93 c6 ce 73 74 23 d8 b8 6c 41 53 70 d3 89 e3 "
-  "0b 9f 0a 3c 02 d2 5d 00 82 e8 ad 6f 3f 1e f2 4a "
-  "45 c3 cf 82 b3 83 36 70 63 a4 d4 61 3e 42 64 f0 "
-  "1b 2d ac 2e 5a a4 20 43 f8 fb 5f 69 fa 87 1d 14 "
-  "fb 27 3e 76 7a 53 1c 40 f0 2f 34 3b c2 fb 45 a0 "
-  "c7 e0 f6 be 25 61 92 3a 77 21 1d 66 a6 e2 db b4 "
-  "3c 36 63 50 be ae 22 da 3a c2 c1 f5 07 70 96 fc "
-  "b5 c4 bf 25 5f 75 74 35 1a e0 b1 e1 f0 36 32 81 "
-  "7c 08 56 d4 a8 ba 97 af bd c8 b8 58 55 40 2b c5 "
-  "69 26 fc ec 20 9f 9e a8 ";
-// Salt:
-static const char salt_9_4[] =
-  "70 f3 82 bd df 4d 5d 2d d8 8b 3b c7 b7 30 8b e6 "
-  "32 b8 40 45 ";
-// Signature:
-static const char signature_9_4[] =
-  "84 eb eb 48 1b e5 98 45 b4 64 68 ba fb 47 1c 01 "
-  "12 e0 2b 23 5d 84 b5 d9 11 cb d1 92 6e e5 07 4a "
-  "e0 42 44 95 cb 20 e8 23 08 b8 eb b6 5f 41 9a 03 "
-  "fb 40 e7 2b 78 98 1d 88 aa d1 43 05 36 85 17 2c "
-  "97 b2 9c 8b 7b f0 ae 73 b5 b2 26 3c 40 3d a0 ed "
-  "2f 80 ff 74 50 af 78 28 eb 8b 86 f0 02 8b d2 a8 "
-  "b1 76 a4 d2 28 cc ce a1 83 94 f2 38 b0 9f f7 58 "
-  "cc 00 bc 04 30 11 52 35 57 42 f2 82 b5 4e 66 3a "
-  "91 9e 70 9d 8d a2 4a de 55 00 a7 b9 aa 50 22 6e "
-  "0c a5 29 23 e6 c2 d8 60 ec 50 ff 48 0f a5 74 77 "
-  "e8 2b 05 65 f4 37 9f 79 c7 72 d5 c2 da 80 af 9f "
-  "bf 32 5e ce 6f c2 0b 00 96 16 14 be e8 9a 18 3e ";
-
-// RSASSA-PSS Signature Example 9.5
-// Message to be signed:
-static const char message_9_5[] =
-  "1b dc 6e 7c 98 fb 8c f5 4e 9b 09 7b 66 a8 31 e9 "
-  "cf e5 2d 9d 48 88 44 8e e4 b0 97 80 93 ba 1d 7d "
-  "73 ae 78 b3 a6 2b a4 ad 95 cd 28 9c cb 9e 00 52 "
-  "26 bb 3d 17 8b cc aa 82 1f b0 44 a4 e2 1e e9 76 "
-  "96 c1 4d 06 78 c9 4c 2d ae 93 b0 ad 73 92 22 18 "
-  "55 3d aa 7e 44 eb e5 77 25 a7 a4 5c c7 2b 9b 21 "
-  "38 a6 b1 7c 8d b4 11 ce 82 79 ee 12 41 af f0 a8 "
-  "be c6 f7 7f 87 ed b0 c6 9c b2 72 36 e3 43 5a 80 "
-  "0b 19 2e 4f 11 e5 19 e3 fe 30 fc 30 ea cc ca 4f "
-  "bb 41 76 90 29 bf 70 8e 81 7a 9e 68 38 05 be 67 "
-  "fa 10 09 84 68 3b 74 83 8e 3b cf fa 79 36 6e ed "
-  "1d 48 1c 76 72 91 18 83 8f 31 ba 8a 04 8a 93 c1 "
-  "be 44 24 59 8e 8d f6 32 8b 7a 77 88 0a 3f 9c 7e "
-  "2e 8d fc a8 eb 5a 26 fb 86 bd c5 56 d4 2b be 01 "
-  "d9 fa 6e d8 06 46 49 1c 93 41 ";
-// Salt:
-static const char salt_9_5[] =
-  "d6 89 25 7a 86 ef fa 68 21 2c 5e 0c 61 9e ca 29 "
-  "5f b9 1b 67 ";
-// Signature:
-static const char signature_9_5[] =
-  "82 10 2d f8 cb 91 e7 17 99 19 a0 4d 26 d3 35 d6 "
-  "4f bc 2f 87 2c 44 83 39 43 24 1d e8 45 48 10 27 "
-  "4c df 3d b5 f4 2d 42 3d b1 52 af 71 35 f7 01 42 "
-  "0e 39 b4 94 a6 7c bf d1 9f 91 19 da 23 3a 23 da "
-  "5c 64 39 b5 ba 0d 2b c3 73 ee e3 50 70 01 37 8d "
-  "4a 40 73 85 6b 7f e2 ab a0 b5 ee 93 b2 7f 4a fe "
-  "c7 d4 d1 20 92 1c 83 f6 06 76 5b 02 c1 9e 4d 6a "
-  "1a 3b 95 fa 4c 42 29 51 be 4f 52 13 10 77 ef 17 "
-  "17 97 29 cd df bd b5 69 50 db ac ee fe 78 cb 16 "
-  "64 0a 09 9e a5 6d 24 38 9e ef 10 f8 fe cb 31 ba "
-  "3e a3 b2 27 c0 a8 66 98 bb 89 e3 e9 36 39 05 bf "
-  "22 77 7b 2a 3a a5 21 b6 5b 4c ef 76 d8 3b de 4c ";
-
-// RSASSA-PSS Signature Example 9.6
-// Message to be signed:
-static const char message_9_6[] =
-  "88 c7 a9 f1 36 04 01 d9 0e 53 b1 01 b6 1c 53 25 "
-  "c3 c7 5d b1 b4 11 fb eb 8e 83 0b 75 e9 6b 56 67 "
-  "0a d2 45 40 4e 16 79 35 44 ee 35 4b c6 13 a9 0c "
-  "c9 84 87 15 a7 3d b5 89 3e 7f 6d 27 98 15 c0 c1 "
-  "de 83 ef 8e 29 56 e3 a5 6e d2 6a 88 8d 7a 9c dc "
-  "d0 42 f4 b1 6b 7f a5 1e f1 a0 57 36 62 d1 6a 30 "
-  "2d 0e c5 b2 85 d2 e0 3a d9 65 29 c8 7b 3d 37 4d "
-  "b3 72 d9 5b 24 43 d0 61 b6 b1 a3 50 ba 87 80 7e "
-  "d0 83 af d1 eb 05 c3 f5 2f 4e ba 5e d2 22 77 14 "
-  "fd b5 0b 9d 9d 9d d6 81 4f 62 f6 27 2f cd 5c db "
-  "ce 7a 9e f7 97 ";
-// Salt:
-static const char salt_9_6[] =
-  "c2 5f 13 bf 67 d0 81 67 1a 04 81 a1 f1 82 0d 61 "
-  "3b ba 22 76 ";
-// Signature:
-static const char signature_9_6[] =
-  "a7 fd b0 d2 59 16 5c a2 c8 8d 00 bb f1 02 8a 86 "
-  "7d 33 76 99 d0 61 19 3b 17 a9 64 8e 14 cc bb aa "
-  "de ac aa cd ec 81 5e 75 71 29 4e bb 8a 11 7a f2 "
-  "05 fa 07 8b 47 b0 71 2c 19 9e 3a d0 51 35 c5 04 "
-  "c2 4b 81 70 51 15 74 08 02 48 79 92 ff d5 11 d4 "
-  "af c6 b8 54 49 1e b3 f0 dd 52 31 39 54 2f f1 5c "
-  "31 01 ee 85 54 35 17 c6 a3 c7 94 17 c6 7e 2d d9 "
-  "aa 74 1e 9a 29 b0 6d cb 59 3c 23 36 b3 67 0a e3 "
-  "af ba c7 c3 e7 6e 21 54 73 e8 66 e3 38 ca 24 4d "
-  "e0 0b 62 62 4d 6b 94 26 82 2c ea e9 f8 cc 46 08 "
-  "95 f4 12 50 07 3f d4 5c 5a 1e 7b 42 5c 20 4a 42 "
-  "3a 69 91 59 f6 90 3e 71 0b 37 a7 bb 2b c8 04 9f ";
-
-// Example 10: A 2048-bit RSA Key Pair
-
-// RSA modulus n:
-static const char rsa_modulus_n_10[] =
-  "a5 dd 86 7a c4 cb 02 f9 0b 94 57 d4 8c 14 a7 70 "
-  "ef 99 1c 56 c3 9c 0e c6 5f d1 1a fa 89 37 ce a5 "
-  "7b 9b e7 ac 73 b4 5c 00 17 61 5b 82 d6 22 e3 18 "
-  "75 3b 60 27 c0 fd 15 7b e1 2f 80 90 fe e2 a7 ad "
-  "cd 0e ef 75 9f 88 ba 49 97 c7 a4 2d 58 c9 aa 12 "
-  "cb 99 ae 00 1f e5 21 c1 3b b5 43 14 45 a8 d5 ae "
-  "4f 5e 4c 7e 94 8a c2 27 d3 60 40 71 f2 0e 57 7e "
-  "90 5f be b1 5d fa f0 6d 1d e5 ae 62 53 d6 3a 6a "
-  "21 20 b3 1a 5d a5 da bc 95 50 60 0e 20 f2 7d 37 "
-  "39 e2 62 79 25 fe a3 cc 50 9f 21 df f0 4e 6e ea "
-  "45 49 c5 40 d6 80 9f f9 30 7e ed e9 1f ff 58 73 "
-  "3d 83 85 a2 37 d6 d3 70 5a 33 e3 91 90 09 92 07 "
-  "0d f7 ad f1 35 7c f7 e3 70 0c e3 66 7d e8 3f 17 "
-  "b8 df 17 78 db 38 1d ce 09 cb 4a d0 58 a5 11 00 "
-  "1a 73 81 98 ee 27 cf 55 a1 3b 75 45 39 90 65 82 "
-  "ec 8b 17 4b d5 8d 5d 1f 3d 76 7c 61 37 21 ae 05 ";
-// RSA public exponent e:
-static const char rsa_public_exponent_e_10[] =
-  "01 00 01 ";
-
-// RSASSA-PSS Signature Example 10.1
-// Message to be signed:
-static const char message_10_1[] =
-  "88 31 77 e5 12 6b 9b e2 d9 a9 68 03 27 d5 37 0c "
-  "6f 26 86 1f 58 20 c4 3d a6 7a 3a d6 09 ";
-// Salt:
-static const char salt_10_1[] =
-  "04 e2 15 ee 6f f9 34 b9 da 70 d7 73 0c 87 34 ab "
-  "fc ec de 89 ";
-// Signature:
-static const char signature_10_1[] =
-  "82 c2 b1 60 09 3b 8a a3 c0 f7 52 2b 19 f8 73 54 "
-  "06 6c 77 84 7a bf 2a 9f ce 54 2d 0e 84 e9 20 c5 "
-  "af b4 9f fd fd ac e1 65 60 ee 94 a1 36 96 01 14 "
-  "8e ba d7 a0 e1 51 cf 16 33 17 91 a5 72 7d 05 f2 "
-  "1e 74 e7 eb 81 14 40 20 69 35 d7 44 76 5a 15 e7 "
-  "9f 01 5c b6 6c 53 2c 87 a6 a0 59 61 c8 bf ad 74 "
-  "1a 9a 66 57 02 28 94 39 3e 72 23 73 97 96 c0 2a "
-  "77 45 5d 0f 55 5b 0e c0 1d df 25 9b 62 07 fd 0f "
-  "d5 76 14 ce f1 a5 57 3b aa ff 4e c0 00 69 95 16 "
-  "59 b8 5f 24 30 0a 25 16 0c a8 52 2d c6 e6 72 7e "
-  "57 d0 19 d7 e6 36 29 b8 fe 5e 89 e2 5c c1 5b eb "
-  "3a 64 75 77 55 92 99 28 0b 9b 28 f7 9b 04 09 00 "
-  "0b e2 5b bd 96 40 8b a3 b4 3c c4 86 18 4d d1 c8 "
-  "e6 25 53 fa 1a f4 04 0f 60 66 3d e7 f5 e4 9c 04 "
-  "38 8e 25 7f 1c e8 9c 95 da b4 8a 31 5d 9b 66 b1 "
-  "b7 62 82 33 87 6f f2 38 52 30 d0 70 d0 7e 16 66 ";
-
-// RSASSA-PSS Signature Example 10.2
-// Message to be signed:
-static const char message_10_2[] =
-  "dd 67 0a 01 46 58 68 ad c9 3f 26 13 19 57 a5 0c "
-  "52 fb 77 7c db aa 30 89 2c 9e 12 36 11 64 ec 13 "
-  "97 9d 43 04 81 18 e4 44 5d b8 7b ee 58 dd 98 7b "
-  "34 25 d0 20 71 d8 db ae 80 70 8b 03 9d bb 64 db "
-  "d1 de 56 57 d9 fe d0 c1 18 a5 41 43 74 2e 0f f3 "
-  "c8 7f 74 e4 58 57 64 7a f3 f7 9e b0 a1 4c 9d 75 "
-  "ea 9a 1a 04 b7 cf 47 8a 89 7a 70 8f d9 88 f4 8e "
-  "80 1e db 0b 70 39 df 8c 23 bb 3c 56 f4 e8 21 ac ";
-// Salt:
-static const char salt_10_2[] =
-  "8b 2b dd 4b 40 fa f5 45 c7 78 dd f9 bc 1a 49 cb "
-  "57 f9 b7 1b ";
-// Signature:
-static const char signature_10_2[] =
-  "14 ae 35 d9 dd 06 ba 92 f7 f3 b8 97 97 8a ed 7c "
-  "d4 bf 5f f0 b5 85 a4 0b d4 6c e1 b4 2c d2 70 30 "
-  "53 bb 90 44 d6 4e 81 3d 8f 96 db 2d d7 00 7d 10 "
-  "11 8f 6f 8f 84 96 09 7a d7 5e 1f f6 92 34 1b 28 "
-  "92 ad 55 a6 33 a1 c5 5e 7f 0a 0a d5 9a 0e 20 3a "
-  "5b 82 78 ae c5 4d d8 62 2e 28 31 d8 71 74 f8 ca "
-  "ff 43 ee 6c 46 44 53 45 d8 4a 59 65 9b fb 92 ec "
-  "d4 c8 18 66 86 95 f3 47 06 f6 68 28 a8 99 59 63 "
-  "7f 2b f3 e3 25 1c 24 bd ba 4d 4b 76 49 da 00 22 "
-  "21 8b 11 9c 84 e7 9a 65 27 ec 5b 8a 5f 86 1c 15 "
-  "99 52 e2 3e c0 5e 1e 71 73 46 fa ef e8 b1 68 68 "
-  "25 bd 2b 26 2f b2 53 10 66 c0 de 09 ac de 2e 42 "
-  "31 69 07 28 b5 d8 5e 11 5a 2f 6b 92 b7 9c 25 ab "
-  "c9 bd 93 99 ff 8b cf 82 5a 52 ea 1f 56 ea 76 dd "
-  "26 f4 3b aa fa 18 bf a9 2a 50 4c bd 35 69 9e 26 "
-  "d1 dc c5 a2 88 73 85 f3 c6 32 32 f0 6f 32 44 c3 ";
-
-// RSASSA-PSS Signature Example 10.3
-// Message to be signed:
-static const char message_10_3[] =
-  "48 b2 b6 a5 7a 63 c8 4c ea 85 9d 65 c6 68 28 4b "
-  "08 d9 6b dc aa be 25 2d b0 e4 a9 6c b1 ba c6 01 "
-  "93 41 db 6f be fb 8d 10 6b 0e 90 ed a6 bc c6 c6 "
-  "26 2f 37 e7 ea 9c 7e 5d 22 6b d7 df 85 ec 5e 71 "
-  "ef ff 2f 54 c5 db 57 7f f7 29 ff 91 b8 42 49 1d "
-  "e2 74 1d 0c 63 16 07 df 58 6b 90 5b 23 b9 1a f1 "
-  "3d a1 23 04 bf 83 ec a8 a7 3e 87 1f f9 db ";
-// Salt:
-static const char salt_10_3[] =
-  "4e 96 fc 1b 39 8f 92 b4 46 71 01 0c 0d c3 ef d6 "
-  "e2 0c 2d 73 ";
-// Signature:
-static const char signature_10_3[] =
-  "6e 3e 4d 7b 6b 15 d2 fb 46 01 3b 89 00 aa 5b bb "
-  "39 39 cf 2c 09 57 17 98 70 42 02 6e e6 2c 74 c5 "
-  "4c ff d5 d7 d5 7e fb bf 95 0a 0f 5c 57 4f a0 9d "
-  "3f c1 c9 f5 13 b0 5b 4f f5 0d d8 df 7e df a2 01 "
-  "02 85 4c 35 e5 92 18 01 19 a7 0c e5 b0 85 18 2a "
-  "a0 2d 9e a2 aa 90 d1 df 03 f2 da ae 88 5b a2 f5 "
-  "d0 5a fd ac 97 47 6f 06 b9 3b 5b c9 4a 1a 80 aa "
-  "91 16 c4 d6 15 f3 33 b0 98 89 2b 25 ff ac e2 66 "
-  "f5 db 5a 5a 3b cc 10 a8 24 ed 55 aa d3 5b 72 78 "
-  "34 fb 8c 07 da 28 fc f4 16 a5 d9 b2 22 4f 1f 8b "
-  "44 2b 36 f9 1e 45 6f de a2 d7 cf e3 36 72 68 de "
-  "03 07 a4 c7 4e 92 41 59 ed 33 39 3d 5e 06 55 53 "
-  "1c 77 32 7b 89 82 1b de df 88 01 61 c7 8c d4 19 "
-  "6b 54 19 f7 ac c3 f1 3e 5e bf 16 1b 6e 7c 67 24 "
-  "71 6c a3 3b 85 c2 e2 56 40 19 2a c2 85 96 51 d5 "
-  "0b de 7e b9 76 e5 1c ec 82 8b 98 b6 56 3b 86 bb ";
-
-// RSASSA-PSS Signature Example 10.4
-// Message to be signed:
-static const char message_10_4[] =
-  "0b 87 77 c7 f8 39 ba f0 a6 4b bb db c5 ce 79 75 "
-  "5c 57 a2 05 b8 45 c1 74 e2 d2 e9 05 46 a0 89 c4 "
-  "e6 ec 8a df fa 23 a7 ea 97 ba e6 b6 5d 78 2b 82 "
-  "db 5d 2b 5a 56 d2 2a 29 a0 5e 7c 44 33 e2 b8 2a "
-  "62 1a bb a9 0a dd 05 ce 39 3f c4 8a 84 05 42 45 "
-  "1a ";
-// Salt:
-static const char salt_10_4[] =
-  "c7 cd 69 8d 84 b6 51 28 d8 83 5e 3a 8b 1e b0 e0 "
-  "1c b5 41 ec ";
-// Signature:
-static const char signature_10_4[] =
-  "34 04 7f f9 6c 4d c0 dc 90 b2 d4 ff 59 a1 a3 61 "
-  "a4 75 4b 25 5d 2e e0 af 7d 8b f8 7c 9b c9 e7 dd "
-  "ee de 33 93 4c 63 ca 1c 0e 3d 26 2c b1 45 ef 93 "
-  "2a 1f 2c 0a 99 7a a6 a3 4f 8e ae e7 47 7d 82 cc "
-  "f0 90 95 a6 b8 ac ad 38 d4 ee c9 fb 7e ab 7a d0 "
-  "2d a1 d1 1d 8e 54 c1 82 5e 55 bf 58 c2 a2 32 34 "
-  "b9 02 be 12 4f 9e 90 38 a8 f6 8f a4 5d ab 72 f6 "
-  "6e 09 45 bf 1d 8b ac c9 04 4c 6f 07 09 8c 9f ce "
-  "c5 8a 3a ab 10 0c 80 51 78 15 5f 03 0a 12 4c 45 "
-  "0e 5a cb da 47 d0 e4 f1 0b 80 a2 3f 80 3e 77 4d "
-  "02 3b 00 15 c2 0b 9f 9b be 7c 91 29 63 38 d5 ec "
-  "b4 71 ca fb 03 20 07 b6 7a 60 be 5f 69 50 4a 9f "
-  "01 ab b3 cb 46 7b 26 0e 2b ce 86 0b e8 d9 5b f9 "
-  "2c 0c 8e 14 96 ed 1e 52 85 93 a4 ab b6 df 46 2d "
-  "de 8a 09 68 df fe 46 83 11 68 57 a2 32 f5 eb f6 "
-  "c8 5b e2 38 74 5a d0 f3 8f 76 7a 5f db f4 86 fb ";
-
-// RSASSA-PSS Signature Example 10.5
-// Message to be signed:
-static const char message_10_5[] =
-  "f1 03 6e 00 8e 71 e9 64 da dc 92 19 ed 30 e1 7f "
-  "06 b4 b6 8a 95 5c 16 b3 12 b1 ed df 02 8b 74 97 "
-  "6b ed 6b 3f 6a 63 d4 e7 78 59 24 3c 9c cc dc 98 "
-  "01 65 23 ab b0 24 83 b3 55 91 c3 3a ad 81 21 3b "
-  "b7 c7 bb 1a 47 0a ab c1 0d 44 25 6c 4d 45 59 d9 "
-  "16 ";
-// Salt:
-static const char salt_10_5[] =
-  "ef a8 bf f9 62 12 b2 f4 a3 f3 71 a1 0d 57 41 52 "
-  "65 5f 5d fb ";
-// Signature:
-static const char signature_10_5[] =
-  "7e 09 35 ea 18 f4 d6 c1 d1 7c e8 2e b2 b3 83 6c "
-  "55 b3 84 58 9c e1 9d fe 74 33 63 ac 99 48 d1 f3 "
-  "46 b7 bf dd fe 92 ef d7 8a db 21 fa ef c8 9a de "
-  "42 b1 0f 37 40 03 fe 12 2e 67 42 9a 1c b8 cb d1 "
-  "f8 d9 01 45 64 c4 4d 12 01 16 f4 99 0f 1a 6e 38 "
-  "77 4c 19 4b d1 b8 21 32 86 b0 77 b0 49 9d 2e 7b "
-  "3f 43 4a b1 22 89 c5 56 68 4d ee d7 81 31 93 4b "
-  "b3 dd 65 37 23 6f 7c 6f 3d cb 09 d4 76 be 07 72 "
-  "1e 37 e1 ce ed 9b 2f 7b 40 68 87 bd 53 15 73 05 "
-  "e1 c8 b4 f8 4d 73 3b c1 e1 86 fe 06 cc 59 b6 ed "
-  "b8 f4 bd 7f fe fd f4 f7 ba 9c fb 9d 57 06 89 b5 "
-  "a1 a4 10 9a 74 6a 69 08 93 db 37 99 25 5a 0c b9 "
-  "21 5d 2d 1c d4 90 59 0e 95 2e 8c 87 86 aa 00 11 "
-  "26 52 52 47 0c 04 1d fb c3 ee c7 c3 cb f7 1c 24 "
-  "86 9d 11 5c 0c b4 a9 56 f5 6d 53 0b 80 ab 58 9a "
-  "cf ef c6 90 75 1d df 36 e8 d3 83 f8 3c ed d2 cc ";
-
-// RSASSA-PSS Signature Example 10.6
-// Message to be signed:
-static const char message_10_6[] =
-  "25 f1 08 95 a8 77 16 c1 37 45 0b b9 51 9d fa a1 "
-  "f2 07 fa a9 42 ea 88 ab f7 1e 9c 17 98 00 85 b5 "
-  "55 ae ba b7 62 64 ae 2a 3a b9 3c 2d 12 98 11 91 "
-  "dd ac 6f b5 94 9e b3 6a ee 3c 5d a9 40 f0 07 52 "
-  "c9 16 d9 46 08 fa 7d 97 ba 6a 29 15 b6 88 f2 03 "
-  "23 d4 e9 d9 68 01 d8 9a 72 ab 58 92 dc 21 17 c0 "
-  "74 34 fc f9 72 e0 58 cf 8c 41 ca 4b 4f f5 54 f7 "
-  "d5 06 8a d3 15 5f ce d0 f3 12 5b c0 4f 91 93 37 "
-  "8a 8f 5c 4c 3b 8c b4 dd 6d 1c c6 9d 30 ec ca 6e "
-  "aa 51 e3 6a 05 73 0e 9e 34 2e 85 5b af 09 9d ef "
-  "b8 af d7 ";
-// Salt:
-static const char salt_10_6[] =
-  "ad 8b 15 23 70 36 46 22 4b 66 0b 55 08 85 91 7c "
-  "a2 d1 df 28 ";
-// Signature:
-static const char signature_10_6[] =
-  "6d 3b 5b 87 f6 7e a6 57 af 21 f7 54 41 97 7d 21 "
-  "80 f9 1b 2c 5f 69 2d e8 29 55 69 6a 68 67 30 d9 "
-  "b9 77 8d 97 07 58 cc b2 60 71 c2 20 9f fb d6 12 "
-  "5b e2 e9 6e a8 1b 67 cb 9b 93 08 23 9f da 17 f7 "
-  "b2 b6 4e cd a0 96 b6 b9 35 64 0a 5a 1c b4 2a 91 "
-  "55 b1 c9 ef 7a 63 3a 02 c5 9f 0d 6e e5 9b 85 2c "
-  "43 b3 50 29 e7 3c 94 0f f0 41 0e 8f 11 4e ed 46 "
-  "bb d0 fa e1 65 e4 2b e2 52 8a 40 1c 3b 28 fd 81 "
-  "8e f3 23 2d ca 9f 4d 2a 0f 51 66 ec 59 c4 23 96 "
-  "d6 c1 1d bc 12 15 a5 6f a1 71 69 db 95 75 34 3e "
-  "f3 4f 9d e3 2a 49 cd c3 17 49 22 f2 29 c2 3e 18 "
-  "e4 5d f9 35 31 19 ec 43 19 ce dc e7 a1 7c 64 08 "
-  "8c 1f 6f 52 be 29 63 41 00 b3 91 9d 38 f3 d1 ed "
-  "94 e6 89 1e 66 a7 3b 8f b8 49 f5 87 4d f5 94 59 "
-  "e2 98 c7 bb ce 2e ee 78 2a 19 5a a6 6f e2 d0 73 "
-  "2b 25 e5 95 f5 7d 3e 06 1b 1f c3 e4 06 3b f9 8f ";
-
-struct SignatureExample {
-  const char* message;
-  const char* salt;
-  const char* signature;
+// -----BEGIN RSA PRIVATE KEY-----
+// MIIEowIBAAKCAQEArg5NXFRQQ5QU7dcqqIjZwL4qy4AaJNSPfSPvXmFbK0hDXdp6
+// PdOZ2Wd+lQLZwb7ZQ2ZdqHVK3kZ2sVUlFmngIoEXNhVg+gW2zGPZ1YemwBMdZ/NW
+// V2xTX7Y3RrdR/kSccd9ByRTHKb+BCJ2XN5pHu91+LFchahW0lVPHz9DkBPUCThM2
+// I4ZosM3+AcO93RrrcbiQdpuY60Lfg9ZX7+1clM7zhiuOjWNY+FLN4+j4Ec8isiis
+// /V1LQyxRZ2t29kto47UJKu0Li7gUvEE1PS/nXBVgEqcSEBBKXa4ahsTqKWJAwvEH
+// xaH1t2qhVO1IHcf9FSv5k1T47H7XMLpO2OCPrwIDAQABAoIBAQCXA4exTOHa0Dcc
+// aGv1j87GAPimWX3VaKsaGzyKuZNdSTRR0MXwsI+yZa4Y4UFHbSuZ483s499SXPaM
+// Q2CLQs8ZgME/xmq+YojIavXL4wcVbUA9OY43CaCI0VLCQzmbj7HgxqCQMzvdh+8P
+// J5PUxUHpyHG5TNuL7EsiqG8bapT7ip2+IpKrKjr18gn3k0k9mLNJxK9Qr+CJphwo
+// eJgq0Kcjx3bfgDEpPzyvdd+J3e+jclOTYbk2HwJ0FVCrfgJedHFIWUytZoM5783g
+// knXzgDyKs65aUDjc/opidXp3WOqfNJUPSiofPYPdYQ26UI0vztL5MBkWCpl+d/55
+// BqxCdDlhAoGBANm90DFUca+7LdnDgj8mWtUIzr+XVzSD9tzOIpcjiPwEnxk8RHrM
+// aMHCAKZpbsnX/ikdc2I1OsirPgNFh1q30xgL7oCadzxlwfXnEM0Nff8RJKtN+yI6
+// +nRoOCDGCHBsaa2wyMYRbnanyRDLPIOP4eGQ6Hz/LQJBvhjRyTXlrUU/AoGBAMyj
+// ec1ySnlJ2S0JqPBCk14dRsEs/zStgFz1Wdmk7TMRBPUMyhWf8JwNrU5Ppm9biJMo
+// MKwkiFjzv/us4ne3wFRsTiKj4uiIwfji7/N2VpbEXSDGtonrX7hES4wQ/s+qr8XJ
+// 8ykHrZ9rPOY2lBhxOo+VYE3U6aspAY/qwK8WyumRAoGAMdl+/Iw0quLTkHNuMj75
+// tKQbkUl4sZE0x0B6Mtfz2J7GPeTKWMLLiPB9bZvdvWAx0//mFqnRF3f87orQfjhv
+// n6W7qL20ZqN1UHLiKc/Y9LhcCMwFnsSZ6mSh1P8Bl5t6ZkV+8bmz7H5lTe75n7Ul
+// JZsjXtqc11NtzgjZY/l9PckCgYAH6ZI+FVs30VkqWqNDlu9nxi4ELh84BDVgYsQ0
+// nCHnxZKxfusZZvPAtO6shnvi9mETf4xSO59iARq9OnQPOPWgzgc/Y6LUZuVJIE0y
+// 1rKGZdVL/SL1tjofP9TD96xCj1D4jtRuE7Ps5BKYvCeBwm8HOjldCQx357/9to/4
+// tSLnYQKBgG7STr94Slb3/BzzMxdMLCum1PH73/+IFxu1J0cXxYLP2zEhcSgqGIwm
+// aMgdu1L9eE6lJM99AWTEkpcUz8UFwNt+hZW+lZZpex77RMgRl9VCiwid1BNBSU/o
+// +lT1mlpDrPCNOge9n6Qvy5waBugB8uNS86w0UImYiKZr+8IQ4EdE
+// -----END RSA PRIVATE KEY-----
+const uint8_t kPSSPublicKey[] = {
+    0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
+    0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xae, 0x0e, 0x4d,
+    0x5c, 0x54, 0x50, 0x43, 0x94, 0x14, 0xed, 0xd7, 0x2a, 0xa8, 0x88, 0xd9,
+    0xc0, 0xbe, 0x2a, 0xcb, 0x80, 0x1a, 0x24, 0xd4, 0x8f, 0x7d, 0x23, 0xef,
+    0x5e, 0x61, 0x5b, 0x2b, 0x48, 0x43, 0x5d, 0xda, 0x7a, 0x3d, 0xd3, 0x99,
+    0xd9, 0x67, 0x7e, 0x95, 0x02, 0xd9, 0xc1, 0xbe, 0xd9, 0x43, 0x66, 0x5d,
+    0xa8, 0x75, 0x4a, 0xde, 0x46, 0x76, 0xb1, 0x55, 0x25, 0x16, 0x69, 0xe0,
+    0x22, 0x81, 0x17, 0x36, 0x15, 0x60, 0xfa, 0x05, 0xb6, 0xcc, 0x63, 0xd9,
+    0xd5, 0x87, 0xa6, 0xc0, 0x13, 0x1d, 0x67, 0xf3, 0x56, 0x57, 0x6c, 0x53,
+    0x5f, 0xb6, 0x37, 0x46, 0xb7, 0x51, 0xfe, 0x44, 0x9c, 0x71, 0xdf, 0x41,
+    0xc9, 0x14, 0xc7, 0x29, 0xbf, 0x81, 0x08, 0x9d, 0x97, 0x37, 0x9a, 0x47,
+    0xbb, 0xdd, 0x7e, 0x2c, 0x57, 0x21, 0x6a, 0x15, 0xb4, 0x95, 0x53, 0xc7,
+    0xcf, 0xd0, 0xe4, 0x04, 0xf5, 0x02, 0x4e, 0x13, 0x36, 0x23, 0x86, 0x68,
+    0xb0, 0xcd, 0xfe, 0x01, 0xc3, 0xbd, 0xdd, 0x1a, 0xeb, 0x71, 0xb8, 0x90,
+    0x76, 0x9b, 0x98, 0xeb, 0x42, 0xdf, 0x83, 0xd6, 0x57, 0xef, 0xed, 0x5c,
+    0x94, 0xce, 0xf3, 0x86, 0x2b, 0x8e, 0x8d, 0x63, 0x58, 0xf8, 0x52, 0xcd,
+    0xe3, 0xe8, 0xf8, 0x11, 0xcf, 0x22, 0xb2, 0x28, 0xac, 0xfd, 0x5d, 0x4b,
+    0x43, 0x2c, 0x51, 0x67, 0x6b, 0x76, 0xf6, 0x4b, 0x68, 0xe3, 0xb5, 0x09,
+    0x2a, 0xed, 0x0b, 0x8b, 0xb8, 0x14, 0xbc, 0x41, 0x35, 0x3d, 0x2f, 0xe7,
+    0x5c, 0x15, 0x60, 0x12, 0xa7, 0x12, 0x10, 0x10, 0x4a, 0x5d, 0xae, 0x1a,
+    0x86, 0xc4, 0xea, 0x29, 0x62, 0x40, 0xc2, 0xf1, 0x07, 0xc5, 0xa1, 0xf5,
+    0xb7, 0x6a, 0xa1, 0x54, 0xed, 0x48, 0x1d, 0xc7, 0xfd, 0x15, 0x2b, 0xf9,
+    0x93, 0x54, 0xf8, 0xec, 0x7e, 0xd7, 0x30, 0xba, 0x4e, 0xd8, 0xe0, 0x8f,
+    0xaf, 0x02, 0x03, 0x01, 0x00, 0x01,
 };
 
-struct PSSTestVector {
-  const char* modulus_n;
-  const char* public_exponent_e;
-  SignatureExample example[6];
+const uint8_t kPSSMessage[] = {
+    0x1e, 0x70, 0xbd, 0xeb, 0x24, 0xf2, 0x9d, 0x05, 0xc5, 0xb5,
+    0xf4, 0xca, 0xe6, 0x1d, 0x01, 0x97, 0x29, 0xf4, 0xe0, 0x7c,
+    0xfd, 0xcc, 0x97, 0x8d, 0xc2, 0xbb, 0x2d, 0x9b, 0x6b, 0x45,
+    0x06, 0xbd, 0x2c, 0x66, 0x10, 0x42, 0x73, 0x8d, 0x88, 0x9b,
+    0x18, 0xcc, 0xcb, 0x7e, 0x43, 0x23, 0x06, 0xe9, 0x8f, 0x8f,
 };
 
-static const PSSTestVector pss_test[] = {
-  {
-    rsa_modulus_n_1,
-    rsa_public_exponent_e_1,
-    {
-      { message_1_1, salt_1_1, signature_1_1 },
-      { message_1_2, salt_1_2, signature_1_2 },
-      { message_1_3, salt_1_3, signature_1_3 },
-      { message_1_4, salt_1_4, signature_1_4 },
-      { message_1_5, salt_1_5, signature_1_5 },
-      { message_1_6, salt_1_6, signature_1_6 },
-    }
-  },
-  {
-    rsa_modulus_n_9,
-    rsa_public_exponent_e_9,
-    {
-      { message_9_1, salt_9_1, signature_9_1 },
-      { message_9_2, salt_9_2, signature_9_2 },
-      { message_9_3, salt_9_3, signature_9_3 },
-      { message_9_4, salt_9_4, signature_9_4 },
-      { message_9_5, salt_9_5, signature_9_5 },
-      { message_9_6, salt_9_6, signature_9_6 },
-    }
-  },
-  {
-    rsa_modulus_n_10,
-    rsa_public_exponent_e_10,
-    {
-      { message_10_1, salt_10_1, signature_10_1 },
-      { message_10_2, salt_10_2, signature_10_2 },
-      { message_10_3, salt_10_3, signature_10_3 },
-      { message_10_4, salt_10_4, signature_10_4 },
-      { message_10_5, salt_10_5, signature_10_5 },
-      { message_10_6, salt_10_6, signature_10_6 },
-    }
-  },
+const uint8_t kPSSSignatureGood[] = {
+    0x12, 0xa7, 0x6d, 0x9e, 0x8a, 0xea, 0x28, 0xe0, 0x3f, 0x6f, 0x5a, 0xa4,
+    0x1b, 0x6a, 0x0a, 0x14, 0xba, 0xfa, 0x84, 0xf6, 0xb7, 0x3c, 0xc9, 0xd6,
+    0x84, 0xab, 0x1e, 0x77, 0x88, 0x53, 0x95, 0x43, 0x8e, 0x73, 0xe4, 0x21,
+    0xab, 0x69, 0xb2, 0x0c, 0x73, 0x4d, 0x98, 0x42, 0xbd, 0x65, 0xa2, 0x95,
+    0x0d, 0x76, 0xb2, 0xbd, 0xe5, 0x9a, 0x6e, 0x9f, 0x72, 0x7f, 0xdd, 0x1e,
+    0x9f, 0xda, 0xc8, 0x2e, 0xa3, 0xe6, 0x28, 0x03, 0x98, 0x5c, 0x13, 0xa7,
+    0x7d, 0x4e, 0xde, 0xea, 0x35, 0x1b, 0x35, 0x7e, 0xaa, 0x14, 0xf9, 0xfb,
+    0xac, 0x61, 0xd0, 0x44, 0x20, 0xd5, 0x52, 0x5b, 0x92, 0x8f, 0xe7, 0x37,
+    0xa2, 0x72, 0x7d, 0xe6, 0x0d, 0x81, 0x63, 0xcc, 0x0f, 0xbd, 0xde, 0x25,
+    0xe3, 0x3f, 0x89, 0x1b, 0x39, 0x64, 0xfa, 0x21, 0x1d, 0x0f, 0x9b, 0x8a,
+    0xc1, 0xad, 0x03, 0x49, 0x96, 0xff, 0x9f, 0x2d, 0x83, 0xee, 0x2d, 0x2a,
+    0x1e, 0xc5, 0x73, 0x9f, 0x5b, 0xde, 0xcb, 0xaf, 0x02, 0xbd, 0xc5, 0x9b,
+    0x78, 0xb9, 0x8e, 0x01, 0x75, 0x3c, 0xc9, 0x6e, 0x7d, 0x3e, 0x61, 0x62,
+    0xc4, 0x8c, 0x9e, 0x76, 0xed, 0x52, 0x5e, 0x80, 0x89, 0xa7, 0x75, 0x5e,
+    0xc6, 0x34, 0x97, 0x22, 0x40, 0xb5, 0x0c, 0x77, 0x09, 0x8c, 0xa8, 0xe9,
+    0xf6, 0x8d, 0xc0, 0x10, 0x78, 0x92, 0xa9, 0xc6, 0x68, 0xa3, 0x57, 0x6e,
+    0x73, 0xb5, 0x73, 0x8d, 0x8e, 0x21, 0xb1, 0xf3, 0xd0, 0x0a, 0x40, 0x68,
+    0xfc, 0x3c, 0xeb, 0xd3, 0x48, 0x4a, 0x44, 0xbd, 0xc0, 0x40, 0x5d, 0x9b,
+    0x40, 0x6f, 0x45, 0x98, 0x2b, 0xae, 0x58, 0xe8, 0x9d, 0x34, 0x49, 0xd2,
+    0xec, 0xdc, 0xd5, 0x98, 0xb4, 0x87, 0x8a, 0xcc, 0x41, 0x3e, 0xd7, 0xe6,
+    0x21, 0xd6, 0x4c, 0x89, 0xf1, 0xf4, 0x77, 0x40, 0x3f, 0x9a, 0x28, 0x25,
+    0x55, 0x7c, 0xf5, 0x0c,
 };
 
-static uint8_t HexDigitValue(char digit) {
-  if ('0' <= digit && digit <= '9')
-    return digit - '0';
-  if ('a' <= digit && digit <= 'f')
-    return digit - 'a' + 10;
-  return digit - 'A' + 10;
-}
+const uint8_t kPSSSignatureBadSaltLength[] = {
+    0x6e, 0x61, 0xbe, 0x8a, 0x82, 0xbd, 0xed, 0xc6, 0xe4, 0x33, 0x91, 0xa4,
+    0x43, 0x57, 0x51, 0x7e, 0xa8, 0x18, 0xbf, 0x20, 0x98, 0xbc, 0x04, 0x50,
+    0x06, 0x1b, 0x0b, 0xb6, 0x43, 0xde, 0x58, 0x7f, 0x6b, 0xa5, 0x5e, 0x9d,
+    0xd1, 0x75, 0x03, 0xf5, 0x19, 0x8d, 0xdb, 0x2c, 0xd2, 0x9a, 0xf9, 0xbd,
+    0x82, 0x8d, 0x32, 0x9d, 0x7d, 0x70, 0x6f, 0x81, 0x95, 0x60, 0x1d, 0x62,
+    0x72, 0xf3, 0x95, 0x5b, 0x7a, 0x66, 0x7f, 0x45, 0x94, 0x0c, 0x07, 0xc8,
+    0xa7, 0x64, 0x38, 0x57, 0x1a, 0x64, 0x64, 0xf1, 0xe0, 0x45, 0xfe, 0x00,
+    0x11, 0x90, 0x57, 0x95, 0x15, 0x21, 0x10, 0x85, 0xc0, 0xbe, 0x53, 0x5b,
+    0x3b, 0xa3, 0x57, 0x99, 0x2b, 0x94, 0x6b, 0xbf, 0xa5, 0x55, 0x7d, 0x5a,
+    0xcb, 0xa2, 0x73, 0x6b, 0x5f, 0x7b, 0x3f, 0x10, 0x90, 0xd1, 0x26, 0x72,
+    0x5e, 0xad, 0xd1, 0x34, 0xe8, 0x8a, 0x33, 0xeb, 0xd2, 0xbf, 0x54, 0x92,
+    0xeb, 0x7c, 0xb9, 0x97, 0x80, 0x5a, 0x46, 0xc4, 0xbd, 0xf5, 0x7e, 0xd6,
+    0x20, 0x90, 0x92, 0xcb, 0x37, 0x85, 0x9d, 0x81, 0x0a, 0xd0, 0xa5, 0x73,
+    0x17, 0x7e, 0xe2, 0x91, 0xef, 0x35, 0x55, 0xc9, 0x5e, 0x87, 0x84, 0x11,
+    0xa4, 0x36, 0xf0, 0x2a, 0xa7, 0x7a, 0x83, 0x1d, 0x7a, 0x90, 0x69, 0x22,
+    0x5d, 0x3b, 0x30, 0x48, 0x46, 0xd2, 0xd3, 0x49, 0x23, 0x64, 0xa4, 0x6d,
+    0xd1, 0xef, 0xb9, 0x1b, 0xa4, 0xd1, 0x92, 0xdd, 0x8c, 0xb2, 0xaa, 0x9f,
+    0x6a, 0x2c, 0xc9, 0xdb, 0xa7, 0x35, 0x66, 0x92, 0x8b, 0x73, 0x11, 0x70,
+    0x2b, 0xf4, 0x34, 0x3f, 0x9e, 0x15, 0x3e, 0xc0, 0xac, 0x78, 0x6f, 0x74,
+    0x8a, 0x6b, 0xe4, 0xf2, 0x7b, 0x10, 0xca, 0x01, 0x3a, 0x3a, 0x88, 0x39,
+    0x34, 0xa8, 0x52, 0x4a, 0x76, 0x50, 0xef, 0xdb, 0x91, 0x3c, 0x4a, 0x5c,
+    0xe5, 0x43, 0x6f, 0x8e,
+};
 
-static bool DecodeTestInput(const char* in, std::vector<uint8_t>* out) {
-  out->clear();
-  while (in[0] != '\0') {
-    if (!isxdigit(in[0]) || !isxdigit(in[1]) || in[2] != ' ')
-      return false;
-    uint8_t octet = HexDigitValue(in[0]) * 16 + HexDigitValue(in[1]);
-    out->push_back(octet);
-    in += 3;
-  }
-  return true;
-}
-
-// PrependASN1Length prepends an ASN.1 serialized length to the beginning of
-// |out|.
-static void PrependASN1Length(std::vector<uint8_t>* out, size_t len) {
-  if (len < 128) {
-    out->insert(out->begin(), static_cast<uint8_t>(len));
-  } else if (len < 256) {
-    out->insert(out->begin(), static_cast<uint8_t>(len));
-    out->insert(out->begin(), 0x81);
-  } else if (len < 0x10000) {
-    out->insert(out->begin(), static_cast<uint8_t>(len));
-    out->insert(out->begin(), static_cast<uint8_t>(len >> 8));
-    out->insert(out->begin(), 0x82);
-  } else {
-    CHECK(false) << "ASN.1 length not handled: " << len;
-  }
-}
-
-static bool EncodeRSAPublicKey(const std::vector<uint8_t>& modulus_n,
-                               const std::vector<uint8_t>& public_exponent_e,
-                               std::vector<uint8_t>* public_key_info) {
-  // The public key is specified as the following ASN.1 structure:
-  //   SubjectPublicKeyInfo  ::=  SEQUENCE  {
-  //       algorithm            AlgorithmIdentifier,
-  //       subjectPublicKey     BIT STRING  }
-  //
-  // The algorithm is specified as the following ASN.1 structure:
-  //    AlgorithmIdentifier  ::=  SEQUENCE  {
-  //        algorithm               OBJECT IDENTIFIER,
-  //        parameters              ANY DEFINED BY algorithm OPTIONAL  }
-  //
-  // An RSA public key is specified as the following ASN.1 structure:
-  //    RSAPublicKey ::= SEQUENCE {
-  //        modulus           INTEGER,  -- n
-  //        publicExponent    INTEGER   -- e
-  //    }
-  static const uint8_t kIntegerTag = 0x02;
-  static const uint8_t kBitStringTag = 0x03;
-  static const uint8_t kSequenceTag = 0x30;
-  public_key_info->clear();
-
-  // Encode the public exponent e as an INTEGER.
-  public_key_info->insert(public_key_info->begin(),
-                          public_exponent_e.begin(),
-                          public_exponent_e.end());
-  PrependASN1Length(public_key_info, public_exponent_e.size());
-  public_key_info->insert(public_key_info->begin(), kIntegerTag);
-
-  // Encode the modulus n as an INTEGER.
-  public_key_info->insert(public_key_info->begin(),
-                          modulus_n.begin(), modulus_n.end());
-  size_t modulus_size = modulus_n.size();
-  if (modulus_n[0] & 0x80) {
-    public_key_info->insert(public_key_info->begin(), 0x00);
-    modulus_size++;
-  }
-  PrependASN1Length(public_key_info, modulus_size);
-  public_key_info->insert(public_key_info->begin(), kIntegerTag);
-
-  // Encode the RSAPublicKey SEQUENCE.
-  PrependASN1Length(public_key_info, public_key_info->size());
-  public_key_info->insert(public_key_info->begin(), kSequenceTag);
-
-  // Encode the BIT STRING.
-  // Number of unused bits.
-  public_key_info->insert(public_key_info->begin(), 0x00);
-  PrependASN1Length(public_key_info, public_key_info->size());
-  public_key_info->insert(public_key_info->begin(), kBitStringTag);
-
-  // Encode the AlgorithmIdentifier.
-  static const uint8_t algorithm[] = {
-      0x30, 0x0d,  // a SEQUENCE of length 13
-      0x06, 0x09,  // an OBJECT IDENTIFIER of length 9
-      0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
-  };
-  public_key_info->insert(public_key_info->begin(),
-                          algorithm, algorithm + sizeof(algorithm));
-
-  // Encode the outermost SEQUENCE.
-  PrependASN1Length(public_key_info, public_key_info->size());
-  public_key_info->insert(public_key_info->begin(), kSequenceTag);
-
-  return true;
-}
+}  // namespace
 
 TEST(SignatureVerifierTest, VerifyRSAPSS) {
-  for (unsigned int i = 0; i < arraysize(pss_test); i++) {
-    SCOPED_TRACE(i);
-    std::vector<uint8_t> modulus_n;
-    std::vector<uint8_t> public_exponent_e;
-    ASSERT_TRUE(DecodeTestInput(pss_test[i].modulus_n, &modulus_n));
-    ASSERT_TRUE(DecodeTestInput(pss_test[i].public_exponent_e,
-                                &public_exponent_e));
-    std::vector<uint8_t> public_key_info;
-    ASSERT_TRUE(EncodeRSAPublicKey(modulus_n, public_exponent_e,
-                                   &public_key_info));
+  // Verify the test vector.
+  crypto::SignatureVerifier verifier;
+  ASSERT_TRUE(verifier.VerifyInit(crypto::SignatureVerifier::RSA_PSS_SHA256,
+                                  kPSSSignatureGood, sizeof(kPSSSignatureGood),
+                                  kPSSPublicKey, sizeof(kPSSPublicKey)));
+  verifier.VerifyUpdate(kPSSMessage, sizeof(kPSSMessage));
+  EXPECT_TRUE(verifier.VerifyFinal());
 
-    for (unsigned int j = 0; j < arraysize(pss_test[i].example); j++) {
-      SCOPED_TRACE(j);
-      std::vector<uint8_t> message;
-      std::vector<uint8_t> salt;
-      std::vector<uint8_t> signature;
-      ASSERT_TRUE(DecodeTestInput(pss_test[i].example[j].message, &message));
-      ASSERT_TRUE(DecodeTestInput(pss_test[i].example[j].salt, &salt));
-      ASSERT_TRUE(DecodeTestInput(pss_test[i].example[j].signature,
-                                  &signature));
-
-      crypto::SignatureVerifier verifier;
-      bool ok;
-
-      // Positive test.
-      ok = verifier.VerifyInitRSAPSS(crypto::SignatureVerifier::SHA1,
-                                     crypto::SignatureVerifier::SHA1,
-                                     salt.size(),
-                                     &signature[0], signature.size(),
-                                     &public_key_info[0],
-                                     public_key_info.size());
-      ASSERT_TRUE(ok);
-      verifier.VerifyUpdate(&message[0], message.size());
-      ok = verifier.VerifyFinal();
-      EXPECT_TRUE(ok);
-
-      // Modify the first byte of the message.
-      ok = verifier.VerifyInitRSAPSS(crypto::SignatureVerifier::SHA1,
-                                     crypto::SignatureVerifier::SHA1,
-                                     salt.size(),
-                                     &signature[0], signature.size(),
-                                     &public_key_info[0],
-                                     public_key_info.size());
-      ASSERT_TRUE(ok);
-      message[0] += 1;
-      verifier.VerifyUpdate(&message[0], message.size());
-      message[0] -= 1;
-      ok = verifier.VerifyFinal();
-      EXPECT_FALSE(ok);
-
-      // Truncate the message.
-      ASSERT_FALSE(message.empty());
-      ok = verifier.VerifyInitRSAPSS(crypto::SignatureVerifier::SHA1,
-                                     crypto::SignatureVerifier::SHA1,
-                                     salt.size(),
-                                     &signature[0], signature.size(),
-                                     &public_key_info[0],
-                                     public_key_info.size());
-      ASSERT_TRUE(ok);
-      verifier.VerifyUpdate(&message[0], message.size() - 1);
-      ok = verifier.VerifyFinal();
-      EXPECT_FALSE(ok);
-
-      // Corrupt the signature.
-      signature[0] += 1;
-      ok = verifier.VerifyInitRSAPSS(crypto::SignatureVerifier::SHA1,
-                                     crypto::SignatureVerifier::SHA1,
-                                     salt.size(),
-                                     &signature[0], signature.size(),
-                                     &public_key_info[0],
-                                     public_key_info.size());
-      signature[0] -= 1;
-      ASSERT_TRUE(ok);
-      verifier.VerifyUpdate(&message[0], message.size());
-      ok = verifier.VerifyFinal();
-      EXPECT_FALSE(ok);
-    }
+  // Verify the test vector byte-by-byte.
+  ASSERT_TRUE(verifier.VerifyInit(crypto::SignatureVerifier::RSA_PSS_SHA256,
+                                  kPSSSignatureGood, sizeof(kPSSSignatureGood),
+                                  kPSSPublicKey, sizeof(kPSSPublicKey)));
+  for (uint8_t b : kPSSMessage) {
+    verifier.VerifyUpdate(&b, 1);
   }
+  EXPECT_TRUE(verifier.VerifyFinal());
+
+  // The bad salt length does not verify.
+  ASSERT_TRUE(verifier.VerifyInit(crypto::SignatureVerifier::RSA_PSS_SHA256,
+                                  kPSSSignatureBadSaltLength,
+                                  sizeof(kPSSSignatureBadSaltLength),
+                                  kPSSPublicKey, sizeof(kPSSPublicKey)));
+  verifier.VerifyUpdate(kPSSMessage, sizeof(kPSSMessage));
+  EXPECT_FALSE(verifier.VerifyFinal());
+
+  // Corrupt the message.
+  std::vector<uint8_t> message(std::begin(kPSSMessage), std::end(kPSSMessage));
+  message[0] ^= 1;
+  ASSERT_TRUE(verifier.VerifyInit(crypto::SignatureVerifier::RSA_PSS_SHA256,
+                                  kPSSSignatureGood, sizeof(kPSSSignatureGood),
+                                  kPSSPublicKey, sizeof(kPSSPublicKey)));
+  verifier.VerifyUpdate(message.data(), message.size());
+  EXPECT_FALSE(verifier.VerifyFinal());
+
+  // Corrupt the signature.
+  std::vector<uint8_t> signature(std::begin(kPSSSignatureGood),
+                                 std::end(kPSSSignatureGood));
+  signature[0] ^= 1;
+  ASSERT_TRUE(verifier.VerifyInit(crypto::SignatureVerifier::RSA_PSS_SHA256,
+                                  signature.data(), signature.size(),
+                                  kPSSPublicKey, sizeof(kPSSPublicKey)));
+  verifier.VerifyUpdate(kPSSMessage, sizeof(kPSSMessage));
+  EXPECT_FALSE(verifier.VerifyFinal());
 }
diff --git a/extensions/browser/api/feedback_private/feedback_private_api_chromeos_unittest.cc b/extensions/browser/api/feedback_private/feedback_private_api_chromeos_unittest.cc
index fe7f2d3..ef44cf6 100644
--- a/extensions/browser/api/feedback_private/feedback_private_api_chromeos_unittest.cc
+++ b/extensions/browser/api/feedback_private/feedback_private_api_chromeos_unittest.cc
@@ -281,6 +281,7 @@
 
 TEST_F(FeedbackPrivateApiUnittest, ReadLogSourceWithAccessTimeouts) {
   const TimeDelta timeout(TimeDelta::FromMilliseconds(100));
+  LogSourceAccessManager::SetMaxNumBurstAccessesForTesting(1);
   LogSourceAccessManager::SetRateLimitingTimeoutForTesting(&timeout);
 
   base::SimpleTestTickClock* test_clock = new base::SimpleTestTickClock;
diff --git a/extensions/browser/api/feedback_private/log_source_access_manager.cc b/extensions/browser/api/feedback_private/log_source_access_manager.cc
index e709b041..e1e9bb9 100644
--- a/extensions/browser/api/feedback_private/log_source_access_manager.cc
+++ b/extensions/browser/api/feedback_private/log_source_access_manager.cc
@@ -27,11 +27,18 @@
 using ReadLogSourceResult = api::feedback_private::ReadLogSourceResult;
 using SystemLogsResponse = system_logs::SystemLogsResponse;
 
+// Default value of |g_max_num_burst_accesses|.
+constexpr int kDefaultMaxNumBurstAccesses = 10;
+
 // The minimum time between consecutive reads of a log source by a particular
 // extension.
 constexpr base::TimeDelta kDefaultRateLimitingTimeout =
     base::TimeDelta::FromMilliseconds(1000);
 
+// The maximum number of accesses on a single log source that can be allowed
+// before the next recharge increment. See access_rate_limiter.h for more info.
+int g_max_num_burst_accesses = kDefaultMaxNumBurstAccesses;
+
 // If this is null, then |kDefaultRateLimitingTimeoutMs| is used as the timeout.
 const base::TimeDelta* g_rate_limiting_timeout = nullptr;
 
@@ -81,6 +88,12 @@
 LogSourceAccessManager::~LogSourceAccessManager() {}
 
 // static
+void LogSourceAccessManager::SetMaxNumBurstAccessesForTesting(
+    int num_accesses) {
+  g_max_num_burst_accesses = num_accesses;
+}
+
+// static
 void LogSourceAccessManager::SetRateLimitingTimeoutForTesting(
     const base::TimeDelta* timeout) {
   g_rate_limiting_timeout = timeout;
@@ -228,7 +241,8 @@
   const SourceAndExtension& key = *iter->second;
   if (rate_limiters_.find(key) == rate_limiters_.end()) {
     rate_limiters_.emplace(
-        key, std::make_unique<AccessRateLimiter>(1, GetMinTimeBetweenReads(),
+        key, std::make_unique<AccessRateLimiter>(g_max_num_burst_accesses,
+                                                 GetMinTimeBetweenReads(),
                                                  tick_clock_.get()));
   }
   return rate_limiters_[key]->AttemptAccess();
diff --git a/extensions/browser/api/feedback_private/log_source_access_manager.h b/extensions/browser/api/feedback_private/log_source_access_manager.h
index 1b883362..6315907 100644
--- a/extensions/browser/api/feedback_private/log_source_access_manager.h
+++ b/extensions/browser/api/feedback_private/log_source_access_manager.h
@@ -36,6 +36,9 @@
   explicit LogSourceAccessManager(content::BrowserContext* context);
   ~LogSourceAccessManager();
 
+  // Call this to override the maximum burst access count of the rate limiter.
+  static void SetMaxNumBurstAccessesForTesting(int num_accesses);
+
   // To override the default rate-limiting mechanism of this function, pass in
   // a TimeDelta representing the desired minimum time between consecutive reads
   // of a source from an extension. Does not take ownership of |timeout|. When
diff --git a/extensions/browser/api/media_perception_private/media_perception_api_manager.cc b/extensions/browser/api/media_perception_private/media_perception_api_manager.cc
index 591f0751..59c29e4 100644
--- a/extensions/browser/api/media_perception_private/media_perception_api_manager.cc
+++ b/extensions/browser/api/media_perception_private/media_perception_api_manager.cc
@@ -4,6 +4,10 @@
 
 #include "extensions/browser/api/media_perception_private/media_perception_api_manager.h"
 
+#include <memory>
+#include <utility>
+#include <vector>
+
 #include "base/files/file_path.h"
 #include "base/lazy_instance.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -290,28 +294,26 @@
   GetState(callback);
 }
 
-void MediaPerceptionAPIManager::StateCallback(const APIStateCallback& callback,
-                                              bool succeeded,
-                                              const mri::State& state_proto) {
-  media_perception::State state;
-  if (!succeeded) {
+void MediaPerceptionAPIManager::StateCallback(
+    const APIStateCallback& callback,
+    base::Optional<mri::State> result) {
+  if (!result.has_value()) {
     callback.Run(GetStateForServiceError(
         media_perception::SERVICE_ERROR_SERVICE_UNREACHABLE));
     return;
   }
-  callback.Run(media_perception::StateProtoToIdl(state_proto));
+  callback.Run(media_perception::StateProtoToIdl(result.value()));
 }
 
 void MediaPerceptionAPIManager::GetDiagnosticsCallback(
     const APIGetDiagnosticsCallback& callback,
-    bool succeeded,
-    const mri::Diagnostics& diagnostics_proto) {
-  if (!succeeded) {
+    base::Optional<mri::Diagnostics> result) {
+  if (!result.has_value()) {
     callback.Run(GetDiagnosticsForServiceError(
         media_perception::SERVICE_ERROR_SERVICE_UNREACHABLE));
     return;
   }
-  callback.Run(media_perception::DiagnosticsProtoToIdl(diagnostics_proto));
+  callback.Run(media_perception::DiagnosticsProtoToIdl(result.value()));
 }
 
 void MediaPerceptionAPIManager::MediaPerceptionSignalHandler(
diff --git a/extensions/browser/api/media_perception_private/media_perception_api_manager.h b/extensions/browser/api/media_perception_private/media_perception_api_manager.h
index b4fda310..4f72ce3 100644
--- a/extensions/browser/api/media_perception_private/media_perception_api_manager.h
+++ b/extensions/browser/api/media_perception_private/media_perception_api_manager.h
@@ -5,7 +5,10 @@
 #ifndef EXTENSIONS_BROWSER_API_MEDIA_PERCEPTION_PRIVATE_MEDIA_PERCEPTION_API_MANAGER_H_
 #define EXTENSIONS_BROWSER_API_MEDIA_PERCEPTION_PRIVATE_MEDIA_PERCEPTION_API_MANAGER_H_
 
+#include <string>
+
 #include "base/memory/weak_ptr.h"
+#include "base/optional.h"
 #include "chromeos/media_perception/media_perception.pb.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
 #include "extensions/common/api/media_perception_private.h"
@@ -73,14 +76,12 @@
 
   // Callback for State D-Bus method calls to the media analytics process.
   void StateCallback(const APIStateCallback& callback,
-                     bool succeeded,
-                     const mri::State& state);
+                     base::Optional<mri::State> state);
 
   // Callback for GetDiagnostics D-Bus method calls to the media analytics
   // process.
   void GetDiagnosticsCallback(const APIGetDiagnosticsCallback& callback,
-                              bool succeeded,
-                              const mri::Diagnostics& diagnostics);
+                              base::Optional<mri::Diagnostics> diagnostics);
 
   // Callback for Upstart command to start media analytics process.
   void UpstartStartCallback(const APIStateCallback& callback,
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc
index f7e112bb..964cde2 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest.cc
+++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -631,11 +631,6 @@
                                                        std::move(args)));
 }
 
-void WebViewGuest::SetContextMenuPosition(const gfx::Point& position) {
-  if (web_view_guest_delegate_)
-    web_view_guest_delegate_->SetContextMenuPosition(position);
-}
-
 void WebViewGuest::CreateNewGuestWebViewWindow(
     const content::OpenURLParams& params) {
   GuestViewManager* guest_manager =
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.h b/extensions/browser/guest_view/web_view/web_view_guest.h
index c1c25e6..3abab36 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest.h
+++ b/extensions/browser/guest_view/web_view/web_view_guest.h
@@ -193,7 +193,6 @@
   void GuestViewDidStopLoading() final;
   void GuestZoomChanged(double old_zoom_level, double new_zoom_level) final;
   bool IsAutoSizeSupported() const final;
-  void SetContextMenuPosition(const gfx::Point& position) final;
   void SignalWhenReady(const base::Closure& callback) final;
   void WillAttachToEmbedder() final;
   void WillDestroy() final;
diff --git a/extensions/browser/guest_view/web_view/web_view_guest_delegate.h b/extensions/browser/guest_view/web_view/web_view_guest_delegate.h
index 8abb15f..b9a33b02 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest_delegate.h
+++ b/extensions/browser/guest_view/web_view/web_view_guest_delegate.h
@@ -24,8 +24,6 @@
   // Returns true if the WebViewGuest should handle find requests for its
   // embedder.
   virtual bool ShouldHandleFindRequestsForEmbedder() const = 0;
-
-  virtual void SetContextMenuPosition(const gfx::Point& position) = 0;
 };
 
 }  // namespace extensions
diff --git a/gpu/command_buffer/client/raster_implementation_gles.cc b/gpu/command_buffer/client/raster_implementation_gles.cc
index f1b525d..830add1b 100644
--- a/gpu/command_buffer/client/raster_implementation_gles.cc
+++ b/gpu/command_buffer/client/raster_implementation_gles.cc
@@ -404,15 +404,18 @@
                            can_use_lcd_text, use_distance_field_text,
                            color_type, raster_color_space.color_space_id);
   transfer_cache_serialize_helper.FlushEntries();
+  background_color_ = sk_color;
 };
 
 void RasterImplementationGLES::RasterCHROMIUM(
     const cc::DisplayItemList* list,
     cc::ImageProvider* provider,
-    const gfx::Vector2d& translate,
+    const gfx::Size& content_size,
+    const gfx::Rect& full_raster_rect,
     const gfx::Rect& playback_rect,
     const gfx::Vector2dF& post_translate,
-    GLfloat post_scale) {
+    GLfloat post_scale,
+    bool requires_clear) {
   if (std::abs(post_scale) < std::numeric_limits<float>::epsilon())
     return;
 
@@ -430,10 +433,13 @@
 
   // This section duplicates RasterSource::PlaybackToCanvas setup preamble.
   cc::PaintOpBufferSerializer::Preamble preamble;
-  preamble.translation = translate;
-  preamble.playback_rect = gfx::RectF(playback_rect);
+  preamble.content_size = content_size;
+  preamble.full_raster_rect = full_raster_rect;
+  preamble.playback_rect = playback_rect;
   preamble.post_translation = post_translate;
   preamble.post_scale = gfx::SizeF(post_scale, post_scale);
+  preamble.requires_clear = requires_clear;
+  preamble.background_color = background_color_;
 
   // Wrap the provided provider in a stashing provider so that we can delay
   // unrefing images until we have serialized dependent commands.
diff --git a/gpu/command_buffer/client/raster_implementation_gles.h b/gpu/command_buffer/client/raster_implementation_gles.h
index c651e6dc..ce127bf 100644
--- a/gpu/command_buffer/client/raster_implementation_gles.h
+++ b/gpu/command_buffer/client/raster_implementation_gles.h
@@ -10,6 +10,7 @@
 #include "gpu/command_buffer/client/raster_interface.h"
 #include "gpu/command_buffer/common/capabilities.h"
 #include "gpu/raster_export.h"
+#include "third_party/skia/include/core/SkColor.h"
 
 namespace gpu {
 
@@ -142,10 +143,12 @@
       const cc::RasterColorSpace& raster_color_space) override;
   void RasterCHROMIUM(const cc::DisplayItemList* list,
                       cc::ImageProvider* provider,
-                      const gfx::Vector2d& translate,
+                      const gfx::Size& content_size,
+                      const gfx::Rect& full_raster_rect,
                       const gfx::Rect& playback_rect,
                       const gfx::Vector2dF& post_translate,
-                      GLfloat post_scale) override;
+                      GLfloat post_scale,
+                      bool requires_clear) override;
   void EndRasterCHROMIUM() override;
 
   // Raster via GrContext.
@@ -154,6 +157,7 @@
 
  private:
   gles2::GLES2Interface* gl_;
+  SkColor background_color_;
   ContextSupport* support_;
   bool use_texture_storage_;
   bool use_texture_storage_image_;
diff --git a/gpu/command_buffer/client/raster_implementation_gles_unittest.cc b/gpu/command_buffer/client/raster_implementation_gles_unittest.cc
index 09c7e2e..b2bff23 100644
--- a/gpu/command_buffer/client/raster_implementation_gles_unittest.cc
+++ b/gpu/command_buffer/client/raster_implementation_gles_unittest.cc
@@ -693,10 +693,12 @@
   display_list->Finalize();
 
   ImageProviderStub image_provider;
-  const gfx::Vector2d translate(1, 2);
+  const gfx::Size content_size(100, 200);
+  const gfx::Rect full_raster_rect(2, 3, 8, 9);
   const gfx::Rect playback_rect(3, 4, 5, 6);
   const gfx::Vector2dF post_translate(7.0f, 8.0f);
   const GLfloat post_scale = 9.0f;
+  bool requires_clear = false;
 
   constexpr const GLsizeiptr kBufferSize = 16 << 10;
   char buffer[kBufferSize];
@@ -704,8 +706,10 @@
   EXPECT_CALL(*gl_, MapRasterCHROMIUM(Le(kBufferSize)))
       .WillOnce(Return(buffer));
   EXPECT_CALL(*gl_, UnmapRasterCHROMIUM(Gt(0))).Times(1);
-  ri_->RasterCHROMIUM(display_list.get(), &image_provider, translate,
-                      playback_rect, post_translate, post_scale);
+
+  ri_->RasterCHROMIUM(display_list.get(), &image_provider, content_size,
+                      full_raster_rect, playback_rect, post_translate,
+                      post_scale, requires_clear);
 }
 
 TEST_F(RasterImplementationGLESTest, EndRasterCHROMIUM) {
diff --git a/gpu/command_buffer/client/raster_interface.h b/gpu/command_buffer/client/raster_interface.h
index d787489..530e177 100644
--- a/gpu/command_buffer/client/raster_interface.h
+++ b/gpu/command_buffer/client/raster_interface.h
@@ -17,7 +17,7 @@
 
 namespace gfx {
 class Rect;
-class Vector2d;
+class Size;
 class Vector2dF;
 }  // namespace gfx
 
@@ -109,10 +109,12 @@
       const cc::RasterColorSpace& raster_color_space) = 0;
   virtual void RasterCHROMIUM(const cc::DisplayItemList* list,
                               cc::ImageProvider* provider,
-                              const gfx::Vector2d& translate,
+                              const gfx::Size& content_size,
+                              const gfx::Rect& full_raster_rect,
                               const gfx::Rect& playback_rect,
                               const gfx::Vector2dF& post_translate,
-                              GLfloat post_scale) = 0;
+                              GLfloat post_scale,
+                              bool requires_clear) = 0;
 
   // Raster via GrContext.
   virtual void BeginGpuRaster() = 0;
diff --git a/ios/chrome/browser/ui/main_content/main_content_ui_state.h b/ios/chrome/browser/ui/main_content/main_content_ui_state.h
index e5cf9765..f789265 100644
--- a/ios/chrome/browser/ui/main_content/main_content_ui_state.h
+++ b/ios/chrome/browser/ui/main_content/main_content_ui_state.h
@@ -45,6 +45,9 @@
                            residualVelocity:(CGPoint)velocity;
 // Called when the scroll view stops decelerating.
 - (void)scrollViewDidEndDecelerating;
+// Called when a scroll event is interrupted (i.e. when a navigation occurs mid-
+// scroll).
+- (void)scrollWasInterrupted;
 
 @end
 
diff --git a/ios/chrome/browser/ui/main_content/main_content_ui_state.mm b/ios/chrome/browser/ui/main_content/main_content_ui_state.mm
index 311c1b0..a25607d 100644
--- a/ios/chrome/browser/ui/main_content/main_content_ui_state.mm
+++ b/ios/chrome/browser/ui/main_content/main_content_ui_state.mm
@@ -110,4 +110,10 @@
   self.state.decelerating = NO;
 }
 
+- (void)scrollWasInterrupted {
+  self.state.scrolling = NO;
+  self.state.dragging = NO;
+  self.state.decelerating = NO;
+}
+
 @end
diff --git a/ios/chrome/browser/ui/main_content/web_scroll_view_main_content_ui_forwarder.mm b/ios/chrome/browser/ui/main_content/web_scroll_view_main_content_ui_forwarder.mm
index a357b17c..73561a26 100644
--- a/ios/chrome/browser/ui/main_content/web_scroll_view_main_content_ui_forwarder.mm
+++ b/ios/chrome/browser/ui/main_content/web_scroll_view_main_content_ui_forwarder.mm
@@ -13,16 +13,19 @@
 #import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
 #import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h"
 #import "ios/web/public/web_state/web_state.h"
+#import "ios/web/public/web_state/web_state_observer_bridge.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
 @interface WebScrollViewMainContentUIForwarder ()<
+    CRWWebStateObserver,
     CRWWebViewScrollViewProxyObserver,
     WebStateListObserving> {
-  // The observer bridge.
-  std::unique_ptr<WebStateListObserver> _bridge;
+  // The observer bridges.
+  std::unique_ptr<WebStateListObserver> _webStateListBridge;
+  std::unique_ptr<web::WebStateObserver> _webStateBridge;
 }
 
 // The updater being driven by this object.
@@ -48,11 +51,13 @@
     DCHECK(_updater);
     _webStateList = webStateList;
     DCHECK(_webStateList);
-    _bridge = std::make_unique<WebStateListObserverBridge>(self);
-    _webStateList->AddObserver(_bridge.get());
+    _webStateBridge = std::make_unique<web::WebStateObserverBridge>(self);
+    _webStateListBridge = std::make_unique<WebStateListObserverBridge>(self);
+    _webStateList->AddObserver(_webStateListBridge.get());
     web::WebState* activeWebState = webStateList->GetActiveWebState();
     if (activeWebState) {
       _webState = activeWebState;
+      _webState->AddObserver(_webStateBridge.get());
       _proxy = activeWebState->GetWebViewProxy().scrollViewProxy;
       [_proxy addObserver:self];
     }
@@ -62,7 +67,8 @@
 
 - (void)dealloc {
   // |-disconnect| must be called before deallocation.
-  DCHECK(!_bridge);
+  DCHECK(!_webStateListBridge);
+  DCHECK(!_webStateBridge);
   DCHECK(!_webState);
   DCHECK(!_proxy);
 }
@@ -72,7 +78,11 @@
 - (void)setWebState:(web::WebState*)webState {
   if (_webState == webState)
     return;
+  if (_webState)
+    _webState->RemoveObserver(_webStateBridge.get());
   _webState = webState;
+  if (_webState)
+    _webState->AddObserver(_webStateBridge.get());
   self.proxy =
       _webState ? _webState->GetWebViewProxy().scrollViewProxy : nullptr;
 }
@@ -88,9 +98,17 @@
 #pragma mark Public
 
 - (void)disconnect {
-  self.webStateList->RemoveObserver(_bridge.get());
-  _bridge = nullptr;
+  self.webStateList->RemoveObserver(_webStateListBridge.get());
+  _webStateListBridge = nullptr;
   self.webState = nullptr;
+  _webStateBridge = nullptr;
+}
+
+#pragma mark CRWWebStateObserver
+
+- (void)webState:(web::WebState*)webState
+    didFinishNavigation:(web::NavigationContext*)navigation {
+  [self.updater scrollWasInterrupted];
 }
 
 #pragma mark CRWWebViewScrollViewObserver
diff --git a/ios/chrome/browser/ui/ntp/incognito_view.mm b/ios/chrome/browser/ui/ntp/incognito_view.mm
index 56efe079..b60a8f2 100644
--- a/ios/chrome/browser/ui/ntp/incognito_view.mm
+++ b/ios/chrome/browser/ui/ntp/incognito_view.mm
@@ -35,12 +35,20 @@
   return google_util::AppendGoogleLocaleParam(url, locale);
 }
 
+const CGFloat kStackViewHorizontalMargin = 24.0;
+const CGFloat kStackViewMaxWidth = 416.0;
+const CGFloat kStackViewDefaultSpacing = 32.0;
+const CGFloat kStackViewImageSpacing = 24.0;
+const CGFloat kLayoutGuideVerticalMargin = 8.0;
+const CGFloat kLayoutGuideMinHeight = 12.0;
+
 const int kLinkColor = 0x03A9F4;
 }  // namespace
 
 @implementation IncognitoView {
   __weak id<UrlLoader> _loader;
   UIView* _containerView;
+  UIStackView* _stackView;
 
   // Constraint ensuring that |containerView| is at least as high as the
   // superview of the IncognitoNTPView, i.e. the Incognito panel.
@@ -61,15 +69,28 @@
 
     self.alwaysBounceVertical = YES;
 
-    // Container in which all the subviews (image, labels, button) are added.
+    // Container to hold and vertically position the stack view.
     _containerView = [[UIView alloc] initWithFrame:frame];
     [_containerView setTranslatesAutoresizingMaskIntoConstraints:NO];
 
+    // Stackview in which all the subviews (image, labels, button) are added.
+    _stackView = [[UIStackView alloc] init];
+    [_stackView setTranslatesAutoresizingMaskIntoConstraints:NO];
+    _stackView.axis = UILayoutConstraintAxisVertical;
+    _stackView.spacing = kStackViewDefaultSpacing;
+    _stackView.distribution = UIStackViewDistributionFill;
+    _stackView.alignment = UIStackViewAlignmentCenter;
+    [_containerView addSubview:_stackView];
+
     // Incognito image.
     UIImageView* incognitoImage = [[UIImageView alloc]
         initWithImage:[UIImage imageNamed:@"incognito_icon"]];
     [incognitoImage setTranslatesAutoresizingMaskIntoConstraints:NO];
-    [_containerView addSubview:incognitoImage];
+    [_stackView addArrangedSubview:incognitoImage];
+    if (@available(iOS 11.0, *)) {
+      [_stackView setCustomSpacing:kStackViewImageSpacing
+                         afterView:incognitoImage];
+    }
 
     // Title.
     UIFont* titleFont = [[MDCTypography fontLoader] lightFontOfSize:24];
@@ -77,7 +98,7 @@
         [self labelWithString:l10n_util::GetNSString(IDS_NEW_TAB_OTR_HEADING)
                          font:titleFont
                         alpha:0.8];
-    [_containerView addSubview:incognitoTabHeading];
+    [_stackView addArrangedSubview:incognitoTabHeading];
 
     // Description paragraph.
     UIFont* regularFont = [[MDCTypography fontLoader] regularFontOfSize:14];
@@ -85,14 +106,14 @@
         labelWithString:l10n_util::GetNSString(IDS_NEW_TAB_OTR_DESCRIPTION)
                    font:regularFont
                   alpha:0.7];
-    [_containerView addSubview:incognitoTabDescription];
+    [_stackView addArrangedSubview:incognitoTabDescription];
 
     // Warning paragraph.
     UILabel* incognitoTabWarning = [self
         labelWithString:l10n_util::GetNSString(IDS_NEW_TAB_OTR_MESSAGE_WARNING)
                    font:regularFont
                   alpha:0.7];
-    [_containerView addSubview:incognitoTabWarning];
+    [_stackView addArrangedSubview:incognitoTabWarning];
 
     // Learn more button.
     MDCButton* learnMore = [[MDCFlatButton alloc] init];
@@ -111,59 +132,55 @@
     [learnMore addTarget:self
                   action:@selector(learnMoreButtonPressed)
         forControlEvents:UIControlEventTouchUpInside];
-    [_containerView addSubview:learnMore];
+    [_stackView addArrangedSubview:learnMore];
 
-    // |topGuide| and |bottomGuide| exist to vertically center the sibling views
-    // located in between them.
+    // |topGuide| and |bottomGuide| exist to vertically position the stackview
+    // inside the container scrollview.
     UILayoutGuide* topGuide = [[UILayoutGuide alloc] init];
     UILayoutGuide* bottomGuide = [[UILayoutGuide alloc] init];
     [_containerView addLayoutGuide:topGuide];
     [_containerView addLayoutGuide:bottomGuide];
 
-    NSDictionary* viewsDictionary = @{
-      @"topGuide" : topGuide,
-      @"image" : incognitoImage,
-      @"heading" : incognitoTabHeading,
-      @"description" : incognitoTabDescription,
-      @"warning" : incognitoTabWarning,
-      @"learnMoreButton" : learnMore,
-      @"bottomGuide" : bottomGuide,
-    };
-    NSArray* constraints = @[
-      @"V:|-0-[topGuide(>=12)]-[image]-24-[heading]-32-[description]",
-      @"V:[description]-32-[warning]-32-[learnMoreButton]",
-      @"V:[learnMoreButton]-[bottomGuide]-0-|",
-      @"H:|-(>=24)-[heading]-(>=24)-|",
-      @"H:|-(>=24)-[description(==416@999)]-(>=24)-|",
-      @"H:|-(>=24)-[warning(==416@999)]-(>=24)-|"
-    ];
-    ApplyVisualConstraintsWithOptions(constraints, viewsDictionary,
-                                      LayoutOptionForRTLSupport(),
-                                      _containerView);
+    [NSLayoutConstraint activateConstraints:@[
+      // Position the stackview between the two guides.
+      [topGuide.topAnchor constraintEqualToAnchor:_containerView.topAnchor],
+      [_stackView.topAnchor constraintEqualToAnchor:topGuide.bottomAnchor
+                                           constant:kLayoutGuideVerticalMargin],
+      [bottomGuide.topAnchor
+          constraintEqualToAnchor:_stackView.bottomAnchor
+                         constant:kLayoutGuideVerticalMargin],
+      [_containerView.bottomAnchor
+          constraintEqualToAnchor:bottomGuide.bottomAnchor],
 
-    AddSameCenterXConstraint(_containerView, incognitoImage);
-    AddSameCenterXConstraint(_containerView, incognitoTabHeading);
-    AddSameCenterXConstraint(_containerView, incognitoTabDescription);
-    AddSameCenterXConstraint(_containerView, incognitoTabWarning);
-    AddSameCenterXConstraint(_containerView, learnMore);
+      // Center the stackview horizontally with a minimum margin.
+      [_stackView.leadingAnchor
+          constraintGreaterThanOrEqualToAnchor:_containerView.leadingAnchor
+                                      constant:kStackViewHorizontalMargin],
+      [_stackView.trailingAnchor
+          constraintLessThanOrEqualToAnchor:_containerView.trailingAnchor
+                                   constant:-kStackViewHorizontalMargin],
+      [_stackView.centerXAnchor
+          constraintEqualToAnchor:_containerView.centerXAnchor],
 
-    // The bottom guide is twice as big as the top guide.
-    [_containerView addConstraint:[NSLayoutConstraint
-                                      constraintWithItem:bottomGuide
-                                               attribute:NSLayoutAttributeHeight
-                                               relatedBy:NSLayoutRelationEqual
-                                                  toItem:topGuide
-                                               attribute:NSLayoutAttributeHeight
-                                              multiplier:2
-                                                constant:0]];
+      // Ensure that the stackview width is constrained.
+      [_stackView.widthAnchor
+          constraintLessThanOrEqualToConstant:kStackViewMaxWidth],
+
+      // Set a minimum top margin and make the bottom guide twice as tall as the
+      // top guide.
+      [topGuide.heightAnchor
+          constraintGreaterThanOrEqualToConstant:kLayoutGuideMinHeight],
+      [bottomGuide.heightAnchor constraintEqualToAnchor:topGuide.heightAnchor
+                                             multiplier:2.0],
+    ]];
 
     [self addSubview:_containerView];
 
     // Constraints comunicating the size of the contentView to the scrollview.
     // See UIScrollView autolayout information at
     // https://developer.apple.com/library/ios/releasenotes/General/RN-iOSSDK-6_0/index.html
-    viewsDictionary = @{@"containerView" : _containerView};
-    constraints = @[
+    NSDictionary* viewsDictionary = @{@"containerView" : _containerView};
+    NSArray* constraints = @[
       @"V:|-0-[containerView]-0-|",
       @"H:|-0-[containerView]-0-|",
     ];
diff --git a/ipc/ipc_mojo_bootstrap.cc b/ipc/ipc_mojo_bootstrap.cc
index 8248b60..6b0fd3b 100644
--- a/ipc/ipc_mojo_bootstrap.cc
+++ b/ipc/ipc_mojo_bootstrap.cc
@@ -123,9 +123,11 @@
 
   void ShutDown() {
     DCHECK(thread_checker_.CalledOnValidThread());
+    shut_down_ = true;
     connector_->CloseMessagePipe();
     OnPipeError();
     connector_.reset();
+    outgoing_messages_.clear();
   }
 
   // mojo::AssociatedGroupController:
@@ -585,7 +587,8 @@
     if (task_runner_->BelongsToCurrentThread()) {
       DCHECK(thread_checker_.CalledOnValidThread());
       if (!connector_ || paused_) {
-        outgoing_messages_.emplace_back(std::move(*message));
+        if (!shut_down_)
+          outgoing_messages_.emplace_back(std::move(*message));
         return true;
       }
       return connector_->Accept(message);
@@ -869,6 +872,7 @@
   base::Lock lock_;
 
   bool encountered_error_ = false;
+  bool shut_down_ = false;
 
   // ID #1 is reserved for the mojom::Channel interface.
   uint32_t next_interface_id_ = 2;
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn
index 6098fa4..c433e86f 100644
--- a/media/audio/BUILD.gn
+++ b/media/audio/BUILD.gn
@@ -345,6 +345,8 @@
     "audio_system_test_util.h",
     "audio_unittest_util.cc",
     "audio_unittest_util.h",
+    "mock_audio_debug_recording_manager.cc",
+    "mock_audio_debug_recording_manager.h",
     "mock_audio_manager.cc",
     "mock_audio_manager.h",
     "mock_audio_source_callback.cc",
diff --git a/media/audio/audio_debug_file_writer.cc b/media/audio/audio_debug_file_writer.cc
index 564da92..9143a88 100644
--- a/media/audio/audio_debug_file_writer.cc
+++ b/media/audio/audio_debug_file_writer.cc
@@ -304,7 +304,7 @@
   return !!file_writer_;
 }
 
-const base::FilePath::CharType* AudioDebugFileWriter::GetFileNameExtension() {
+const base::FilePath::CharType* AudioDebugFileWriter::GetFileExtension() {
   return FILE_PATH_LITERAL("wav");
 }
 
diff --git a/media/audio/audio_debug_file_writer.h b/media/audio/audio_debug_file_writer.h
index b45efb1..a11cd5b 100644
--- a/media/audio/audio_debug_file_writer.h
+++ b/media/audio/audio_debug_file_writer.h
@@ -55,7 +55,7 @@
   // Gets the extension for the file type the as a string, for example "wav".
   // Can be called before calling Start() to add the appropriate extension to
   // the filename.
-  virtual const base::FilePath::CharType* GetFileNameExtension();
+  virtual const base::FilePath::CharType* GetFileExtension();
 
  protected:
   const AudioParameters params_;
diff --git a/media/audio/audio_debug_file_writer_unittest.cc b/media/audio/audio_debug_file_writer_unittest.cc
index bb60734..805b1d88 100644
--- a/media/audio/audio_debug_file_writer_unittest.cc
+++ b/media/audio/audio_debug_file_writer_unittest.cc
@@ -242,10 +242,10 @@
   RecordAndVerifyOnce();
 }
 
-TEST_P(AudioDebugFileWriterTest, GetFileNameExtension) {
+TEST_P(AudioDebugFileWriterTest, GetFileExtension) {
   debug_writer_.reset(new AudioDebugFileWriter(params_));
   EXPECT_EQ(FILE_PATH_LITERAL("wav"),
-            base::FilePath::StringType(debug_writer_->GetFileNameExtension()));
+            base::FilePath::StringType(debug_writer_->GetFileExtension()));
 }
 
 TEST_P(AudioDebugFileWriterSingleThreadTest,
diff --git a/media/audio/audio_debug_recording_helper.cc b/media/audio/audio_debug_recording_helper.cc
index 1e85b02d..68e975e 100644
--- a/media/audio/audio_debug_recording_helper.cc
+++ b/media/audio/audio_debug_recording_helper.cc
@@ -5,6 +5,7 @@
 #include "media/audio/audio_debug_recording_helper.h"
 
 #include <memory>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/files/file.h"
@@ -17,12 +18,10 @@
 AudioDebugRecordingHelper::AudioDebugRecordingHelper(
     const AudioParameters& params,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-    CreateFileCallback create_file_callback,
     base::OnceClosure on_destruction_closure)
     : params_(params),
       recording_enabled_(0),
       task_runner_(std::move(task_runner)),
-      create_file_callback_(std::move(create_file_callback)),
       on_destruction_closure_(std::move(on_destruction_closure)),
       weak_factory_(this) {}
 
@@ -32,16 +31,16 @@
 }
 
 void AudioDebugRecordingHelper::EnableDebugRecording(
-    const base::FilePath& file_name) {
+    const base::FilePath& file_name_suffix,
+    CreateFileCallback create_file_callback) {
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(!debug_writer_);
-  DCHECK(!file_name.empty());
 
   debug_writer_ = CreateAudioDebugFileWriter(params_);
-  create_file_callback_.Run(
-      file_name.AddExtension(debug_writer_->GetFileNameExtension()),
-      base::BindOnce(&AudioDebugRecordingHelper::StartDebugRecordingToFile,
-                     weak_factory_.GetWeakPtr()));
+  std::move(create_file_callback)
+      .Run(file_name_suffix.AddExtension(debug_writer_->GetFileExtension()),
+           base::BindOnce(&AudioDebugRecordingHelper::StartDebugRecordingToFile,
+                          weak_factory_.GetWeakPtr()));
 }
 
 void AudioDebugRecordingHelper::StartDebugRecordingToFile(base::File file) {
diff --git a/media/audio/audio_debug_recording_helper.h b/media/audio/audio_debug_recording_helper.h
index 5124b4e..889d9cd 100644
--- a/media/audio/audio_debug_recording_helper.h
+++ b/media/audio/audio_debug_recording_helper.h
@@ -50,22 +50,22 @@
 // soundcard thread -> file thread.
 class MEDIA_EXPORT AudioDebugRecordingHelper : public AudioDebugRecorder {
  public:
-  using CreateFileCallback = base::RepeatingCallback<void(
+  using CreateFileCallback = base::OnceCallback<void(
       const base::FilePath&,
       base::OnceCallback<void(base::File)> reply_callback)>;
 
   AudioDebugRecordingHelper(
       const AudioParameters& params,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-      CreateFileCallback create_file_callback,
       base::OnceClosure on_destruction_closure);
   ~AudioDebugRecordingHelper() override;
 
-  // Enable debug recording. The AudioDebugFileWriter is created and
-  // |create_file_callback_| is ran to create debug recording file.
-  virtual void EnableDebugRecording(const base::FilePath& file_name);
+  // Enable debug recording. Creates |debug_writer_| and runs
+  // |create_file_callback| to create debug recording file.
+  virtual void EnableDebugRecording(const base::FilePath& file_name_suffix,
+                                    CreateFileCallback create_file_callback);
 
-  // Disable debug recording. The AudioDebugFileWriter is destroyed.
+  // Disable debug recording. Destroys |debug_writer_|.
   virtual void DisableDebugRecording();
 
   // AudioDebugRecorder implementation. Can be called on any thread.
@@ -82,8 +82,8 @@
   virtual std::unique_ptr<AudioDebugFileWriter> CreateAudioDebugFileWriter(
       const AudioParameters& params);
 
-  // Passed to |create_file_callback_|, to be called after debug recording
-  // file was created.
+  // Passed to |create_file_callback| in EnableDebugRecording, to be called
+  // after debug recording file was created.
   void StartDebugRecordingToFile(base::File file);
 
   const AudioParameters params_;
@@ -96,9 +96,6 @@
   // The task runner for accessing |debug_writer_|.
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
-  // Callback used for creating debug recording file.
-  CreateFileCallback create_file_callback_;
-
   // Runs in destructor if set.
   base::OnceClosure on_destruction_closure_;
 
diff --git a/media/audio/audio_debug_recording_helper_unittest.cc b/media/audio/audio_debug_recording_helper_unittest.cc
index 9406936c..7520202 100644
--- a/media/audio/audio_debug_recording_helper_unittest.cc
+++ b/media/audio/audio_debug_recording_helper_unittest.cc
@@ -4,7 +4,9 @@
 
 #include "media/audio/audio_debug_recording_helper.h"
 
+#include <limits>
 #include <memory>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/files/file_path.h"
@@ -34,15 +36,21 @@
 
 namespace {
 
-// The filename extension the mock should return in GetFileNameExtension().
-const base::FilePath::CharType kFileNameExtension[] = FILE_PATH_LITERAL("wav");
+const base::FilePath::CharType kBaseFileName[] =
+    FILE_PATH_LITERAL("debug_recording");
+
+const base::FilePath::CharType kFileNameSuffix[] =
+    FILE_PATH_LITERAL("output.1");
+
+// The file extension the mock should return in GetFileExtension().
+const base::FilePath::CharType kFileExtension[] = FILE_PATH_LITERAL("wav");
 
 }  // namespace
 
 // Mock class for the audio file writer that the helper wraps.
 class MockAudioDebugFileWriter : public AudioDebugFileWriter {
  public:
-  MockAudioDebugFileWriter(const AudioParameters& params)
+  explicit MockAudioDebugFileWriter(const AudioParameters& params)
       : AudioDebugFileWriter(params), reference_data_(nullptr) {}
   ~MockAudioDebugFileWriter() override = default;
 
@@ -67,7 +75,7 @@
   }
 
   MOCK_METHOD0(WillWrite, bool());
-  MOCK_METHOD0(GetFileNameExtension, const base::FilePath::CharType*());
+  MOCK_METHOD0(GetFileExtension, const base::FilePath::CharType*());
 
   // Set reference data to compare against. Must be called before Write() is
   // called.
@@ -90,22 +98,19 @@
   AudioDebugRecordingHelperUnderTest(
       const AudioParameters& params,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-      AudioDebugRecordingHelper::CreateFileCallback create_file_callback,
       base::OnceClosure on_destruction_closure)
       : AudioDebugRecordingHelper(params,
                                   std::move(task_runner),
-                                  std::move(create_file_callback),
                                   std::move(on_destruction_closure)) {}
   ~AudioDebugRecordingHelperUnderTest() override = default;
 
  private:
   // Creates the mock writer. After the mock writer is returned, we always
-  // expect GetFileNameExtension() and Start() to be called on it by the helper.
+  // expect GetFileExtension() and Start() to be called on it by the helper.
   std::unique_ptr<AudioDebugFileWriter> CreateAudioDebugFileWriter(
       const AudioParameters& params) override {
     MockAudioDebugFileWriter* writer = new MockAudioDebugFileWriter(params);
-    EXPECT_CALL(*writer, GetFileNameExtension())
-        .WillOnce(Return(kFileNameExtension));
+    EXPECT_CALL(*writer, GetFileExtension()).WillOnce(Return(kFileExtension));
     EXPECT_CALL(*writer, DoStart(true));
     return base::WrapUnique<AudioDebugFileWriter>(writer);
   }
@@ -116,7 +121,8 @@
 // The test fixture.
 class AudioDebugRecordingHelperTest : public ::testing::Test {
  public:
-  AudioDebugRecordingHelperTest() {}
+  AudioDebugRecordingHelperTest()
+      : file_name_suffix_(base::FilePath(kFileNameSuffix)) {}
 
   ~AudioDebugRecordingHelperTest() override = default;
 
@@ -126,33 +132,37 @@
       base::OnceClosure on_destruction_closure) {
     return std::make_unique<AudioDebugRecordingHelperUnderTest>(
         params, scoped_task_environment_.GetMainThreadTaskRunner(),
-        base::BindRepeating(&AudioDebugRecordingHelperTest::CreateFile,
-                            base::Unretained(this)),
         std::move(on_destruction_closure));
   }
 
-  // Helper function that unsets the mock writer pointer after disabling.
-  void DisableDebugRecording(AudioDebugRecordingHelper* recording_helper,
-                             const base::FilePath& file_path) {
-    recording_helper->DisableDebugRecording();
-    EXPECT_TRUE(
-        base::DeleteFile(file_path.AddExtension(kFileNameExtension), false));
-  }
-
   MOCK_METHOD0(OnAudioDebugRecordingHelperDestruction, void());
 
-  // Callback function for creating a file, passed in constructor and run on
-  // enable. Creating actual files to be able to test writer->DoWrite mock.
-  MOCK_METHOD1(DoCreateFile, void(const base::FilePath& file_name));
-  void CreateFile(const base::FilePath& file_name,
+  // Bound and passed to AudioDebugRecordingHelper::EnableDebugRecording as
+  // AudioDebugRecordingHelper::CreateFileCallback.
+  void CreateFile(const base::FilePath& file_name_suffix,
                   base::OnceCallback<void(base::File)> reply_callback) {
+    // Check that AudioDebugRecordingHelper::EnableDebugRecording adds file
+    // extension to file name suffix.
+    EXPECT_EQ(file_name_suffix_.AddExtension(kFileExtension), file_name_suffix);
+    base::FilePath temp_dir;
+    ASSERT_TRUE(base::GetTempDir(&temp_dir));
+    base::FilePath base_file_path(
+        temp_dir.Append(base::FilePath(kBaseFileName)));
+    base::FilePath file_path =
+        base_file_path.AddExtension(file_name_suffix.value());
     base::File debug_file(base::File(
-        file_name, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE));
+        file_path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE));
+    // Run |reply_callback| with a valid file for expected
+    // MockAudioDebugFileWriter::Start mocked call to happen.
     std::move(reply_callback).Run(std::move(debug_file));
-    DoCreateFile(file_name);
+    // File can be removed right away because MockAudioDebugFileWriter::Start is
+    // called synchronously.
+    ASSERT_TRUE(base::DeleteFile(file_path, false));
   }
 
  protected:
+  base::FilePath file_name_suffix_;
+
   // The test task environment.
   base::test::ScopedTaskEnvironment scoped_task_environment_;
 
@@ -160,8 +170,7 @@
   DISALLOW_COPY_AND_ASSIGN(AudioDebugRecordingHelperTest);
 };
 
-// Creates a helper with an on destruction closure, and verifies that it's
-// run.
+// Creates a helper with an on destruction closure, and verifies that it's run.
 TEST_F(AudioDebugRecordingHelperTest, TestDestructionClosure) {
   const AudioParameters params;
   std::unique_ptr<AudioDebugRecordingHelper> recording_helper =
@@ -187,22 +196,23 @@
   std::unique_ptr<AudioDebugRecordingHelper> recording_helper =
       CreateRecordingHelper(params, base::OnceClosure());
 
-  base::FilePath file_path;
-  EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
-  EXPECT_CALL(*this, DoCreateFile(file_path.AddExtension(kFileNameExtension)));
-  recording_helper->EnableDebugRecording(file_path);
+  recording_helper->EnableDebugRecording(
+      file_name_suffix_,
+      base::BindOnce(&AudioDebugRecordingHelperTest::CreateFile,
+                     base::Unretained(this)));
   EXPECT_CALL(*static_cast<MockAudioDebugFileWriter*>(
                   recording_helper->debug_writer_.get()),
               Stop());
-  DisableDebugRecording(recording_helper.get(), file_path);
+  recording_helper->DisableDebugRecording();
 
-  EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
-  EXPECT_CALL(*this, DoCreateFile(file_path.AddExtension(kFileNameExtension)));
-  recording_helper->EnableDebugRecording(file_path);
+  recording_helper->EnableDebugRecording(
+      file_name_suffix_,
+      base::BindOnce(&AudioDebugRecordingHelperTest::CreateFile,
+                     base::Unretained(this)));
   EXPECT_CALL(*static_cast<MockAudioDebugFileWriter*>(
                   recording_helper->debug_writer_.get()),
               Stop());
-  DisableDebugRecording(recording_helper.get(), file_path);
+  recording_helper->DisableDebugRecording();
 }
 
 TEST_F(AudioDebugRecordingHelperTest, OnData) {
@@ -229,10 +239,10 @@
   // Should not do anything.
   recording_helper->OnData(audio_bus.get());
 
-  base::FilePath file_path;
-  EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
-  EXPECT_CALL(*this, DoCreateFile(file_path.AddExtension(kFileNameExtension)));
-  recording_helper->EnableDebugRecording(file_path);
+  recording_helper->EnableDebugRecording(
+      file_name_suffix_,
+      base::BindOnce(&AudioDebugRecordingHelperTest::CreateFile,
+                     base::Unretained(this)));
   MockAudioDebugFileWriter* mock_audio_file_writer =
       static_cast<MockAudioDebugFileWriter*>(
           recording_helper->debug_writer_.get());
@@ -243,17 +253,18 @@
   base::RunLoop().RunUntilIdle();
 
   EXPECT_CALL(*mock_audio_file_writer, Stop());
-  DisableDebugRecording(recording_helper.get(), file_path);
+  recording_helper->DisableDebugRecording();
 
   // Make sure we clear the loop before enabling again.
   base::RunLoop().RunUntilIdle();
 
-  // Enable again, this time with two OnData() calls, one OnData() call
-  // without running the message loop until after disabling, and one call after
+  // Enable again, this time with two OnData() calls, one OnData() call without
+  // running the message loop until after disabling, and one call after
   // disabling.
-  EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
-  EXPECT_CALL(*this, DoCreateFile(file_path.AddExtension(kFileNameExtension)));
-  recording_helper->EnableDebugRecording(file_path);
+  recording_helper->EnableDebugRecording(
+      file_name_suffix_,
+      base::BindOnce(&AudioDebugRecordingHelperTest::CreateFile,
+                     base::Unretained(this)));
   mock_audio_file_writer = static_cast<MockAudioDebugFileWriter*>(
       recording_helper->debug_writer_.get());
   mock_audio_file_writer->SetReferenceData(audio_bus.get());
@@ -269,7 +280,7 @@
   recording_helper->OnData(audio_bus.get());
 
   EXPECT_CALL(*mock_audio_file_writer, Stop());
-  DisableDebugRecording(recording_helper.get(), file_path);
+  recording_helper->DisableDebugRecording();
 
   // This call should not yield a DoWrite() call on the mock either.
   recording_helper->OnData(audio_bus.get());
diff --git a/media/audio/audio_debug_recording_manager.cc b/media/audio/audio_debug_recording_manager.cc
index 99e730bf..7d1c337 100644
--- a/media/audio/audio_debug_recording_manager.cc
+++ b/media/audio/audio_debug_recording_manager.cc
@@ -26,29 +26,11 @@
 #define IntToStringType base::IntToString
 #endif
 
-// Helper function that returns |base_file_name| with |file_name_extension| and
-// |id| added to it as as extensions.
-base::FilePath GetDebugRecordingFileNameWithExtensions(
-    const base::FilePath& base_file_name,
-    const base::FilePath::StringType& file_name_extension,
+// Returns file name suffix created by appending |id| to |stream_type|.
+base::FilePath GetDebugRecordingFileNameSuffix(
+    const base::FilePath::StringType& stream_type,
     int id) {
-  return base_file_name.AddExtension(file_name_extension)
-      .AddExtension(IntToStringType(id));
-}
-
-void CreateFile(const base::FilePath& file_name,
-                base::OnceCallback<void(base::File)> reply_callback) {
-  base::PostTaskWithTraitsAndReplyWithResult(
-      FROM_HERE,
-      {base::MayBlock(), base::TaskPriority::BACKGROUND,
-       base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
-      base::BindOnce(
-          [](const base::FilePath& file_name) {
-            return base::File(file_name, base::File::FLAG_CREATE_ALWAYS |
-                                             base::File::FLAG_WRITE);
-          },
-          file_name),
-      std::move(reply_callback));
+  return base::FilePath(stream_type).AddExtension(IntToStringType(id));
 }
 
 }  // namespace
@@ -60,33 +42,34 @@
 AudioDebugRecordingManager::~AudioDebugRecordingManager() = default;
 
 void AudioDebugRecordingManager::EnableDebugRecording(
-    const base::FilePath& base_file_name) {
+    CreateFileCallback create_file_callback) {
   DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK(!base_file_name.empty());
+  DCHECK(!create_file_callback.is_null());
+  create_file_callback_ = std::move(create_file_callback);
 
-  debug_recording_base_file_name_ = base_file_name;
   for (const auto& it : debug_recording_helpers_) {
     int id = it.first;
     AudioDebugRecordingHelper* recording_helper = it.second.first;
-    const base::FilePath::StringType& file_name_extension = it.second.second;
+    const base::FilePath::StringType& stream_type = it.second.second;
     recording_helper->EnableDebugRecording(
-        GetDebugRecordingFileNameWithExtensions(debug_recording_base_file_name_,
-                                                file_name_extension, id));
+        GetDebugRecordingFileNameSuffix(stream_type, id),
+        create_file_callback_);
   }
 }
 
 void AudioDebugRecordingManager::DisableDebugRecording() {
   DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(!create_file_callback_.is_null());
   for (const auto& it : debug_recording_helpers_) {
     AudioDebugRecordingHelper* recording_helper = it.second.first;
     recording_helper->DisableDebugRecording();
   }
-  debug_recording_base_file_name_.clear();
+  create_file_callback_.Reset();
 }
 
 std::unique_ptr<AudioDebugRecorder>
 AudioDebugRecordingManager::RegisterDebugRecordingSource(
-    const base::FilePath::StringType& file_name_extension,
+    const base::FilePath::StringType& stream_type,
     const AudioParameters& params) {
   DCHECK(task_runner_->BelongsToCurrentThread());
 
@@ -103,12 +86,12 @@
 
   if (IsDebugRecordingEnabled()) {
     recording_helper->EnableDebugRecording(
-        GetDebugRecordingFileNameWithExtensions(debug_recording_base_file_name_,
-                                                file_name_extension, id));
+        GetDebugRecordingFileNameSuffix(stream_type, id),
+        create_file_callback_);
   }
 
   debug_recording_helpers_[id] =
-      std::make_pair(recording_helper.get(), file_name_extension);
+      std::make_pair(recording_helper.get(), stream_type);
 
   return base::WrapUnique<AudioDebugRecorder>(recording_helper.release());
 }
@@ -126,13 +109,12 @@
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     base::OnceClosure on_destruction_closure) {
   return std::make_unique<AudioDebugRecordingHelper>(
-      params, task_runner, base::BindRepeating(&CreateFile),
-      std::move(on_destruction_closure));
+      params, task_runner, std::move(on_destruction_closure));
 }
 
 bool AudioDebugRecordingManager::IsDebugRecordingEnabled() {
   DCHECK(task_runner_->BelongsToCurrentThread());
-  return !debug_recording_base_file_name_.empty();
+  return !create_file_callback_.is_null();
 }
 
 }  // namespace media
diff --git a/media/audio/audio_debug_recording_manager.h b/media/audio/audio_debug_recording_manager.h
index e90d8e5..23ac55891 100644
--- a/media/audio/audio_debug_recording_manager.h
+++ b/media/audio/audio_debug_recording_manager.h
@@ -26,8 +26,6 @@
 
 namespace media {
 
-class AudioDebugRecordingHelper;
-
 // A manager for audio debug recording that handles registration of data
 // sources and hands them a recorder (AudioDebugRecordingHelper) to feed data
 // to. The recorder will unregister with the manager automatically when deleted.
@@ -51,27 +49,30 @@
 //             ------------------  AudioManagerBase  ----------------
 //
 // AudioDebugRecordingManager is created when
-// AudioManager::InitializeDebugRecording() is called. That is done
-// in AudioManager::Create() in WebRTC enabled builds, but not in non WebRTC
-// enabled builds.
-// If AudioDebugRecordingManager is not created, neither is
+// AudioManager::InitializeDebugRecording() is called. That is done in
+// AudioManager::Create() in WebRTC enabled builds, but not in non WebRTC
+// enabled builds. If AudioDebugRecordingManager is not created, neither is
 // AudioDebugRecordingHelper or AudioDebugFileWriter. In this case the pointers
 // to AudioDebugRecordingManager and AudioDebugRecordingHelper are null.
-//
+
 class MEDIA_EXPORT AudioDebugRecordingManager {
  public:
+  using CreateFileCallback = base::RepeatingCallback<void(
+      const base::FilePath&,
+      base::OnceCallback<void(base::File)> reply_callback)>;
+
   AudioDebugRecordingManager(
       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
   virtual ~AudioDebugRecordingManager();
 
   // Enables and disables debug recording.
-  virtual void EnableDebugRecording(const base::FilePath& base_file_name);
+  virtual void EnableDebugRecording(CreateFileCallback create_file_callback);
   virtual void DisableDebugRecording();
 
-  // Registers a source and returns a wrapped recorder. |file_name_extension| is
-  // added to the base filename, along with a unique running ID.
+  // Registers a source and returns a wrapped recorder. |stream_type| is added
+  // to the base filename, along with a unique running ID.
   std::unique_ptr<AudioDebugRecorder> RegisterDebugRecordingSource(
-      const base::FilePath::StringType& file_name_extension,
+      const base::FilePath::StringType& stream_type,
       const AudioParameters& params);
 
  protected:
@@ -94,7 +95,7 @@
   FRIEND_TEST_ALL_PREFIXES(AudioDebugRecordingManagerTest,
                            EnableRegisterDisable);
 
-  // Map type from source id to recorder and its filename extension.
+  // Map type from source id to recorder and stream type (input/output).
   using DebugRecordingHelperMap = std::map<
       int,
       std::pair<AudioDebugRecordingHelper*, base::FilePath::StringType>>;
@@ -107,9 +108,9 @@
   // Recorders, one per source.
   DebugRecordingHelperMap debug_recording_helpers_;
 
-  // The base file name for debug recording files. If this is non-empty, debug
+  // Callback for creating debug recording files. When this is not null, debug
   // recording is enabled.
-  base::FilePath debug_recording_base_file_name_;
+  CreateFileCallback create_file_callback_;
 
   base::WeakPtrFactory<AudioDebugRecordingManager> weak_factory_;
   DISALLOW_COPY_AND_ASSIGN(AudioDebugRecordingManager);
diff --git a/media/audio/audio_debug_recording_manager_unittest.cc b/media/audio/audio_debug_recording_manager_unittest.cc
index 687259b..3e7b8883 100644
--- a/media/audio/audio_debug_recording_manager_unittest.cc
+++ b/media/audio/audio_debug_recording_manager_unittest.cc
@@ -29,9 +29,8 @@
 
 namespace {
 
-// The filename extension expected to be added.
-const base::FilePath::CharType kFileNameExtension[] =
-    FILE_PATH_LITERAL("extension");
+// The stream type expected to be added to file name.
+const base::FilePath::CharType kStreamType[] = FILE_PATH_LITERAL("output");
 
 // Used to be able to set call expectations in the MockAudioDebugRecordingHelper
 // ctor. See also comment on the test EnableRegisterDisable.
@@ -50,6 +49,11 @@
   }
 };
 
+// Function bound and passed to AudioDebugRecordingManager::EnableDebugRecording
+// as AudioDebugRecordingManager::CreateFileCallback.
+void CreateFile(const base::FilePath& file_path,
+                base::OnceCallback<void(base::File)>) {}
+
 }  // namespace
 
 // Mock class to verify enable and disable calls.
@@ -58,15 +62,13 @@
   MockAudioDebugRecordingHelper(
       const AudioParameters& params,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-      AudioDebugRecordingHelper::CreateFileCallback create_file_callback,
       base::OnceClosure on_destruction_closure)
       : AudioDebugRecordingHelper(params,
                                   std::move(task_runner),
-                                  std::move(create_file_callback),
                                   base::OnceClosure()),
         on_destruction_closure_in_mock_(std::move(on_destruction_closure)) {
     if (g_expect_enable_after_create_helper)
-      EXPECT_CALL(*this, EnableDebugRecording(_));
+      EXPECT_CALL(*this, DoEnableDebugRecording(_));
   }
 
   ~MockAudioDebugRecordingHelper() override {
@@ -74,7 +76,13 @@
       std::move(on_destruction_closure_in_mock_).Run();
   }
 
-  MOCK_METHOD1(EnableDebugRecording, void(const base::FilePath&));
+  MOCK_METHOD1(DoEnableDebugRecording, void(const base::FilePath&));
+  void EnableDebugRecording(const base::FilePath& file_name_suffix,
+                            AudioDebugRecordingHelper::CreateFileCallback
+                                create_file_callback) override {
+    DoEnableDebugRecording(file_name_suffix);
+  }
+
   MOCK_METHOD0(DisableDebugRecording, void());
 
  private:
@@ -101,9 +109,6 @@
       base::OnceClosure on_destruction_closure) override {
     return std::make_unique<MockAudioDebugRecordingHelper>(
         params, std::move(task_runner),
-        base::BindRepeating(
-            [](const base::FilePath& file_name,
-               base::OnceCallback<void(base::File)> reply_callback) {}),
         std::move(on_destruction_closure));
   }
 
@@ -114,8 +119,7 @@
 class AudioDebugRecordingManagerTest : public ::testing::Test {
  public:
   AudioDebugRecordingManagerTest()
-      : manager_(scoped_task_environment_.GetMainThreadTaskRunner()),
-        base_file_path_(base::FilePath::FromUTF8Unsafe("base_path")) {}
+      : manager_(scoped_task_environment_.GetMainThreadTaskRunner()) {}
 
   ~AudioDebugRecordingManagerTest() override = default;
 
@@ -123,7 +127,7 @@
   std::unique_ptr<AudioDebugRecorder> RegisterDebugRecordingSource(
       const AudioParameters& params) {
     ++expected_next_source_id_;
-    return manager_.RegisterDebugRecordingSource(kFileNameExtension, params);
+    return manager_.RegisterDebugRecordingSource(kStreamType, params);
   }
 
  protected:
@@ -131,7 +135,6 @@
   base::test::ScopedTaskEnvironment scoped_task_environment_;
 
   AudioDebugRecordingManagerUnderTest manager_;
-  base::FilePath base_file_path_;
 
   // The expected next source id the manager will assign. It's static since the
   // manager uses a global running id, thus doesn't restart at each
@@ -144,9 +147,10 @@
 
 int AudioDebugRecordingManagerTest::expected_next_source_id_ = 1;
 
-// Shouldn't do anything but store the path, i.e. no calls to recorders.
+// Shouldn't do anything but store the CreateFileCallback, i.e. no calls to
+// recorders.
 TEST_F(AudioDebugRecordingManagerTest, EnableDisable) {
-  manager_.EnableDebugRecording(base_file_path_);
+  manager_.EnableDebugRecording(base::BindRepeating(&CreateFile));
   manager_.DisableDebugRecording();
 }
 
@@ -186,14 +190,14 @@
     MockAudioDebugRecordingHelper* mock_recording_helper =
         static_cast<MockAudioDebugRecordingHelper*>(recorder.get());
     base::FilePath expected_file_path =
-        base_file_path_.AddExtension(kFileNameExtension)
+        base::FilePath(kStreamType)
             .AddExtension(IntToStringType(expected_id++));
     EXPECT_CALL(*mock_recording_helper,
-                EnableDebugRecording(expected_file_path));
+                DoEnableDebugRecording(expected_file_path));
     EXPECT_CALL(*mock_recording_helper, DisableDebugRecording());
   }
 
-  manager_.EnableDebugRecording(base_file_path_);
+  manager_.EnableDebugRecording(base::BindRepeating(&CreateFile));
   manager_.DisableDebugRecording();
 }
 
@@ -206,7 +210,7 @@
 TEST_F(AudioDebugRecordingManagerTest, EnableRegisterDisable) {
   ScopedExpectEnableAfterCreateHelper scoped_enable_after_create_helper;
 
-  manager_.EnableDebugRecording(base_file_path_);
+  manager_.EnableDebugRecording(base::BindRepeating(&CreateFile));
 
   const AudioParameters params;
   std::vector<std::unique_ptr<AudioDebugRecorder>> recorders;
diff --git a/media/audio/audio_debug_recording_session.cc b/media/audio/audio_debug_recording_session.cc
index fe7fd72..ed08ca3 100644
--- a/media/audio/audio_debug_recording_session.cc
+++ b/media/audio/audio_debug_recording_session.cc
@@ -6,7 +6,6 @@
 
 #include "base/files/file_path.h"
 #include "media/audio/audio_debug_recording_session_impl.h"
-#include "media/audio/audio_manager.h"
 
 namespace media {
 
diff --git a/media/audio/audio_debug_recording_session_impl.cc b/media/audio/audio_debug_recording_session_impl.cc
index 2f26d97..c9bc2082 100644
--- a/media/audio/audio_debug_recording_session_impl.cc
+++ b/media/audio/audio_debug_recording_session_impl.cc
@@ -4,9 +4,15 @@
 
 #include "media/audio/audio_debug_recording_session_impl.h"
 
+#include <utility>
+
 #include "base/bind.h"
+#include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/single_thread_task_runner.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/task_scheduler/task_traits.h"
+#include "media/audio/audio_debug_recording_manager.h"
 #include "media/audio/audio_manager.h"
 
 namespace media {
@@ -15,6 +21,26 @@
 // AudioManager::Shutdown() (called before AudioManager destruction) shuts down
 // AudioManager thread.
 
+namespace {
+
+void CreateFile(const base::FilePath& debug_recording_file_path,
+                const base::FilePath& file_name_suffix,
+                base::OnceCallback<void(base::File)> reply_callback) {
+  base::PostTaskWithTraitsAndReplyWithResult(
+      FROM_HERE,
+      {base::MayBlock(), base::TaskPriority::BACKGROUND,
+       base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
+      base::BindOnce(
+          [](const base::FilePath& file_name) {
+            return base::File(file_name, base::File::FLAG_CREATE_ALWAYS |
+                                             base::File::FLAG_WRITE);
+          },
+          debug_recording_file_path.AddExtension(file_name_suffix.value())),
+      std::move(reply_callback));
+}
+
+}  // namespace
+
 AudioDebugRecordingSessionImpl::AudioDebugRecordingSessionImpl(
     const base::FilePath& debug_recording_file_path) {
   AudioManager* audio_manager = AudioManager::Get();
@@ -22,9 +48,20 @@
     return;
 
   audio_manager->GetTaskRunner()->PostTask(
-      FROM_HERE, base::BindOnce(&AudioManager::EnableDebugRecording,
-                                base::Unretained(audio_manager),
-                                debug_recording_file_path));
+      FROM_HERE,
+      base::BindOnce(
+          [](AudioManager* manager,
+             AudioDebugRecordingManager::CreateFileCallback
+                 create_file_callback) {
+            AudioDebugRecordingManager* debug_recording_manager =
+                manager->GetAudioDebugRecordingManager();
+            if (debug_recording_manager == nullptr)
+              return;
+            debug_recording_manager->EnableDebugRecording(
+                std::move(create_file_callback));
+          },
+          base::Unretained(audio_manager),
+          base::BindRepeating(&CreateFile, debug_recording_file_path)));
 }
 
 AudioDebugRecordingSessionImpl::~AudioDebugRecordingSessionImpl() {
@@ -33,8 +70,15 @@
     return;
 
   audio_manager->GetTaskRunner()->PostTask(
-      FROM_HERE, base::BindOnce(&AudioManager::DisableDebugRecording,
-                                base::Unretained(audio_manager)));
+      FROM_HERE, base::BindOnce(
+                     [](AudioManager* manager) {
+                       AudioDebugRecordingManager* debug_recording_manager =
+                           manager->GetAudioDebugRecordingManager();
+                       if (debug_recording_manager == nullptr)
+                         return;
+                       debug_recording_manager->DisableDebugRecording();
+                     },
+                     base::Unretained(audio_manager)));
 }
 
 }  // namespace media
diff --git a/media/audio/audio_debug_recording_session_impl_unittest.cc b/media/audio/audio_debug_recording_session_impl_unittest.cc
index f95840b..2371adf 100644
--- a/media/audio/audio_debug_recording_session_impl_unittest.cc
+++ b/media/audio/audio_debug_recording_session_impl_unittest.cc
@@ -4,7 +4,12 @@
 
 #include "media/audio/audio_debug_recording_session_impl.h"
 
+#include <memory>
+
+#include "base/bind.h"
+#include "base/files/file_util.h"
 #include "base/test/scoped_task_environment.h"
+#include "media/audio/mock_audio_debug_recording_manager.h"
 #include "media/audio/mock_audio_manager.h"
 #include "media/audio/test_audio_thread.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -13,11 +18,36 @@
 namespace media {
 
 namespace {
-const base::FilePath::CharType kFilePath[] = FILE_PATH_LITERAL("file_path");
+
+const base::FilePath::CharType kBaseFileName[] =
+    FILE_PATH_LITERAL("debug_recording");
+const base::FilePath::CharType kInputFileNameSuffix[] =
+    FILE_PATH_LITERAL("input.1.wav");
+const base::FilePath::CharType kOutputFileNameSuffix[] =
+    FILE_PATH_LITERAL("output.1.wav");
+
+void OnFileCreated(base::File debug_file) {}
+
+// Action function called on
+// MockAudioDebugRecordingManager::EnableDebugRecording mocked method to test
+// |create_file_callback| behavior.
+void CreateInputOutputDebugRecordingFiles(
+    const base::RepeatingCallback<void(const base::FilePath&,
+                                       base::OnceCallback<void(base::File)>)>&
+        create_file_callback) {
+  create_file_callback.Run(base::FilePath(kInputFileNameSuffix),
+                           base::BindOnce(&OnFileCreated));
+  create_file_callback.Run(base::FilePath(kOutputFileNameSuffix),
+                           base::BindOnce(&OnFileCreated));
 }
 
+}  // namespace
+
 class AudioDebugRecordingSessionImplTest : public testing::Test {
  public:
+  AudioDebugRecordingSessionImplTest() { SetBaseFilePath(); }
+
+ protected:
   void CreateAudioManager() {
     mock_audio_manager_ =
         std::make_unique<MockAudioManager>(std::make_unique<TestAudioThread>());
@@ -28,21 +58,40 @@
 
   void ShutdownAudioManager() { ASSERT_TRUE(mock_audio_manager_->Shutdown()); }
 
+  void InitializeAudioDebugRecordingManager() {
+    mock_audio_manager_->InitializeDebugRecording();
+    mock_debug_recording_manager_ =
+        static_cast<MockAudioDebugRecordingManager*>(
+            mock_audio_manager_->GetAudioDebugRecordingManager());
+    ASSERT_NE(nullptr, mock_debug_recording_manager_);
+  }
+
   void CreateDebugRecordingSession() {
     audio_debug_recording_session_impl_ =
-        std::make_unique<media::AudioDebugRecordingSessionImpl>(file_path_);
+        std::make_unique<media::AudioDebugRecordingSessionImpl>(
+            base_file_path_);
   }
 
   void DestroyDebugRecordingSession() {
     audio_debug_recording_session_impl_.reset();
   }
 
- protected:
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   std::unique_ptr<MockAudioManager> mock_audio_manager_;
+  MockAudioDebugRecordingManager* mock_debug_recording_manager_;
   std::unique_ptr<AudioDebugRecordingSessionImpl>
       audio_debug_recording_session_impl_;
-  base::FilePath file_path_ = base::FilePath(kFilePath);
+  base::FilePath base_file_path_;
+
+ private:
+  void SetBaseFilePath() {
+    base::FilePath temp_dir;
+    if (!base::GetTempDir(&temp_dir))
+      FAIL();
+    base_file_path_ = temp_dir.Append(base::FilePath(kBaseFileName));
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(AudioDebugRecordingSessionImplTest);
 };
 
 TEST_F(AudioDebugRecordingSessionImplTest,
@@ -50,10 +99,11 @@
   ::testing::InSequence seq;
 
   CreateAudioManager();
-  EXPECT_CALL(*mock_audio_manager_, EnableDebugRecording(file_path_));
+  InitializeAudioDebugRecordingManager();
+  EXPECT_CALL(*mock_debug_recording_manager_, EnableDebugRecording(testing::_));
   CreateDebugRecordingSession();
 
-  EXPECT_CALL(*mock_audio_manager_, DisableDebugRecording());
+  EXPECT_CALL(*mock_debug_recording_manager_, DisableDebugRecording());
   DestroyDebugRecordingSession();
 
   ShutdownAudioManager();
@@ -66,4 +116,40 @@
   DestroyDebugRecordingSession();
 }
 
+TEST_F(AudioDebugRecordingSessionImplTest,
+       CreateDestroySessionDontCrashWithoutInitializingDebugRecordingManager) {
+  CreateAudioManager();
+  CreateDebugRecordingSession();
+  DestroyDebugRecordingSession();
+  ShutdownAudioManager();
+}
+
+// Tests the CreateFile method from AudioDebugRecordingSessionImpl unnamed
+// namespace.
+TEST_F(AudioDebugRecordingSessionImplTest, CreateFileCreatesExpectedFiles) {
+  CreateAudioManager();
+  InitializeAudioDebugRecordingManager();
+  EXPECT_CALL(*mock_debug_recording_manager_, EnableDebugRecording(testing::_))
+      .WillOnce(testing::Invoke(CreateInputOutputDebugRecordingFiles));
+  CreateDebugRecordingSession();
+
+  // Wait for files to be created.
+  scoped_task_environment_.RunUntilIdle();
+
+  // Check that expected files were created.
+  base::FilePath input_recording_filename(
+      base_file_path_.AddExtension(kInputFileNameSuffix));
+  base::FilePath output_recording_filename(
+      base_file_path_.AddExtension(kOutputFileNameSuffix));
+  EXPECT_TRUE(base::PathExists(output_recording_filename));
+  EXPECT_TRUE(base::PathExists(input_recording_filename));
+
+  // Clean-up.
+  EXPECT_CALL(*mock_debug_recording_manager_, DisableDebugRecording());
+  DestroyDebugRecordingSession();
+  ShutdownAudioManager();
+  EXPECT_TRUE(base::DeleteFile(output_recording_filename, false));
+  EXPECT_TRUE(base::DeleteFile(input_recording_filename, false));
+}
+
 }  // namespace media
diff --git a/media/audio/audio_manager.h b/media/audio/audio_manager.h
index 135f83ad..6bcc2f5 100644
--- a/media/audio/audio_manager.h
+++ b/media/audio/audio_manager.h
@@ -20,12 +20,12 @@
 #include "media/base/audio_parameters.h"
 
 namespace base {
-class FilePath;
 class SingleThreadTaskRunner;
 }
 
 namespace media {
 
+class AudioDebugRecordingManager;
 class AudioInputStream;
 class AudioManager;
 class AudioOutputStream;
@@ -173,12 +173,9 @@
   virtual std::unique_ptr<AudioLog> CreateAudioLog(
       AudioLogFactory::AudioComponent component) = 0;
 
-  // Enable debug recording. InitializeDebugRecording() must be called before
-  // this function.
-  virtual void EnableDebugRecording(const base::FilePath& base_file_name) = 0;
-
-  // Disable debug recording.
-  virtual void DisableDebugRecording() = 0;
+  // Get debug recording manager. This can only be called on AudioManager's
+  // thread (GetTaskRunner()).
+  virtual AudioDebugRecordingManager* GetAudioDebugRecordingManager() = 0;
 
   // Gets the name of the audio manager (e.g., Windows, Mac, PulseAudio).
   virtual const char* GetName() = 0;
@@ -194,8 +191,8 @@
 
   virtual void ShutdownOnAudioThread() = 0;
 
-  // Initializes output debug recording. Can be called on any thread; will post
-  // to the audio thread if not called on it.
+  // Initializes debug recording. Can be called on any thread; will post to the
+  // audio thread if not called on it.
   virtual void InitializeDebugRecording() = 0;
 
   // Returns true if the OS reports existence of audio devices. This does not
diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc
index 858f586..450a31a 100644
--- a/media/audio/audio_manager_base.cc
+++ b/media/audio/audio_manager_base.cc
@@ -573,26 +573,17 @@
   debug_recording_manager_ = CreateAudioDebugRecordingManager(GetTaskRunner());
 }
 
-void AudioManagerBase::EnableDebugRecording(
-    const base::FilePath& base_file_name) {
-  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
-  DCHECK(debug_recording_manager_)
-      << "InitializeDebugRecording() must be called before enabling";
-  debug_recording_manager_->EnableDebugRecording(base_file_name);
-}
-
-void AudioManagerBase::DisableDebugRecording() {
-  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
-  if (debug_recording_manager_)
-    debug_recording_manager_->DisableDebugRecording();
-}
-
 std::unique_ptr<AudioDebugRecordingManager>
 AudioManagerBase::CreateAudioDebugRecordingManager(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   return std::make_unique<AudioDebugRecordingManager>(std::move(task_runner));
 }
 
+AudioDebugRecordingManager* AudioManagerBase::GetAudioDebugRecordingManager() {
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
+  return debug_recording_manager_.get();
+}
+
 void AudioManagerBase::SetMaxStreamCountForTesting(int max_input,
                                                    int max_output) {
   max_num_output_streams_ = max_output;
diff --git a/media/audio/audio_manager_base.h b/media/audio/audio_manager_base.h
index 5ead83e3..dcb27ec 100644
--- a/media/audio/audio_manager_base.h
+++ b/media/audio/audio_manager_base.h
@@ -53,8 +53,6 @@
 
   std::unique_ptr<AudioLog> CreateAudioLog(
       AudioLogFactory::AudioComponent component) override;
-  void EnableDebugRecording(const base::FilePath& base_file_name) final;
-  void DisableDebugRecording() final;
 
   void SetMaxStreamCountForTesting(int max_input, int max_output) final;
 
@@ -159,6 +157,7 @@
   virtual std::unique_ptr<AudioDebugRecordingManager>
   CreateAudioDebugRecordingManager(
       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+  AudioDebugRecordingManager* GetAudioDebugRecordingManager() final;
 
   // These functions assign group ids to devices based on their device ids. The
   // default implementation is an attempt to do this based on
diff --git a/media/audio/audio_manager_unittest.cc b/media/audio/audio_manager_unittest.cc
index 60ed847..720df56 100644
--- a/media/audio/audio_manager_unittest.cc
+++ b/media/audio/audio_manager_unittest.cc
@@ -605,22 +605,6 @@
 }
 #endif  // defined(USE_CRAS)
 
-// Mock class to verify enable and disable debug recording calls.
-class MockAudioDebugRecordingManager : public AudioDebugRecordingManager {
- public:
-  MockAudioDebugRecordingManager(
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-      : AudioDebugRecordingManager(std::move(task_runner)) {}
-
-  ~MockAudioDebugRecordingManager() override = default;
-
-  MOCK_METHOD1(EnableDebugRecording, void(const base::FilePath&));
-  MOCK_METHOD0(DisableDebugRecording, void());
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockAudioDebugRecordingManager);
-};
-
 class TestAudioManager : public FakeAudioManager {
   // For testing the default implementation of GetGroupId(Input|Output)
   // input$i is associated to output$i, if both exist.
@@ -670,12 +654,6 @@
     device_names->emplace_back("Output 4", "output4");
     device_names->push_front(AudioDeviceName::CreateDefault());
   }
-
-  std::unique_ptr<AudioDebugRecordingManager> CreateAudioDebugRecordingManager(
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
-    return std::make_unique<MockAudioDebugRecordingManager>(
-        std::move(task_runner));
-  }
 };
 
 TEST_F(AudioManagerTest, GroupId) {
@@ -724,32 +702,6 @@
   CheckDescriptionLabels(outputs, default_output_id, communications_output_id);
 }
 
-TEST_F(AudioManagerTest, AudioDebugRecording) {
-  CreateAudioManagerForTesting<TestAudioManager>();
-
-  AudioManagerBase* audio_manager_base =
-      static_cast<AudioManagerBase*>(audio_manager_.get());
-
-  // Initialize is normally done in AudioManager::Create(), but since we don't
-  // use that in this test, we need to initialize here.
-  audio_manager_->InitializeDebugRecording();
-
-  MockAudioDebugRecordingManager* mock_debug_recording_manager =
-      static_cast<MockAudioDebugRecordingManager*>(
-          audio_manager_base->debug_recording_manager_.get());
-  ASSERT_TRUE(mock_debug_recording_manager);
-
-  EXPECT_CALL(*mock_debug_recording_manager, DisableDebugRecording());
-  audio_manager_->DisableDebugRecording();
-
-  base::FilePath file_path(FILE_PATH_LITERAL("path"));
-  EXPECT_CALL(*mock_debug_recording_manager, EnableDebugRecording(file_path));
-  audio_manager_->EnableDebugRecording(file_path);
-
-  EXPECT_CALL(*mock_debug_recording_manager, DisableDebugRecording());
-  audio_manager_->DisableDebugRecording();
-}
-
 #if defined(OS_MACOSX) || defined(USE_CRAS)
 class TestAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
  public:
diff --git a/media/audio/mock_audio_debug_recording_manager.cc b/media/audio/mock_audio_debug_recording_manager.cc
new file mode 100644
index 0000000..1a38ba2
--- /dev/null
+++ b/media/audio/mock_audio_debug_recording_manager.cc
@@ -0,0 +1,17 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/audio/mock_audio_debug_recording_manager.h"
+
+#include <utility>
+
+namespace media {
+
+MockAudioDebugRecordingManager::MockAudioDebugRecordingManager(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+    : AudioDebugRecordingManager(std::move(task_runner)) {}
+
+MockAudioDebugRecordingManager::~MockAudioDebugRecordingManager() = default;
+
+}  // namespace media
diff --git a/media/audio/mock_audio_debug_recording_manager.h b/media/audio/mock_audio_debug_recording_manager.h
new file mode 100644
index 0000000..97ec53c
--- /dev/null
+++ b/media/audio/mock_audio_debug_recording_manager.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_AUDIO_MOCK_AUDIO_DEBUG_RECORDING_MANAGER_H_
+#define MEDIA_AUDIO_MOCK_AUDIO_DEBUG_RECORDING_MANAGER_H_
+
+#include "base/macros.h"
+#include "media/audio/audio_debug_recording_manager.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace media {
+
+class MockAudioDebugRecordingManager : public AudioDebugRecordingManager {
+ public:
+  explicit MockAudioDebugRecordingManager(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+
+  ~MockAudioDebugRecordingManager() override;
+
+  MOCK_METHOD1(
+      EnableDebugRecording,
+      void(base::RepeatingCallback<void(const base::FilePath&,
+                                        base::OnceCallback<void(base::File)>)>
+               create_file_callback));
+  MOCK_METHOD0(DisableDebugRecording, void());
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockAudioDebugRecordingManager);
+};
+
+}  // namespace media.
+
+#endif  // MEDIA_AUDIO_MOCK_AUDIO_DEBUG_RECORDING_MANAGER_H_
diff --git a/media/audio/mock_audio_manager.cc b/media/audio/mock_audio_manager.cc
index 77ad141..f2ea15d4 100644
--- a/media/audio/mock_audio_manager.cc
+++ b/media/audio/mock_audio_manager.cc
@@ -8,6 +8,7 @@
 
 #include "base/callback.h"
 #include "base/logging.h"
+#include "media/audio/mock_audio_debug_recording_manager.h"
 #include "media/base/audio_parameters.h"
 
 namespace media {
@@ -124,7 +125,23 @@
   return nullptr;
 }
 
-void MockAudioManager::InitializeDebugRecording() {}
+void MockAudioManager::InitializeDebugRecording() {
+  if (!GetTaskRunner()->BelongsToCurrentThread()) {
+    GetTaskRunner()->PostTask(
+        FROM_HERE, base::BindOnce(&MockAudioManager::InitializeDebugRecording,
+                                  base::Unretained(this)));
+    return;
+  }
+
+  DCHECK(!debug_recording_manager_);
+  debug_recording_manager_ =
+      std::make_unique<MockAudioDebugRecordingManager>(GetTaskRunner());
+}
+
+AudioDebugRecordingManager* MockAudioManager::GetAudioDebugRecordingManager() {
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
+  return debug_recording_manager_.get();
+}
 
 const char* MockAudioManager::GetName() {
   return nullptr;
diff --git a/media/audio/mock_audio_manager.h b/media/audio/mock_audio_manager.h
index 23105a0..8f6bcf5c 100644
--- a/media/audio/mock_audio_manager.h
+++ b/media/audio/mock_audio_manager.h
@@ -9,10 +9,8 @@
 #include <string>
 
 #include "base/callback_forward.h"
-#include "base/files/file_path.h"
 #include "base/macros.h"
-#include "base/sequenced_task_runner_helpers.h"
-#include "base/single_thread_task_runner.h"
+#include "media/audio/audio_debug_recording_manager.h"
 #include "media/audio/audio_manager.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
@@ -61,9 +59,7 @@
       AudioLogFactory::AudioComponent component) override;
 
   void InitializeDebugRecording() override;
-  MOCK_METHOD1(EnableDebugRecording,
-               void(const base::FilePath& base_file_name));
-  MOCK_METHOD0(DisableDebugRecording, void());
+  AudioDebugRecordingManager* GetAudioDebugRecordingManager() override;
 
   const char* GetName() override;
 
@@ -118,6 +114,7 @@
   GetDeviceDescriptionsCallback get_input_device_descriptions_cb_;
   GetDeviceDescriptionsCallback get_output_device_descriptions_cb_;
   GetAssociatedOutputDeviceIDCallback get_associated_output_device_id_cb_;
+  std::unique_ptr<AudioDebugRecordingManager> debug_recording_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(MockAudioManager);
 };
diff --git a/net/disk_cache/entry_unittest.cc b/net/disk_cache/entry_unittest.cc
index cf00bc3..3456ba1 100644
--- a/net/disk_cache/entry_unittest.cc
+++ b/net/disk_cache/entry_unittest.cc
@@ -1821,6 +1821,12 @@
   EXPECT_EQ(0, cb.GetResult(rv));
   EXPECT_EQ(kTinyLen * 2, start);
 
+  // Get a huge range with maximum boundary
+  start = -1;
+  rv = entry->GetAvailableRange(0x2100000, std::numeric_limits<int32_t>::max(),
+                                &start, cb.callback());
+  EXPECT_EQ(0, cb.GetResult(rv));
+
   entry->Close();
 }
 
diff --git a/net/disk_cache/memory/mem_entry_impl.cc b/net/disk_cache/memory/mem_entry_impl.cc
index 3b096ce..95f43db9 100644
--- a/net/disk_cache/memory/mem_entry_impl.cc
+++ b/net/disk_cache/memory/mem_entry_impl.cc
@@ -12,6 +12,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
+#include "net/base/interval.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 #include "net/disk_cache/memory/mem_backend_impl.h"
@@ -527,36 +528,35 @@
   if (offset < 0 || len < 0 || !start)
     return net::ERR_INVALID_ARGUMENT;
 
-  MemEntryImpl* current_child = nullptr;
+  net::Interval<int64_t> requested(offset, offset + len);
 
-  // Find the first child and record the number of empty bytes.
-  int empty = FindNextChild(offset, len, &current_child);
-  if (current_child && empty < len) {
-    *start = offset + empty;
-    len -= empty;
-
-    // Counts the number of continuous bytes.
-    int continuous = 0;
-
-    // This loop scan for continuous bytes.
-    while (len && current_child) {
-      // Number of bytes available in this child.
-      int data_size = current_child->GetDataSize(kSparseData) -
-                      ToChildOffset(*start + continuous);
-      if (data_size > len)
-        data_size = len;
-
-      // We have found more continuous bytes so increment the count. Also
-      // decrement the length we should scan.
-      continuous += data_size;
-      len -= data_size;
-
-      // If the next child is discontinuous, break the loop.
-      if (FindNextChild(*start + continuous, len, &current_child))
+  // Find the first relevant child, if any --- may have to skip over
+  // one entry as it may be before the range (consider, for example,
+  // if the request is for [2048, 10000), while [0, 1024) is a valid range
+  // for the entry).
+  EntryMap::const_iterator i = children_->lower_bound(ToChildIndex(offset));
+  if (i != children_->cend() && !ChildInterval(i).Intersects(requested))
+    ++i;
+  net::Interval<int64_t> found;
+  if (i != children_->cend() &&
+      requested.Intersects(ChildInterval(i), &found)) {
+    // Found something relevant; now just need to expand this out if next
+    // children are contiguous and relevant to the request.
+    while (true) {
+      ++i;
+      net::Interval<int64_t> relevant_in_next_child;
+      if (i == children_->cend() ||
+          !requested.Intersects(ChildInterval(i), &relevant_in_next_child) ||
+          relevant_in_next_child.min() != found.max()) {
         break;
+      }
+
+      found.SpanningUnion(relevant_in_next_child);
     }
-    return continuous;
+    *start = found.min();
+    return found.Length();
   }
+
   *start = offset;
   return 0;
 }
@@ -589,36 +589,17 @@
   return nullptr;
 }
 
-int MemEntryImpl::FindNextChild(int64_t offset, int len, MemEntryImpl** child) {
-  DCHECK(child);
-  *child = nullptr;
-  int scanned_len = 0;
-
-  // This loop tries to find the first existing child.
-  while (scanned_len < len) {
-    // This points to the current offset in the child.
-    int current_child_offset = ToChildOffset(offset + scanned_len);
-    MemEntryImpl* current_child = GetChild(offset + scanned_len, false);
-    if (current_child) {
-      int child_first_pos = current_child->child_first_pos_;
-
-      // This points to the first byte that we should be reading from, we need
-      // to take care of the filled region and the current offset in the child.
-      int first_pos =  std::max(current_child_offset, child_first_pos);
-
-      // If the first byte position we should read from doesn't exceed the
-      // filled region, we have found the first child.
-      if (first_pos < current_child->GetDataSize(kSparseData)) {
-         *child = current_child;
-
-         // We need to advance the scanned length.
-         scanned_len += first_pos - current_child_offset;
-         break;
-      }
-    }
-    scanned_len += kMaxSparseEntrySize - current_child_offset;
-  }
-  return scanned_len;
+net::Interval<int64_t> MemEntryImpl::ChildInterval(
+    MemEntryImpl::EntryMap::const_iterator i) {
+  DCHECK(i != children_->cend());
+  const MemEntryImpl* child = i->second;
+  // The valid range in child is [child_first_pos_, DataSize), since the child
+  // entry ops just use standard disk_cache::Entry API, so DataSize is
+  // not aware of any hole in the beginning.
+  int64_t child_responsibility_start = (i->first) * kMaxSparseEntrySize;
+  return net::Interval<int64_t>(
+      child_responsibility_start + child->child_first_pos_,
+      child_responsibility_start + child->GetDataSize(kSparseData));
 }
 
 }  // namespace disk_cache
diff --git a/net/disk_cache/memory/mem_entry_impl.h b/net/disk_cache/memory/mem_entry_impl.h
index 6b5ab3dc..33ffbdb4 100644
--- a/net/disk_cache/memory/mem_entry_impl.h
+++ b/net/disk_cache/memory/mem_entry_impl.h
@@ -7,9 +7,9 @@
 
 #include <stdint.h>
 
+#include <map>
 #include <memory>
 #include <string>
-#include <unordered_map>
 #include <vector>
 
 #include "base/containers/linked_list.h"
@@ -17,6 +17,7 @@
 #include "base/macros.h"
 #include "base/time/time.h"
 #include "base/trace_event/memory_usage_estimator.h"
+#include "net/base/interval.h"
 #include "net/base/net_export.h"
 #include "net/disk_cache/disk_cache.h"
 #include "net/log/net_log_with_source.h"
@@ -140,7 +141,7 @@
                MemEntryImpl* parent,
                net::NetLog* net_log);
 
-  using EntryMap = std::unordered_map<int, MemEntryImpl*>;
+  using EntryMap = std::map<int, MemEntryImpl*>;
 
   static const int kNumStreams = 3;
 
@@ -165,10 +166,11 @@
   // created.
   MemEntryImpl* GetChild(int64_t offset, bool create);
 
-  // Finds the first child located within the range [|offset|, |offset + len|).
-  // Returns the number of bytes ahead of |offset| to reach the first available
-  // bytes in the entry. The first child found is output to |child|.
-  int FindNextChild(int64_t offset, int len, MemEntryImpl** child);
+  // Returns an interval describing what's stored in the child entry pointed to
+  // by i, in global coordinates.
+  // Precondition: i != children_.end();
+  net::Interval<int64_t> ChildInterval(
+      MemEntryImpl::EntryMap::const_iterator i);
 
   std::string key_;
   std::vector<char> data_[kNumStreams];  // User data.
diff --git a/net/disk_cache/simple/simple_entry_impl.cc b/net/disk_cache/simple/simple_entry_impl.cc
index 93e19639..e653bbe 100644
--- a/net/disk_cache/simple/simple_entry_impl.cc
+++ b/net/disk_cache/simple/simple_entry_impl.cc
@@ -1339,12 +1339,11 @@
 void SimpleEntryImpl::EntryOperationComplete(
     const CompletionCallback& completion_callback,
     const SimpleEntryStat& entry_stat,
-    std::unique_ptr<int> result) {
+    int result) {
   DCHECK(io_thread_checker_.CalledOnValidThread());
   DCHECK(synchronous_entry_);
   DCHECK_EQ(STATE_IO_PENDING, state_);
-  DCHECK(result);
-  if (*result < 0) {
+  if (result < 0) {
     state_ = STATE_FAILURE;
     MarkAsDoomed(DOOM_COMPLETED);
   } else {
@@ -1354,7 +1353,7 @@
 
   if (!completion_callback.is_null()) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(completion_callback, *result));
+        FROM_HERE, base::Bind(completion_callback, result));
   }
   RunNextOperationIfNeeded();
 }
@@ -1401,7 +1400,7 @@
                       CreateNetLogReadWriteCompleteCallback(*result));
   }
 
-  EntryOperationComplete(completion_callback, *entry_stat, std::move(result));
+  EntryOperationComplete(completion_callback, *entry_stat, *result);
 }
 
 void SimpleEntryImpl::WriteOperationComplete(
@@ -1423,7 +1422,7 @@
     crc32s_end_offset_[stream_index] = 0;
   }
 
-  EntryOperationComplete(completion_callback, *entry_stat, std::move(result));
+  EntryOperationComplete(completion_callback, *entry_stat, *result);
 }
 
 void SimpleEntryImpl::ReadSparseOperationComplete(
@@ -1441,7 +1440,7 @@
 
   SimpleEntryStat entry_stat(*last_used, last_modified_, data_size_,
                              sparse_data_size_);
-  EntryOperationComplete(completion_callback, entry_stat, std::move(result));
+  EntryOperationComplete(completion_callback, entry_stat, *result);
 }
 
 void SimpleEntryImpl::WriteSparseOperationComplete(
@@ -1457,7 +1456,7 @@
                       CreateNetLogReadWriteCompleteCallback(*result));
   }
 
-  EntryOperationComplete(completion_callback, *entry_stat, std::move(result));
+  EntryOperationComplete(completion_callback, *entry_stat, *result);
 }
 
 void SimpleEntryImpl::GetAvailableRangeOperationComplete(
@@ -1469,7 +1468,7 @@
 
   SimpleEntryStat entry_stat(last_used_, last_modified_, data_size_,
                              sparse_data_size_);
-  EntryOperationComplete(completion_callback, entry_stat, std::move(result));
+  EntryOperationComplete(completion_callback, entry_stat, *result);
 }
 
 void SimpleEntryImpl::DoomOperationComplete(
diff --git a/net/disk_cache/simple/simple_entry_impl.h b/net/disk_cache/simple/simple_entry_impl.h
index d7fc91f..a3e50098 100644
--- a/net/disk_cache/simple/simple_entry_impl.h
+++ b/net/disk_cache/simple/simple_entry_impl.h
@@ -271,7 +271,7 @@
   // |completion_callback| after updating state and dooming on errors.
   void EntryOperationComplete(const CompletionCallback& completion_callback,
                               const SimpleEntryStat& entry_stat,
-                              std::unique_ptr<int> result);
+                              int result);
 
   // Called after an asynchronous read. Updates |crc32s_| if possible.
   void ReadOperationComplete(
diff --git a/net/quic/chromium/crypto/proof_verifier_chromium.cc b/net/quic/chromium/crypto/proof_verifier_chromium.cc
index 47c3cad4..9f1f8b8f 100644
--- a/net/quic/chromium/crypto/proof_verifier_chromium.cc
+++ b/net/quic/chromium/crypto/proof_verifier_chromium.cc
@@ -518,36 +518,28 @@
     return false;
   }
 
-  crypto::SignatureVerifier verifier;
-
   size_t size_bits;
   X509Certificate::PublicKeyType type;
   X509Certificate::GetPublicKeyInfo(cert_->cert_buffer(), &size_bits, &type);
-  if (type == X509Certificate::kPublicKeyTypeRSA) {
-    crypto::SignatureVerifier::HashAlgorithm hash_alg =
-        crypto::SignatureVerifier::SHA256;
-    crypto::SignatureVerifier::HashAlgorithm mask_hash_alg = hash_alg;
-    unsigned int hash_len = 32;  // 32 is the length of a SHA-256 hash.
+  crypto::SignatureVerifier::SignatureAlgorithm algorithm;
+  switch (type) {
+    case X509Certificate::kPublicKeyTypeRSA:
+      algorithm = crypto::SignatureVerifier::RSA_PSS_SHA256;
+      break;
+    case X509Certificate::kPublicKeyTypeECDSA:
+      algorithm = crypto::SignatureVerifier::ECDSA_SHA256;
+      break;
+    default:
+      LOG(ERROR) << "Unsupported public key type " << type;
+      return false;
+  }
 
-    bool ok = verifier.VerifyInitRSAPSS(
-        hash_alg, mask_hash_alg, hash_len,
-        reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
-        reinterpret_cast<const uint8_t*>(spki.data()), spki.size());
-    if (!ok) {
-      DLOG(WARNING) << "VerifyInitRSAPSS failed";
-      return false;
-    }
-  } else if (type == X509Certificate::kPublicKeyTypeECDSA) {
-    if (!verifier.VerifyInit(crypto::SignatureVerifier::ECDSA_SHA256,
-                             reinterpret_cast<const uint8_t*>(signature.data()),
-                             signature.size(),
-                             reinterpret_cast<const uint8_t*>(spki.data()),
-                             spki.size())) {
-      DLOG(WARNING) << "VerifyInit failed";
-      return false;
-    }
-  } else {
-    LOG(ERROR) << "Unsupported public key type " << type;
+  crypto::SignatureVerifier verifier;
+  if (!verifier.VerifyInit(
+          algorithm, reinterpret_cast<const uint8_t*>(signature.data()),
+          signature.size(), reinterpret_cast<const uint8_t*>(spki.data()),
+          spki.size())) {
+    DLOG(WARNING) << "VerifyInit failed";
     return false;
   }
 
diff --git a/sandbox/win/src/app_container_test.cc b/sandbox/win/src/app_container_test.cc
index 7167354..edd15ad 100644
--- a/sandbox/win/src/app_container_test.cc
+++ b/sandbox/win/src/app_container_test.cc
@@ -210,6 +210,8 @@
   EXPECT_EQ(SBOX_ERROR_BAD_PARAMS,
             policy_->SetIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED));
   EXPECT_EQ(SBOX_ERROR_BAD_PARAMS, policy_->SetLowBox(kAppContainerSid));
+  EXPECT_EQ(SBOX_ERROR_BAD_PARAMS,
+            policy_->SetProcessMitigations(MITIGATION_HEAP_TERMINATE));
 }
 
 TEST_F(AppContainerProfileTest, NoCapabilities) {
diff --git a/sandbox/win/src/process_mitigations.cc b/sandbox/win/src/process_mitigations.cc
index c6c2d38..54c756a 100644
--- a/sandbox/win/src/process_mitigations.cc
+++ b/sandbox/win/src/process_mitigations.cc
@@ -431,20 +431,22 @@
   return true;
 }
 
+MitigationFlags GetAllowedPostStartupProcessMitigations() {
+  return MITIGATION_HEAP_TERMINATE | MITIGATION_DEP |
+         MITIGATION_DEP_NO_ATL_THUNK | MITIGATION_RELOCATE_IMAGE |
+         MITIGATION_RELOCATE_IMAGE_REQUIRED | MITIGATION_BOTTOM_UP_ASLR |
+         MITIGATION_STRICT_HANDLE_CHECKS | MITIGATION_EXTENSION_POINT_DISABLE |
+         MITIGATION_DLL_SEARCH_ORDER | MITIGATION_HARDEN_TOKEN_IL_POLICY |
+         MITIGATION_WIN32K_DISABLE | MITIGATION_DYNAMIC_CODE_DISABLE |
+         MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT |
+         MITIGATION_FORCE_MS_SIGNED_BINS | MITIGATION_NONSYSTEM_FONT_DISABLE |
+         MITIGATION_IMAGE_LOAD_NO_REMOTE | MITIGATION_IMAGE_LOAD_NO_LOW_LABEL |
+         MITIGATION_IMAGE_LOAD_PREFER_SYS32;
+}
+
 bool CanSetProcessMitigationsPostStartup(MitigationFlags flags) {
   // All of these mitigations can be enabled after startup.
-  return !(
-      flags &
-      ~(MITIGATION_HEAP_TERMINATE | MITIGATION_DEP |
-        MITIGATION_DEP_NO_ATL_THUNK | MITIGATION_RELOCATE_IMAGE |
-        MITIGATION_RELOCATE_IMAGE_REQUIRED | MITIGATION_BOTTOM_UP_ASLR |
-        MITIGATION_STRICT_HANDLE_CHECKS | MITIGATION_EXTENSION_POINT_DISABLE |
-        MITIGATION_DLL_SEARCH_ORDER | MITIGATION_HARDEN_TOKEN_IL_POLICY |
-        MITIGATION_WIN32K_DISABLE | MITIGATION_DYNAMIC_CODE_DISABLE |
-        MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT |
-        MITIGATION_FORCE_MS_SIGNED_BINS | MITIGATION_NONSYSTEM_FONT_DISABLE |
-        MITIGATION_IMAGE_LOAD_NO_REMOTE | MITIGATION_IMAGE_LOAD_NO_LOW_LABEL |
-        MITIGATION_IMAGE_LOAD_PREFER_SYS32));
+  return !(flags & ~GetAllowedPostStartupProcessMitigations());
 }
 
 bool CanSetProcessMitigationsPreStartup(MitigationFlags flags) {
diff --git a/sandbox/win/src/process_mitigations.h b/sandbox/win/src/process_mitigations.h
index 5d9b667..cf1844a 100644
--- a/sandbox/win/src/process_mitigations.h
+++ b/sandbox/win/src/process_mitigations.h
@@ -38,6 +38,9 @@
 bool ApplyProcessMitigationsToSuspendedProcess(HANDLE process,
                                                MitigationFlags flags);
 
+// Returns the list of process mitigations which can be enabled post startup.
+MitigationFlags GetAllowedPostStartupProcessMitigations();
+
 // Returns true if all the supplied flags can be set after a process starts.
 bool CanSetProcessMitigationsPostStartup(MitigationFlags flags);
 
diff --git a/sandbox/win/src/sandbox_policy_base.cc b/sandbox/win/src/sandbox_policy_base.cc
index 9ce4308c..eeea52afa 100644
--- a/sandbox/win/src/sandbox_policy_base.cc
+++ b/sandbox/win/src/sandbox_policy_base.cc
@@ -267,7 +267,7 @@
 }
 
 ResultCode PolicyBase::SetIntegrityLevel(IntegrityLevel integrity_level) {
-  if (_app_container_profile)
+  if (app_container_profile_)
     return SBOX_ERROR_BAD_PARAMS;
   integrity_level_ = integrity_level;
   return SBOX_ALL_OK;
@@ -288,7 +288,7 @@
     return SBOX_ERROR_UNSUPPORTED;
 
   DCHECK(sid);
-  if (lowbox_sid_ || _app_container_profile)
+  if (lowbox_sid_ || app_container_profile_)
     return SBOX_ERROR_BAD_PARAMS;
 
   if (!ConvertStringSidToSid(sid, &lowbox_sid_))
@@ -298,7 +298,7 @@
 }
 
 ResultCode PolicyBase::SetProcessMitigations(MitigationFlags flags) {
-  if (!CanSetProcessMitigationsPreStartup(flags))
+  if (app_container_profile_ || !CanSetProcessMitigationsPreStartup(flags))
     return SBOX_ERROR_BAD_PARAMS;
   mitigations_ = flags;
   return SBOX_ALL_OK;
@@ -603,16 +603,23 @@
     return SBOX_ERROR_UNSUPPORTED;
 
   DCHECK(profile);
-  if (lowbox_sid_ || _app_container_profile ||
+  if (lowbox_sid_ || app_container_profile_ ||
       integrity_level_ != INTEGRITY_LEVEL_LAST)
     return SBOX_ERROR_BAD_PARAMS;
 
-  _app_container_profile = profile;
+  app_container_profile_ = profile;
+  // A bug exists in CreateProcess where enabling an AppContainer profile and
+  // passing a set of mitigation flags will generate ERROR_INVALID_PARAMETER.
+  // Apply best efforts here and convert set mitigations to delayed mitigations.
+  delayed_mitigations_ =
+      mitigations_ & GetAllowedPostStartupProcessMitigations();
+  DCHECK(delayed_mitigations_ == (mitigations_ & ~MITIGATION_SEHOP));
+  mitigations_ = 0;
   return SBOX_ALL_OK;
 }
 
 scoped_refptr<AppContainerProfile> PolicyBase::GetAppContainerProfile() {
-  return _app_container_profile;
+  return app_container_profile_;
 }
 
 ResultCode PolicyBase::SetupAllInterceptions(TargetProcess* target) {
diff --git a/sandbox/win/src/sandbox_policy_base.h b/sandbox/win/src/sandbox_policy_base.h
index fddea2b..3414ab1 100644
--- a/sandbox/win/src/sandbox_policy_base.h
+++ b/sandbox/win/src/sandbox_policy_base.h
@@ -174,7 +174,7 @@
   base::HandlesToInheritVector handles_to_share_;
   bool enable_opm_redirection_;
 
-  scoped_refptr<AppContainerProfile> _app_container_profile;
+  scoped_refptr<AppContainerProfile> app_container_profile_;
 
   DISALLOW_COPY_AND_ASSIGN(PolicyBase);
 };
diff --git a/services/network/public/cpp/BUILD.gn b/services/network/public/cpp/BUILD.gn
index 880892a..1238fbd 100644
--- a/services/network/public/cpp/BUILD.gn
+++ b/services/network/public/cpp/BUILD.gn
@@ -24,6 +24,9 @@
     "net_adapters.h",
     "network_switches.cc",
     "network_switches.h",
+    "simple_url_loader.cc",
+    "simple_url_loader.h",
+    "simple_url_loader_stream_consumer.h",
   ]
 
   public_deps = [
@@ -103,6 +106,7 @@
     "mutable_partial_network_traffic_annotation_tag_struct_traits_unittest.cc",
     "network_struct_traits_unittest.cc",
     "proxy_config_traits_unittest.cc",
+    "simple_url_loader_unittest.cc",
   ]
   deps = [
     ":cpp",
@@ -111,6 +115,7 @@
     "//mojo/public/cpp/bindings",
     "//net",
     "//net:test_support",
+    "//services/network:network_service",
     "//testing/gtest",
   ]
 }
diff --git a/content/public/common/simple_url_loader.cc b/services/network/public/cpp/simple_url_loader.cc
similarity index 92%
rename from content/public/common/simple_url_loader.cc
rename to services/network/public/cpp/simple_url_loader.cc
index 8a2b8b08..83cdf29 100644
--- a/content/public/common/simple_url_loader.cc
+++ b/services/network/public/cpp/simple_url_loader.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/public/common/simple_url_loader.h"
+#include "services/network/public/cpp/simple_url_loader.h"
 
 #include <stdint.h>
 
@@ -24,7 +24,6 @@
 #include "base/task_scheduler/post_task.h"
 #include "base/task_scheduler/task_traits.h"
 #include "base/threading/sequenced_task_runner_handle.h"
-#include "content/public/common/simple_url_loader_stream_consumer.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
 #include "mojo/public/cpp/system/data_pipe.h"
@@ -36,11 +35,12 @@
 #include "services/network/public/cpp/data_element.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/resource_response.h"
+#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
 #include "services/network/public/interfaces/data_pipe_getter.mojom.h"
 #include "services/network/public/interfaces/url_loader.mojom.h"
 #include "services/network/public/interfaces/url_loader_factory.mojom.h"
 
-namespace content {
+namespace network {
 
 const size_t SimpleURLLoader::kMaxBoundedStringDownloadSize = 1024 * 1024;
 const size_t SimpleURLLoader::kMaxUploadStringSizeToCopy = 256 * 1024;
@@ -65,7 +65,7 @@
 // StringUploadDataPipeGetter is a class to stream a string upload body to the
 // network service, rather than to copy it all at once.
 
-class StringUploadDataPipeGetter : public network::mojom::DataPipeGetter {
+class StringUploadDataPipeGetter : public mojom::DataPipeGetter {
  public:
   explicit StringUploadDataPipeGetter(const std::string& upload_string)
       : upload_string_(upload_string) {}
@@ -73,7 +73,7 @@
 
   // Returns a DataPipeGetterPtr for a new upload attempt, closing all
   // previously opened pipes.
-  network::mojom::DataPipeGetterPtr GetPtrForNewUpload() {
+  mojom::DataPipeGetterPtr GetPtrForNewUpload() {
     // If this is a retry, need to close all bindings, since only one consumer
     // can read from the data pipe at a time.
     binding_set_.CloseAllBindings();
@@ -81,7 +81,7 @@
     // any pending reads.
     ResetBodyPipe();
 
-    network::mojom::DataPipeGetterPtr data_pipe_getter;
+    mojom::DataPipeGetterPtr data_pipe_getter;
     binding_set_.AddBinding(this, mojo::MakeRequest(&data_pipe_getter));
     return data_pipe_getter;
   }
@@ -108,7 +108,7 @@
     WriteData();
   }
 
-  void Clone(network::mojom::DataPipeGetterRequest request) override {
+  void Clone(mojom::DataPipeGetterRequest request) override {
     binding_set_.AddBinding(this, std::move(request));
   }
 
@@ -160,7 +160,7 @@
     write_position_ = 0;
   }
 
-  mojo::BindingSet<network::mojom::DataPipeGetter> binding_set_;
+  mojo::BindingSet<mojom::DataPipeGetter> binding_set_;
 
   mojo::ScopedDataPipeProducerHandle upload_body_pipe_;
   // Must be below |write_pipe_|, so it's deleted first.
@@ -175,31 +175,30 @@
 class BodyHandler;
 
 class SimpleURLLoaderImpl : public SimpleURLLoader,
-                            public network::mojom::URLLoaderClient {
+                            public mojom::URLLoaderClient {
  public:
-  SimpleURLLoaderImpl(
-      std::unique_ptr<network::ResourceRequest> resource_request,
-      const net::NetworkTrafficAnnotationTag& annotation_tag);
+  SimpleURLLoaderImpl(std::unique_ptr<ResourceRequest> resource_request,
+                      const net::NetworkTrafficAnnotationTag& annotation_tag);
   ~SimpleURLLoaderImpl() override;
 
   // SimpleURLLoader implementation.
-  void DownloadToString(network::mojom::URLLoaderFactory* url_loader_factory,
+  void DownloadToString(mojom::URLLoaderFactory* url_loader_factory,
                         BodyAsStringCallback body_as_string_callback,
                         size_t max_body_size) override;
   void DownloadToStringOfUnboundedSizeUntilCrashAndDie(
-      network::mojom::URLLoaderFactory* url_loader_factory,
+      mojom::URLLoaderFactory* url_loader_factory,
       BodyAsStringCallback body_as_string_callback) override;
   void DownloadToFile(
-      network::mojom::URLLoaderFactory* url_loader_factory,
+      mojom::URLLoaderFactory* url_loader_factory,
       DownloadToFileCompleteCallback download_to_file_complete_callback,
       const base::FilePath& file_path,
       int64_t max_body_size) override;
   void DownloadToTempFile(
-      network::mojom::URLLoaderFactory* url_loader_factory,
+      mojom::URLLoaderFactory* url_loader_factory,
       DownloadToFileCompleteCallback download_to_file_complete_callback,
       int64_t max_body_size) override;
   void DownloadAsStream(
-      network::mojom::URLLoaderFactory* url_loader_factory,
+      mojom::URLLoaderFactory* url_loader_factory,
       SimpleURLLoaderStreamConsumer* stream_consumer) override;
   void SetOnRedirectCallback(
       const OnRedirectCallback& on_redirect_callback) override;
@@ -211,15 +210,15 @@
                            const std::string& upload_content_type) override;
   void SetRetryOptions(int max_retries, int retry_mode) override;
   int NetError() const override;
-  const network::ResourceResponseHead* ResponseInfo() const override;
+  const ResourceResponseHead* ResponseInfo() const override;
 
   // Called by BodyHandler when the BodyHandler body handler is done. If |error|
   // is not net::OK, some error occurred reading or consuming the body. If it is
   // net::OK, the pipe was closed and all data received was successfully
   // handled. This could indicate an error, concellation, or completion. To
   // determine which case this is, the size will also be compared to the size
-  // reported in network::URLLoaderCompletionStatus(), if
-  // network::URLLoaderCompletionStatus indicates a success.
+  // reported in URLLoaderCompletionStatus(), if
+  // URLLoaderCompletionStatus indicates a success.
   void OnBodyHandlerDone(net::Error error, int64_t received_body_size);
 
   // Finished the request with the provided error code, after freeing Mojo
@@ -236,7 +235,7 @@
 
     bool request_completed = false;
     // The expected total size of the body, taken from
-    // network::URLLoaderCompletionStatus.
+    // URLLoaderCompletionStatus.
     int64_t expected_body_size = 0;
 
     bool body_started = false;
@@ -251,28 +250,26 @@
     // Result of the request.
     int net_error = net::ERR_IO_PENDING;
 
-    std::unique_ptr<network::ResourceResponseHead> response_info;
+    std::unique_ptr<ResourceResponseHead> response_info;
   };
 
   // Prepares internal state to start a request, and then calls StartRequest().
   // Only used for the initial request (Not retries).
-  void Start(network::mojom::URLLoaderFactory* url_loader_factory);
+  void Start(mojom::URLLoaderFactory* url_loader_factory);
 
   // Starts a request. Used for both the initial request and retries, if any.
-  void StartRequest(network::mojom::URLLoaderFactory* url_loader_factory);
+  void StartRequest(mojom::URLLoaderFactory* url_loader_factory);
 
   // Re-initializes state of |this| and |body_handler_| prior to retrying a
   // request.
   void Retry();
 
-  // network::mojom::URLLoaderClient implementation;
-  void OnReceiveResponse(
-      const network::ResourceResponseHead& response_head,
-      const base::Optional<net::SSLInfo>& ssl_info,
-      network::mojom::DownloadedTempFilePtr downloaded_file) override;
-  void OnReceiveRedirect(
-      const net::RedirectInfo& redirect_info,
-      const network::ResourceResponseHead& response_head) override;
+  // mojom::URLLoaderClient implementation;
+  void OnReceiveResponse(const ResourceResponseHead& response_head,
+                         const base::Optional<net::SSLInfo>& ssl_info,
+                         mojom::DownloadedTempFilePtr downloaded_file) override;
+  void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
+                         const ResourceResponseHead& response_head) override;
   void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override;
   void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override;
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
@@ -281,7 +278,7 @@
                         OnUploadProgressCallback ack_callback) override;
   void OnStartLoadingResponseBody(
       mojo::ScopedDataPipeConsumerHandle body) override;
-  void OnComplete(const network::URLLoaderCompletionStatus& status) override;
+  void OnComplete(const URLLoaderCompletionStatus& status) override;
 
   // Choose the TaskPriority based on |resource_request_|'s net priority.
   // TODO(mmenke): Can something better be done here?
@@ -319,15 +316,15 @@
 
   // Populated in the constructor, and cleared once no longer needed, when no
   // more retries are possible.
-  std::unique_ptr<network::ResourceRequest> resource_request_;
+  std::unique_ptr<ResourceRequest> resource_request_;
   const net::NetworkTrafficAnnotationTag annotation_tag_;
   // Cloned from the input URLLoaderFactory if it may be needed to follow
   // redirects.
-  network::mojom::URLLoaderFactoryPtr url_loader_factory_ptr_;
+  mojom::URLLoaderFactoryPtr url_loader_factory_ptr_;
   std::unique_ptr<BodyHandler> body_handler_;
 
-  mojo::Binding<network::mojom::URLLoaderClient> client_binding_;
-  network::mojom::URLLoaderPtr url_loader_;
+  mojo::Binding<mojom::URLLoaderClient> client_binding_;
+  mojom::URLLoaderPtr url_loader_;
 
   std::unique_ptr<StringUploadDataPipeGetter> string_upload_data_pipe_getter_;
 
@@ -1005,7 +1002,7 @@
 };
 
 SimpleURLLoaderImpl::SimpleURLLoaderImpl(
-    std::unique_ptr<network::ResourceRequest> resource_request,
+    std::unique_ptr<ResourceRequest> resource_request,
     const net::NetworkTrafficAnnotationTag& annotation_tag)
     : resource_request_(std::move(resource_request)),
       annotation_tag_(annotation_tag),
@@ -1016,15 +1013,15 @@
   DETACH_FROM_SEQUENCE(sequence_checker_);
 #if DCHECK_IS_ON()
   if (resource_request_->request_body) {
-    for (const network::DataElement& element :
+    for (const DataElement& element :
          *resource_request_->request_body->elements()) {
       // Files should be attached with AttachFileForUpload, so that (Once
       // supported) they can be opened in the current process.
       //
       // TODO(mmenke): Add a similar method for bytes, to allow streaming of
       // large byte buffers to the network process when uploading.
-      DCHECK(element.type() != network::DataElement::TYPE_FILE &&
-             element.type() != network::DataElement::TYPE_BYTES);
+      DCHECK(element.type() != DataElement::TYPE_FILE &&
+             element.type() != DataElement::TYPE_BYTES);
     }
   }
 #endif  // DCHECK_IS_ON()
@@ -1033,7 +1030,7 @@
 SimpleURLLoaderImpl::~SimpleURLLoaderImpl() {}
 
 void SimpleURLLoaderImpl::DownloadToString(
-    network::mojom::URLLoaderFactory* url_loader_factory,
+    mojom::URLLoaderFactory* url_loader_factory,
     BodyAsStringCallback body_as_string_callback,
     size_t max_body_size) {
   DCHECK_LE(max_body_size, kMaxBoundedStringDownloadSize);
@@ -1043,18 +1040,18 @@
 }
 
 void SimpleURLLoaderImpl::DownloadToStringOfUnboundedSizeUntilCrashAndDie(
-    network::mojom::URLLoaderFactory* url_loader_factory,
+    mojom::URLLoaderFactory* url_loader_factory,
     BodyAsStringCallback body_as_string_callback) {
   body_handler_ = std::make_unique<SaveToStringBodyHandler>(
       this, std::move(body_as_string_callback),
-      // int64_t because network::URLLoaderCompletionStatus::decoded_body_length
+      // int64_t because URLLoaderCompletionStatus::decoded_body_length
       // is an int64_t, not a size_t.
       std::numeric_limits<int64_t>::max());
   Start(url_loader_factory);
 }
 
 void SimpleURLLoaderImpl::DownloadToFile(
-    network::mojom::URLLoaderFactory* url_loader_factory,
+    mojom::URLLoaderFactory* url_loader_factory,
     DownloadToFileCompleteCallback download_to_file_complete_callback,
     const base::FilePath& file_path,
     int64_t max_body_size) {
@@ -1066,7 +1063,7 @@
 }
 
 void SimpleURLLoaderImpl::DownloadToTempFile(
-    network::mojom::URLLoaderFactory* url_loader_factory,
+    mojom::URLLoaderFactory* url_loader_factory,
     DownloadToFileCompleteCallback download_to_file_complete_callback,
     int64_t max_body_size) {
   body_handler_ = std::make_unique<SaveToFileBodyHandler>(
@@ -1076,7 +1073,7 @@
 }
 
 void SimpleURLLoaderImpl::DownloadAsStream(
-    network::mojom::URLLoaderFactory* url_loader_factory,
+    mojom::URLLoaderFactory* url_loader_factory,
     SimpleURLLoaderStreamConsumer* stream_consumer) {
   body_handler_ =
       std::make_unique<DownloadAsStreamBodyHandler>(this, stream_consumer);
@@ -1109,7 +1106,7 @@
   DCHECK(resource_request_->method != "GET" &&
          resource_request_->method != "HEAD");
 
-  resource_request_->request_body = new network::ResourceRequestBody();
+  resource_request_->request_body = new ResourceRequestBody();
 
   if (upload_data.length() <= kMaxUploadStringSizeToCopy) {
     int copy_length = static_cast<int>(upload_data.length());
@@ -1139,7 +1136,7 @@
 
   // Create an empty body to make DCHECKing that there's no upload body yet
   // simpler.
-  resource_request_->request_body = new network::ResourceRequestBody();
+  resource_request_->request_body = new ResourceRequestBody();
   // TODO(mmenke): Open the file in the current process and append the file
   // handle instead of the file path.
   resource_request_->request_body->AppendFileRange(
@@ -1161,13 +1158,13 @@
 
 #if DCHECK_IS_ON()
   if (max_retries > 0 && resource_request_->request_body) {
-    for (const network::DataElement& element :
+    for (const DataElement& element :
          *resource_request_->request_body->elements()) {
       // Data pipes are single-use, so can't retry uploads when there's a data
       // pipe.
       // TODO(mmenke):  Data pipes can be Cloned(), though, so maybe update code
       // to do that?
-      DCHECK(element.type() != network::DataElement::TYPE_DATA_PIPE);
+      DCHECK(element.type() != DataElement::TYPE_DATA_PIPE);
     }
   }
 #endif  // DCHECK_IS_ON()
@@ -1180,7 +1177,7 @@
   return request_state_->net_error;
 }
 
-const network::ResourceResponseHead* SimpleURLLoaderImpl::ResponseInfo() const {
+const ResourceResponseHead* SimpleURLLoaderImpl::ResponseInfo() const {
   // Should only be called once the request is compelete.
   DCHECK(request_state_->finished);
   return request_state_->response_info.get();
@@ -1220,8 +1217,7 @@
   body_handler_->NotifyConsumerOfCompletion(destroy_results);
 }
 
-void SimpleURLLoaderImpl::Start(
-    network::mojom::URLLoaderFactory* url_loader_factory) {
+void SimpleURLLoaderImpl::Start(mojom::URLLoaderFactory* url_loader_factory) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(resource_request_);
   // It's illegal to use a single SimpleURLLoaderImpl to make multiple requests.
@@ -1241,11 +1237,11 @@
 }
 
 void SimpleURLLoaderImpl::StartRequest(
-    network::mojom::URLLoaderFactory* url_loader_factory) {
+    mojom::URLLoaderFactory* url_loader_factory) {
   DCHECK(resource_request_);
   DCHECK(url_loader_factory);
 
-  network::mojom::URLLoaderClientPtr client_ptr;
+  mojom::URLLoaderClientPtr client_ptr;
   client_binding_.Bind(mojo::MakeRequest(&client_ptr));
   client_binding_.set_connection_error_handler(base::BindOnce(
       &SimpleURLLoaderImpl::OnConnectionError, base::Unretained(this)));
@@ -1253,8 +1249,8 @@
   // code doesn't call the Clone() method), so need to create another one, if
   // uploading a string via a data pipe.
   if (string_upload_data_pipe_getter_) {
-    resource_request_->request_body = new network::ResourceRequestBody();
-    network::mojom::DataPipeGetterPtr data_pipe_getter;
+    resource_request_->request_body = new ResourceRequestBody();
+    mojom::DataPipeGetterPtr data_pipe_getter;
     resource_request_->request_body->AppendDataPipe(
         string_upload_data_pipe_getter_->GetPtrForNewUpload());
   }
@@ -1287,9 +1283,9 @@
 }
 
 void SimpleURLLoaderImpl::OnReceiveResponse(
-    const network::ResourceResponseHead& response_head,
+    const ResourceResponseHead& response_head,
     const base::Optional<net::SSLInfo>& ssl_info,
-    network::mojom::DownloadedTempFilePtr downloaded_file) {
+    mojom::DownloadedTempFilePtr downloaded_file) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (request_state_->response_info) {
     // The final headers have already been received, so the URLLoader is
@@ -1314,14 +1310,14 @@
   }
 
   request_state_->response_info =
-      std::make_unique<network::ResourceResponseHead>(response_head);
+      std::make_unique<ResourceResponseHead>(response_head);
   if (!allow_http_error_results_ && response_code / 100 != 2)
     FinishWithResult(net::ERR_FAILED);
 }
 
 void SimpleURLLoaderImpl::OnReceiveRedirect(
     const net::RedirectInfo& redirect_info,
-    const network::ResourceResponseHead& response_head) {
+    const ResourceResponseHead& response_head) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (request_state_->response_info) {
     // If the headers have already been received, the URLLoader is violating the
@@ -1372,8 +1368,7 @@
   body_handler_->OnStartLoadingResponseBody(std::move(body));
 }
 
-void SimpleURLLoaderImpl::OnComplete(
-    const network::URLLoaderCompletionStatus& status) {
+void SimpleURLLoaderImpl::OnComplete(const URLLoaderCompletionStatus& status) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // Request should not have been completed yet.
   DCHECK(!request_state_->finished);
@@ -1447,7 +1442,7 @@
       request_state_->net_error = net::ERR_FAILED;
     } else {
       // The caller provided more data through the pipe than it reported in
-      // network::URLLoaderCompletionStatus, so the URLLoader is violating the
+      // URLLoaderCompletionStatus, so the URLLoader is violating the
       // API contract. Just fail the request.
       request_state_->net_error = net::ERR_UNEXPECTED;
     }
@@ -1459,7 +1454,7 @@
 }  // namespace
 
 std::unique_ptr<SimpleURLLoader> SimpleURLLoader::Create(
-    std::unique_ptr<network::ResourceRequest> resource_request,
+    std::unique_ptr<ResourceRequest> resource_request,
     const net::NetworkTrafficAnnotationTag& annotation_tag) {
   DCHECK(resource_request);
   return std::make_unique<SimpleURLLoaderImpl>(std::move(resource_request),
@@ -1470,4 +1465,4 @@
 
 SimpleURLLoader::SimpleURLLoader() {}
 
-}  // namespace content
+}  // namespace network
diff --git a/content/public/common/simple_url_loader.h b/services/network/public/cpp/simple_url_loader.h
similarity index 90%
rename from content/public/common/simple_url_loader.h
rename to services/network/public/cpp/simple_url_loader.h
index ec3463b7..e330795 100644
--- a/content/public/common/simple_url_loader.h
+++ b/services/network/public/cpp/simple_url_loader.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_PUBLIC_COMMON_SIMPLE_URL_LOADER_H_
-#define CONTENT_PUBLIC_COMMON_SIMPLE_URL_LOADER_H_
+#ifndef SERVICES_NETWORK_PUBLIC_CPP_SIMPLE_URL_LOADER_H_
+#define SERVICES_NETWORK_PUBLIC_CPP_SIMPLE_URL_LOADER_H_
 
 #include <stdint.h>
 
@@ -12,8 +12,8 @@
 #include <string>
 
 #include "base/callback_forward.h"
+#include "base/component_export.h"
 #include "base/macros.h"
-#include "content/common/content_export.h"
 
 namespace base {
 class FilePath;
@@ -32,7 +32,7 @@
 }
 }  // namespace network
 
-namespace content {
+namespace network {
 
 class SimpleURLLoaderStreamConsumer;
 
@@ -53,7 +53,7 @@
 // * Maybe some sort of retry backoff or delay?  ServiceURLLoaderContext enables
 // throttling for its URLFetchers.  Could additionally/alternatively support
 // 503 + Retry-After.
-class CONTENT_EXPORT SimpleURLLoader {
+class COMPONENT_EXPORT(NETWORK_CPP) SimpleURLLoader {
  public:
   // When a failed request should automatically be retried. These are intended
   // to be ORed together.
@@ -90,15 +90,15 @@
 
   // Callback used when a redirect is being followed. It is safe to delete the
   // SimpleURLLoader during the callback.
-  using OnRedirectCallback = base::RepeatingCallback<void(
-      const net::RedirectInfo& redirect_info,
-      const network::ResourceResponseHead& response_head)>;
+  using OnRedirectCallback =
+      base::RepeatingCallback<void(const net::RedirectInfo& redirect_info,
+                                   const ResourceResponseHead& response_head)>;
 
   // Creates a SimpleURLLoader for |resource_request|. The request can be
   // started by calling any one of the Download methods once. The loader may not
   // be reused.
   static std::unique_ptr<SimpleURLLoader> Create(
-      std::unique_ptr<network::ResourceRequest> resource_request,
+      std::unique_ptr<ResourceRequest> resource_request,
       const net::NetworkTrafficAnnotationTag& annotation_tag);
 
   virtual ~SimpleURLLoader();
@@ -115,10 +115,9 @@
   // invoked on completion. Deleting the SimpleURLLoader before the callback is
   // invoked will result in cancelling the request, and the callback will not be
   // called.
-  virtual void DownloadToString(
-      network::mojom::URLLoaderFactory* url_loader_factory,
-      BodyAsStringCallback body_as_string_callback,
-      size_t max_body_size) = 0;
+  virtual void DownloadToString(mojom::URLLoaderFactory* url_loader_factory,
+                                BodyAsStringCallback body_as_string_callback,
+                                size_t max_body_size) = 0;
 
   // Same as DownloadToString, but downloads to a buffer of unbounded size,
   // potentially causing a crash if the amount of addressable memory is
@@ -126,7 +125,7 @@
   // instead (DownloadToString if the body is expected to be of reasonable
   // length, or DownloadToFile otherwise).
   virtual void DownloadToStringOfUnboundedSizeUntilCrashAndDie(
-      network::mojom::URLLoaderFactory* url_loader_factory,
+      mojom::URLLoaderFactory* url_loader_factory,
       BodyAsStringCallback body_as_string_callback) = 0;
 
   // SimpleURLLoader will download the entire response to a file at the
@@ -143,7 +142,7 @@
   // downloaded file will be deleted asynchronously and the callback will not be
   // invoked, regardless of other settings.
   virtual void DownloadToFile(
-      network::mojom::URLLoaderFactory* url_loader_factory,
+      mojom::URLLoaderFactory* url_loader_factory,
       DownloadToFileCompleteCallback download_to_file_complete_callback,
       const base::FilePath& file_path,
       int64_t max_body_size = std::numeric_limits<int64_t>::max()) = 0;
@@ -151,7 +150,7 @@
   // Same as DownloadToFile, but creates a temporary file instead of taking a
   // FilePath.
   virtual void DownloadToTempFile(
-      network::mojom::URLLoaderFactory* url_loader_factory,
+      mojom::URLLoaderFactory* url_loader_factory,
       DownloadToFileCompleteCallback download_to_file_complete_callback,
       int64_t max_body_size = std::numeric_limits<int64_t>::max()) = 0;
 
@@ -165,7 +164,7 @@
   // deleted, or the handler's OnComplete() method has been invoked by the
   // SimpleURLLoader.
   virtual void DownloadAsStream(
-      network::mojom::URLLoaderFactory* url_loader_factory,
+      mojom::URLLoaderFactory* url_loader_factory,
       SimpleURLLoaderStreamConsumer* stream_consumer) = 0;
 
   // Sets callback to be invoked during redirects. Callback may delete the
@@ -248,7 +247,7 @@
   // The ResourceResponseHead for the request. Will be nullptr if ResponseInfo
   // was never received. May only be called once the loader has informed the
   // caller of completion.
-  virtual const network::ResourceResponseHead* ResponseInfo() const = 0;
+  virtual const ResourceResponseHead* ResponseInfo() const = 0;
 
  protected:
   SimpleURLLoader();
@@ -257,6 +256,6 @@
   DISALLOW_COPY_AND_ASSIGN(SimpleURLLoader);
 };
 
-}  // namespace content
+}  // namespace network
 
-#endif  // CONTENT_PUBLIC_COMMON_SIMPLE_URL_LOADER_H_
+#endif  // SERVICES_NETWORK_PUBLIC_CPP_SIMPLE_URL_LOADER_H_
diff --git a/content/public/common/simple_url_loader_stream_consumer.h b/services/network/public/cpp/simple_url_loader_stream_consumer.h
similarity index 87%
rename from content/public/common/simple_url_loader_stream_consumer.h
rename to services/network/public/cpp/simple_url_loader_stream_consumer.h
index 8559755..5fb1a411 100644
--- a/content/public/common/simple_url_loader_stream_consumer.h
+++ b/services/network/public/cpp/simple_url_loader_stream_consumer.h
@@ -2,22 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_PUBLIC_COMMON_SIMPLE_URL_LOADER_STREAM_CONSUMER_H_
-#define CONTENT_PUBLIC_COMMON_SIMPLE_URL_LOADER_STREAM_CONSUMER_H_
+#ifndef SERVICES_NETWORK_PUBLIC_CPP_SIMPLE_URL_LOADER_STREAM_CONSUMER_H_
+#define SERVICES_NETWORK_PUBLIC_CPP_SIMPLE_URL_LOADER_STREAM_CONSUMER_H_
 
 #include "base/callback_forward.h"
+#include "base/component_export.h"
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
-#include "content/common/content_export.h"
 
-namespace content {
+namespace network {
 
 // Interface to handle streaming data from SimpleURLLoader. All methods are
 // invoked on the sequence the SimpleURLLoader was started on, and all callbacks
 // must be invoked on the same sequence. The SimpleURLLoader may be deleted at
 // any time. None of these methods will be called during SimpleURLLoader
 // destruction.
-class CONTENT_EXPORT SimpleURLLoaderStreamConsumer {
+class COMPONENT_EXPORT(NETWORK_CPP) SimpleURLLoaderStreamConsumer {
  public:
   // Called as body data is received.
   //
@@ -66,6 +66,6 @@
   DISALLOW_COPY_AND_ASSIGN(SimpleURLLoaderStreamConsumer);
 };
 
-}  // namespace content
+}  // namespace network
 
-#endif  // CONTENT_PUBLIC_COMMON_SIMPLE_URL_LOADER_STREAM_CONSUMER_H_
+#endif  // SERVICES_NETWORK_PUBLIC_CPP_SIMPLE_URL_LOADER_STREAM_CONSUMER_H_
diff --git a/content/public/common/simple_url_loader_unittest.cc b/services/network/public/cpp/simple_url_loader_unittest.cc
similarity index 99%
rename from content/public/common/simple_url_loader_unittest.cc
rename to services/network/public/cpp/simple_url_loader_unittest.cc
index f3acd31..22a7bae2 100644
--- a/content/public/common/simple_url_loader_unittest.cc
+++ b/services/network/public/cpp/simple_url_loader_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/public/common/simple_url_loader.h"
+#include "services/network/public/cpp/simple_url_loader.h"
 
 #include <stdint.h>
 
@@ -26,9 +26,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/scoped_task_environment.h"
-#include "content/public/common/service_manager_connection.h"
-#include "content/public/common/service_names.mojom.h"
-#include "content/public/common/simple_url_loader_stream_consumer.h"
 #include "mojo/public/c/system/types.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
@@ -45,13 +42,14 @@
 #include "services/network/network_service.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/resource_response.h"
+#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
 #include "services/network/public/cpp/url_loader_completion_status.h"
 #include "services/network/public/interfaces/network_service.mojom.h"
 #include "services/network/public/interfaces/url_loader_factory.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
-namespace content {
+namespace network {
 namespace {
 
 // Server path that returns a response containing as many a's as are specified
@@ -555,7 +553,7 @@
   static base::FilePath GetTestFilePath() {
     base::FilePath test_data_dir;
     base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir);
-    return test_data_dir.AppendASCII("content/test/data/title1.html");
+    return test_data_dir.AppendASCII("services/test/data/title1.html");
   }
 
   static std::string GetTestFileContents() {
@@ -2531,4 +2529,4 @@
 }
 
 }  // namespace
-}  // namespace content
+}  // namespace network
diff --git a/services/test/BUILD.gn b/services/test/BUILD.gn
index ceaf5836..7bd581f 100644
--- a/services/test/BUILD.gn
+++ b/services/test/BUILD.gn
@@ -65,6 +65,7 @@
     "//services/test/data/redirect307-to-echo",
     "//services/test/data/redirect307-to-echo.mock-http-headers",
     "//services/test/data/simple_page.html",
+    "//services/test/data/title1.html",
   ]
   outputs = [
     "{{bundle_resources_dir}}/" +
diff --git a/services/test/data/title1.html b/services/test/data/title1.html
new file mode 100644
index 0000000..2526072
--- /dev/null
+++ b/services/test/data/title1.html
@@ -0,0 +1,4 @@
+<html>
+<head></head>
+<body>This page has no title.</body>
+</html>
diff --git a/sql/connection_unittest.cc b/sql/connection_unittest.cc
index a9b60d44..0d4e2df 100644
--- a/sql/connection_unittest.cc
+++ b/sql/connection_unittest.cc
@@ -26,10 +26,6 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/sqlite/sqlite3.h"
 
-#if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE)
-#include "base/ios/ios_util.h"
-#endif  // defined(OS_IOS) && defined(USE_SYSTEM_SQLITE)
-
 namespace sql {
 namespace test {
 
diff --git a/sql/recovery.cc b/sql/recovery.cc
index e0541038..7e9dcca 100644
--- a/sql/recovery.cc
+++ b/sql/recovery.cc
@@ -238,7 +238,7 @@
   }
 
   // Enable the recover virtual table for this connection.
-  int rc = recoverVtableInit(recover_db_.db_);
+  int rc = chrome_sqlite3_recoverVtableInit(recover_db_.db_);
   if (rc != SQLITE_OK) {
     RecordRecoveryEvent(RECOVERY_FAILED_VIRTUAL_TABLE_INIT);
     LOG(ERROR) << "Failed to initialize recover module: "
diff --git a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
index b31a8a2..de5e938 100644
--- a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
+++ b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
@@ -48,6 +48,7 @@
 -DevToolsDownloadContentTest.SingleDownload
 -DevToolsProtocolTest.ControlNavigationsMainFrame
 -DevToolsProtocolTest.SubresourceWithCertificateError
+-DownloadContentTest.Resume_Hash
 -GetUserMediaVideoCaptureBrowserTest.RecoverFromCrashInVideoCaptureProcess
 -IsolatedDevToolsProtocolTest.ControlNavigationsChildFrames
 -IsolateIcelandFrameTreeBrowserTest.ProcessSwitchForIsolatedBlob
diff --git a/testing/libfuzzer/proto/BUILD.gn b/testing/libfuzzer/proto/BUILD.gn
index 52af8df..861e8e65 100644
--- a/testing/libfuzzer/proto/BUILD.gn
+++ b/testing/libfuzzer/proto/BUILD.gn
@@ -55,9 +55,8 @@
     #  Can't disable instrumentation because of container-overflow false
     # positives.
 
-    # Assertion failures in skia are uninteresting. Don't use debug builds on
-    # CF.
-    if (is_debug) {
+    # Assertion failures and integer oveflows in skia are uninteresting.
+    if (is_debug || is_ubsan) {
       all_dependent_configs = [ "//testing/libfuzzer:no_clusterfuzz" ]
     }
   }
diff --git a/testing/libfuzzer/proto/skia_image_filter_proto_converter.cc b/testing/libfuzzer/proto/skia_image_filter_proto_converter.cc
index bbdd38d..784db20 100644
--- a/testing/libfuzzer/proto/skia_image_filter_proto_converter.cc
+++ b/testing/libfuzzer/proto/skia_image_filter_proto_converter.cc
@@ -195,10 +195,10 @@
                                             1, 2, 2, 3, 2, 3, 3, 4};
 
 // The rest of the Converter attributes are not copied from skia.
-const int Converter::kFlattenableDepthLimit = 4;
+const int Converter::kFlattenableDepthLimit = 3;
 const int Converter::kColorTableBufferLength = 256;
 uint8_t Converter::kColorTableBuffer[kColorTableBufferLength];
-const int Converter::kNumBound = 50;
+const int Converter::kNumBound = 20;
 const uint8_t Converter::kMutateEnumDenominator = 40;
 
 // Does not include SkSumPathEffect, SkComposePathEffect or SkRegion
diff --git a/third_party/.gitignore b/third_party/.gitignore
index 61ccf3d..b1e8717 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -64,6 +64,7 @@
 /freetype/src
 /fuchsia-sdk
 /gestures/gestures
+/gles1_conform
 /gles2_conform
 /glslang/src
 /glslang-angle/src
diff --git a/third_party/SPIRV-Tools/BUILD.gn b/third_party/SPIRV-Tools/BUILD.gn
index 227e109..807ec23 100644
--- a/third_party/SPIRV-Tools/BUILD.gn
+++ b/third_party/SPIRV-Tools/BUILD.gn
@@ -189,6 +189,9 @@
 
   all_dependent_configs = [ ":SPIRV-Tools_config" ]
 
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [ "//build/config/compiler:no_chromium_code" ]
+
   deps = [
     ":build_version_inc",
     ":core_tables_1-0",
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 6b23b95a..dcdb01e3 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -25,6 +25,11 @@
 # Assert in ng_box_fragment_painter.cc(327)
 crbug.com/626703 fast/multicol/multicol-becomes-paged-auto-height.html [ Crash ]
 
+# Different on bots and local, needs rebaselines.
+crbug.com/591099 fast/canvas/fillrect_gradient.html [ Failure ]
+crbug.com/591099 fast/text/justify-nbsp.html [ Failure ]
+crbug.com/591099 fast/css3-text/css3-text-justify/text-justify-8bits.html [ Failure ]
+
 # New passes
 crbug.com/626703 external/wpt/css/css-ui/text-overflow-021.html [ Failure ]
 crbug.com/492664 external/wpt/css/css-writing-modes/inline-block-alignment-003.xht [ Pass ]
@@ -118,7 +123,6 @@
 crbug.com/591099 animations/animation-ready-reject-script-forbidden.html [ Timeout ]
 crbug.com/591099 animations/cross-fade-list-style-image.html [ Failure ]
 crbug.com/591099 animations/interpolation/backdrop-filter-interpolation.html [ Timeout ]
-crbug.com/591099 animations/interpolation/border-image-width-interpolation.html [ Pass Timeout ]
 crbug.com/591099 animations/interpolation/line-height-interpolation.html [ Pass Timeout ]
 crbug.com/591099 animations/interpolation/svg-stroke-dasharray-interpolation.html [ Timeout ]
 crbug.com/591099 animations/interpolation/webkit-clip-path-interpolation.html [ Pass Timeout ]
@@ -276,7 +280,6 @@
 crbug.com/591099 compositing/squashing/squashed-layer-loses-graphicslayer.html [ Failure ]
 crbug.com/591099 compositing/squashing/vertical-writing-mode-squashed.html [ Failure ]
 crbug.com/591099 compositing/text-on-large-layer.html [ Failure ]
-crbug.com/714962 compositing/transitions/transform-on-large-layer.html [ Failure Pass ]
 crbug.com/591099 crypto/subtle/hkdf/cloneKey.html [ Timeout ]
 crbug.com/591099 crypto/subtle/hmac/cloneKey.html [ Timeout ]
 crbug.com/591099 crypto/subtle/pbkdf2/cloneKey.html [ Timeout ]
@@ -833,7 +836,7 @@
 crbug.com/591099 editing/execCommand/insertNewLineInQuotedContent-outside-quote.html [ Failure ]
 crbug.com/591099 editing/execCommand/outdent-multiparagraph-list.html [ Failure ]
 crbug.com/591099 editing/execCommand/query-command-state.html [ Timeout ]
-crbug.com/591099 editing/execCommand/query-format-block.html [ Pass Timeout ]
+crbug.com/591099 editing/execCommand/query-format-block.html [ Timeout ]
 crbug.com/591099 editing/execCommand/queryCommandState-02.html [ Failure ]
 crbug.com/591099 editing/execCommand/remove-list-from-range-selection.html [ Failure ]
 crbug.com/591099 editing/execCommand/replaceSelectorCommand-crash.html [ Crash ]
@@ -964,7 +967,7 @@
 crbug.com/591099 editing/selection/extend-selection-bidi.html [ Failure ]
 crbug.com/591099 editing/selection/extend-selection-character.html [ Timeout ]
 crbug.com/591099 editing/selection/extend-selection-home-end.html [ Timeout ]
-crbug.com/591099 editing/selection/extend-selection-word.html [ Pass Timeout ]
+crbug.com/591099 editing/selection/extend-selection-word.html [ Timeout ]
 crbug.com/591099 editing/selection/focus-body.html [ Failure ]
 crbug.com/591099 editing/selection/home-end.html [ Timeout ]
 crbug.com/591099 editing/selection/inactive-selection.html [ Failure ]
@@ -1109,9 +1112,9 @@
 crbug.com/714962 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-color-5.html [ Failure ]
 crbug.com/714962 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-5.html [ Failure ]
 crbug.com/714962 external/wpt/css/css-backgrounds/background-image-003.html [ Failure ]
-crbug.com/714962 external/wpt/css/css-backgrounds/background-image-004.html [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-backgrounds/background-image-004.html [ Failure ]
 crbug.com/714962 external/wpt/css/css-backgrounds/background-image-005.html [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-backgrounds/background-image-006.html [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-backgrounds/background-image-006.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-display/display-contents-details.html [ Crash ]
 crbug.com/714962 external/wpt/css/css-display/display-contents-dynamic-before-after-001.html [ Failure ]
 crbug.com/714962 external/wpt/css/css-display/display-contents-dynamic-before-after-first-letter-001.html [ Failure ]
@@ -1445,6 +1448,8 @@
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-013.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-014.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-022.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-ui/text-overflow-027.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-ui/text-overflow-029.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vlr-003.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vlr-011.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vlr-033.xht [ Pass ]
@@ -1458,7 +1463,7 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vrl-020.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vrl-030.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-003.xht [ Failure Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-005.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-005.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-007.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-009.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-011.xht [ Failure ]
@@ -1469,7 +1474,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-021.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-023.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-025.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-027.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-027.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-029.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-031.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-033.xht [ Failure Pass ]
@@ -1483,7 +1488,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-049.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-051.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-053.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-055.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-055.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-057.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-059.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-061.xht [ Failure ]
@@ -1491,28 +1496,28 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-065.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-067.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-069.xht [ Failure Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-071.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-073.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-075.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-071.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-073.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-075.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-077.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-079.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-079.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-081.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-083.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-083.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-085.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-087.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-089.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-091.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-091.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-093.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-095.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-097.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-103.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-105.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-107.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-107.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-109.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-111.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-113.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-115.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-117.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-117.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-119.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-121.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-123.xht [ Failure ]
@@ -1522,7 +1527,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-131.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-133.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-135.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-137.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-137.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-139.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-141.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-143.xht [ Failure ]
@@ -1531,7 +1536,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-149.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-151.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-153.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-155.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-155.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-157.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-159.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-161.xht [ Failure ]
@@ -1549,17 +1554,17 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-185.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-187.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-189.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-191.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-191.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-193.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-195.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-197.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-199.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-201.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-201.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-203.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-205.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-207.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-209.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-211.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-211.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-213.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-215.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-217.xht [ Failure Pass ]
@@ -1567,13 +1572,13 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-221.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-223.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-225.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-227.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-227.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-229.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-004.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-006.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-008.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-010.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-010.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-012.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-014.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-016.xht [ Failure ]
@@ -1582,7 +1587,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-022.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-024.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-026.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-028.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-028.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-030.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-032.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-034.xht [ Failure ]
@@ -1606,7 +1611,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-070.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-072.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-074.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-076.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-076.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-078.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-080.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-082.xht [ Failure ]
@@ -1646,13 +1651,13 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-154.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-156.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-158.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-160.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-160.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-162.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-164.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-166.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-168.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-170.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-172.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-172.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-174.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-176.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-178.xht [ Failure ]
@@ -1678,7 +1683,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-218.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-220.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-222.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-224.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-224.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-226.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-228.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/available-size-001.html [ Failure ]
@@ -1701,7 +1706,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-003.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-005.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-002.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-004.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-006.xht [ Failure ]
@@ -1778,7 +1783,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-003.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-005.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-007.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-009.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-009.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-align-vlr-011.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-013.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-015.xht [ Failure ]
@@ -1787,7 +1792,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-002.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-004.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-006.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-008.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-008.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-010.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-012.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-014.xht [ Failure ]
@@ -1801,7 +1806,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-005.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-011.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-013.xht [ Failure Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-002.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-006.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-008.xht [ Failure ]
@@ -2061,7 +2066,7 @@
 crbug.com/591099 external/wpt/html/syntax/parsing/html5lib_tests2.html?run_type=write [ Pass ]
 crbug.com/591099 external/wpt/html/syntax/parsing/html5lib_tests2.html?run_type=write_single [ Pass ]
 crbug.com/591099 external/wpt/html/syntax/parsing/named-character-references.html [ Timeout ]
-crbug.com/591099 external/wpt/html/the-xhtml-syntax/parsing-xhtml-documents/xhtml-mathml-dtd-entity-1.htm [ Timeout ]
+crbug.com/591099 external/wpt/html/the-xhtml-syntax/parsing-xhtml-documents/xhtml-mathml-dtd-entity-1.htm [ Pass Timeout ]
 crbug.com/591099 external/wpt/html/the-xhtml-syntax/parsing-xhtml-documents/xhtml-mathml-dtd-entity-4.htm [ Pass Timeout ]
 crbug.com/591099 external/wpt/html/the-xhtml-syntax/parsing-xhtml-documents/xhtml-mathml-dtd-entity-7.htm [ Pass Timeout ]
 crbug.com/591099 external/wpt/html/the-xhtml-syntax/parsing-xhtml-documents/xhtml-mathml-dtd-entity-8.htm [ Timeout ]
@@ -2131,7 +2136,7 @@
 crbug.com/591099 external/wpt/wasm/wasm_local_iframe_test.html [ Failure ]
 crbug.com/591099 external/wpt/webmessaging/broadcastchannel/sandbox.html [ Failure ]
 crbug.com/591099 external/wpt/webrtc/interfaces.html [ Pass Timeout ]
-crbug.com/591099 external/wpt/webrtc/interfaces.https.html [ Timeout ]
+crbug.com/591099 external/wpt/webrtc/interfaces.https.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/websockets/binary/001.html?wss [ Pass ]
 crbug.com/591099 external/wpt/websockets/binary/002.html?wss [ Pass ]
 crbug.com/591099 external/wpt/websockets/binary/004.html?wss [ Pass ]
@@ -2180,7 +2185,6 @@
 crbug.com/591099 external/wpt/websockets/opening-handshake/002.html?wss [ Pass ]
 crbug.com/591099 external/wpt/websockets/opening-handshake/003.html?wss [ Pass Timeout ]
 crbug.com/591099 external/wpt/websockets/opening-handshake/005.html [ Pass ]
-crbug.com/591099 external/wpt/websockets/opening-handshake/005.html?wss [ Pass ]
 crbug.com/591099 external/wpt/websockets/unload-a-document/001.html [ Pass ]
 crbug.com/591099 external/wpt/websockets/unload-a-document/001.html?wss [ Pass ]
 crbug.com/591099 external/wpt/webstorage/storage_setitem.html [ Pass Timeout ]
@@ -3084,7 +3088,7 @@
 crbug.com/591099 fast/events/keypress-focus-change.html [ Failure ]
 crbug.com/591099 fast/events/media-element-focus-tab.html [ Failure ]
 crbug.com/591099 fast/events/menu-key-context-menu-document-pinch-zoom.html [ Failure ]
-crbug.com/714962 fast/events/middleClickAutoscroll-latching.html [ Timeout ]
+crbug.com/714962 fast/events/middleClickAutoscroll-latching.html [ Pass Timeout ]
 crbug.com/714962 fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure ]
 crbug.com/591099 fast/events/mouse-drag-from-frame-to-other-frame.html [ Failure ]
 crbug.com/591099 fast/events/mouse-event-buttons-attribute.html [ Timeout ]
@@ -3144,7 +3148,6 @@
 crbug.com/714962 fast/events/touch/gesture/gesture-tap-input-after-composition.html [ Failure ]
 crbug.com/714962 fast/events/touch/gesture/gesture-tap-mouse-events.html [ Failure ]
 crbug.com/714962 fast/events/touch/gesture/gesture-tap-result.html [ Failure ]
-crbug.com/591099 fast/events/touch/scroll-without-mouse-lacks-mousemove-events.html [ Failure Pass ]
 crbug.com/591099 fast/events/touch/touch-action-range-input-csp.html [ Timeout ]
 crbug.com/591099 fast/events/touch/touch-action-range-input.html [ Timeout ]
 crbug.com/714962 fast/events/touch/touch-before-pressing-spin-button.html [ Failure ]
@@ -3164,7 +3167,6 @@
 crbug.com/591099 fast/files/apply-blob-url-to-img.html [ Timeout ]
 crbug.com/591099 fast/files/file-in-input-display.html [ Timeout ]
 crbug.com/591099 fast/forms/001.html [ Failure ]
-crbug.com/591099 fast/forms/006.html [ Failure ]
 crbug.com/591099 fast/forms/007.html [ Failure ]
 crbug.com/714962 fast/forms/25153.html [ Failure ]
 crbug.com/591099 fast/forms/ValidityState-customError.html [ Failure ]
@@ -3180,7 +3182,6 @@
 crbug.com/591099 fast/forms/button-state-restore.html [ Failure ]
 crbug.com/591099 fast/forms/button-style-color.html [ Failure ]
 crbug.com/591099 fast/forms/button-table-styles.html [ Failure ]
-crbug.com/591099 fast/forms/button-text-transform.html [ Failure ]
 crbug.com/591099 fast/forms/button/button-align.html [ Failure ]
 crbug.com/591099 fast/forms/button/button-baseline-and-collapsing.html [ Failure ]
 crbug.com/591099 fast/forms/button/button-click-DOM.html [ Failure ]
@@ -3188,7 +3189,6 @@
 crbug.com/591099 fast/forms/button/button-inner-block-reuse.html [ Failure ]
 crbug.com/591099 fast/forms/button/button-type-change.html [ Failure ]
 crbug.com/591099 fast/forms/button/button-white-space.html [ Failure ]
-crbug.com/591099 fast/forms/calendar-picker/calendar-picker-appearance-zoom125.html [ Failure ]
 crbug.com/591099 fast/forms/calendar-picker/calendar-picker-key-operations.html [ Pass Timeout ]
 crbug.com/714962 fast/forms/calendar-picker/calendar-picker-mouse-operations.html [ Failure ]
 crbug.com/714962 fast/forms/calendar-picker/calendar-picker-type-change-onclick.html [ Timeout ]
@@ -3199,7 +3199,6 @@
 crbug.com/591099 fast/forms/caret-rtl.html [ Failure ]
 crbug.com/591099 fast/forms/checkbox/checkbox-appearance-basic.html [ Failure ]
 crbug.com/714962 fast/forms/checkbox/checkbox-focus-by-mouse.html [ Failure ]
-crbug.com/591099 fast/forms/color/input-appearance-color.html [ Failure ]
 crbug.com/714962 fast/forms/color/input-color-chooser-shown-readonly.html [ Timeout ]
 crbug.com/714962 fast/forms/color/input-color-chooser-shown.html [ Timeout ]
 crbug.com/591099 fast/forms/color/input-color-onchange-event.html [ Failure ]
@@ -3207,21 +3206,16 @@
 crbug.com/591099 fast/forms/control-clip.html [ Failure ]
 crbug.com/591099 fast/forms/control-restrict-line-height.html [ Failure ]
 crbug.com/591099 fast/forms/datalist/input-appearance-range-with-datalist-zoomed.html [ Failure ]
-crbug.com/591099 fast/forms/datalist/input-appearance-range-with-padding-with-datalist.html [ Failure ]
-crbug.com/591099 fast/forms/datalist/input-appearance-range-with-transform.html [ Failure ]
 crbug.com/591099 fast/forms/datalist/range-snap-to-datalist.html [ Failure ]
 crbug.com/714962 fast/forms/date-multiple-fields/date-clearbutton-preventdefault-mousecapture-status.html [ Failure ]
 crbug.com/714962 fast/forms/date-multiple-fields/date-multiple-fields-clearbutton-change-and-input-events.html [ Failure ]
 crbug.com/714962 fast/forms/date-multiple-fields/date-multiple-fields-mouse-events.html [ Failure ]
 crbug.com/714962 fast/forms/date-multiple-fields/date-multiple-fields-spinbutton-change-and-input-events.html [ Failure ]
 crbug.com/591099 fast/forms/date-multiple-fields/date-multiple-fields-wheel-event.html [ Failure ]
-crbug.com/591099 fast/forms/date/date-appearance-basic.html [ Failure ]
-crbug.com/591099 fast/forms/date/date-appearance-pseudo-elements.html [ Failure ]
 crbug.com/714962 fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-clearbutton-change-and-input-events.html [ Failure ]
 crbug.com/714962 fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-mouse-events.html [ Failure ]
 crbug.com/714962 fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-spinbutton-change-and-input-events.html [ Failure ]
 crbug.com/591099 fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-wheel-event.html [ Failure ]
-crbug.com/591099 fast/forms/datetimelocal/datetimelocal-appearance-basic.html [ Failure ]
 crbug.com/714962 fast/forms/disabled-mousedown-event.html [ Failure ]
 crbug.com/591099 fast/forms/encoding-test.html [ Failure ]
 crbug.com/591099 fast/forms/fieldset/fieldset-crash.html [ Failure ]
@@ -3249,7 +3243,6 @@
 crbug.com/591099 fast/forms/focus-selection-textarea.html [ Failure ]
 crbug.com/591099 fast/forms/focus-style-pending.html [ Failure ]
 crbug.com/591099 fast/forms/form-attribute-elements-order.html [ Failure ]
-crbug.com/591099 fast/forms/form-element-geometry.html [ Failure ]
 crbug.com/591099 fast/forms/form-hides-table.html [ Failure ]
 crbug.com/591099 fast/forms/form-in-malformed-markup.html [ Failure ]
 crbug.com/591099 fast/forms/form-radio-node-list.html [ Failure ]
@@ -3262,7 +3255,6 @@
 crbug.com/591099 fast/forms/image-border.html [ Failure ]
 crbug.com/591099 fast/forms/image/002.html [ Failure ]
 crbug.com/591099 fast/forms/image/005.html [ Failure ]
-crbug.com/591099 fast/forms/image/image-alt-text.html [ Failure ]
 crbug.com/591099 fast/forms/image/image-error-event-modifies-type-crash.html [ Failure ]
 crbug.com/591099 fast/forms/image/input-align-image.html [ Failure ]
 crbug.com/591099 fast/forms/indeterminate.html [ Failure ]
@@ -3290,8 +3282,6 @@
 crbug.com/714962 fast/forms/month-multiple-fields/month-multiple-fields-mouse-events.html [ Failure ]
 crbug.com/714962 fast/forms/month-multiple-fields/month-multiple-fields-spinbutton-change-and-input-events.html [ Failure ]
 crbug.com/591099 fast/forms/month-multiple-fields/month-multiple-fields-wheel-event.html [ Failure ]
-crbug.com/591099 fast/forms/month/month-appearance-basic.html [ Failure ]
-crbug.com/591099 fast/forms/month/month-appearance-pseudo-elements.html [ Failure ]
 crbug.com/591099 fast/forms/negativeLineHeight.html [ Failure ]
 crbug.com/591099 fast/forms/number/number-appearance-datalist.html [ Failure ]
 crbug.com/591099 fast/forms/number/number-appearance-spinbutton-disabled-readonly.html [ Failure ]
@@ -3307,8 +3297,6 @@
 crbug.com/591099 fast/forms/number/number-wheel-event.html [ Failure ]
 crbug.com/591099 fast/forms/onselect-textfield.html [ Failure ]
 crbug.com/591099 fast/forms/output/htmloutputelement.html [ Failure ]
-crbug.com/591099 fast/forms/placeholder-position.html [ Failure ]
-crbug.com/591099 fast/forms/plaintext-mode-2.html [ Failure ]
 crbug.com/591099 fast/forms/preserveFormDuringResidualStyle.html [ Failure ]
 crbug.com/591099 fast/forms/radio-checkbox-restore-indeterminate.html [ Failure ]
 crbug.com/591099 fast/forms/radio/radio-appearance-basic.html [ Failure ]
@@ -3338,7 +3326,6 @@
 crbug.com/591099 fast/forms/range/slider-mouse-events.html [ Failure ]
 crbug.com/591099 fast/forms/range/slider-onchange-event.html [ Failure ]
 crbug.com/591099 fast/forms/range/slider-padding.html [ Failure ]
-crbug.com/591099 fast/forms/range/slider-thumb-shared-style.html [ Failure ]
 crbug.com/591099 fast/forms/range/slider-thumb-stylability.html [ Failure ]
 crbug.com/591099 fast/forms/range/slider-zoomed.html [ Failure ]
 crbug.com/591099 fast/forms/range/thumbslider-no-parent-slider.html [ Failure ]
@@ -3361,8 +3348,6 @@
 crbug.com/591099 fast/forms/search/search-vertical-alignment.html [ Failure ]
 crbug.com/714962 fast/forms/search/search-zoomed.html [ Failure ]
 crbug.com/591099 fast/forms/search/searchfield-heights.html [ Failure ]
-crbug.com/714962 fast/forms/select-popup/popup-menu-appearance-transform.html [ Failure ]
-crbug.com/714962 fast/forms/select-popup/popup-menu-appearance-zoom.html [ Failure ]
 crbug.com/591099 fast/forms/select/003.html [ Failure ]
 crbug.com/591099 fast/forms/select/004.html [ Failure ]
 crbug.com/591099 fast/forms/select/HTMLOptionElement_label01.html [ Failure ]
@@ -3383,21 +3368,18 @@
 crbug.com/591099 fast/forms/select/listbox-drag-in-non-multiple.html [ Failure ]
 crbug.com/591099 fast/forms/select/listbox-in-multi-column.html [ Failure ]
 crbug.com/591099 fast/forms/select/listbox-onchange.html [ Failure ]
-crbug.com/591099 fast/forms/select/listbox-scrollbar-incremental-load.html [ Failure ]
 crbug.com/591099 fast/forms/select/listbox-selection-2.html [ Failure ]
 crbug.com/591099 fast/forms/select/listbox-selection.html [ Failure ]
 crbug.com/591099 fast/forms/select/listbox-tap-input-change-event.html [ Failure ]
 crbug.com/591099 fast/forms/select/listbox-tap.html [ Failure ]
 crbug.com/591099 fast/forms/select/listbox-width-change.html [ Failure ]
 crbug.com/591099 fast/forms/select/menulist-appearance-basic.html [ Failure ]
-crbug.com/591099 fast/forms/select/menulist-appearance-none.html [ Failure ]
 crbug.com/591099 fast/forms/select/menulist-appearance-rtl.html [ Failure ]
 crbug.com/591099 fast/forms/select/menulist-clip.html [ Failure ]
 crbug.com/591099 fast/forms/select/menulist-deselect-update.html [ Failure ]
 crbug.com/591099 fast/forms/select/menulist-narrow-width.html [ Failure ]
 crbug.com/591099 fast/forms/select/menulist-no-overflow.html [ Failure ]
 crbug.com/591099 fast/forms/select/menulist-no-renderer-onmousedown.html [ Failure ]
-crbug.com/591099 fast/forms/select/menulist-option-wrap.html [ Failure ]
 crbug.com/591099 fast/forms/select/menulist-restrict-line-height.html [ Failure ]
 crbug.com/591099 fast/forms/select/menulist-separator-painting.html [ Failure ]
 crbug.com/591099 fast/forms/select/menulist-style-color.html [ Failure ]
@@ -3407,8 +3389,6 @@
 crbug.com/591099 fast/forms/select/optgroup-rendering.html [ Failure ]
 crbug.com/591099 fast/forms/select/option-index.html [ Failure ]
 crbug.com/591099 fast/forms/select/option-relayout-modified-text.html [ Failure ]
-crbug.com/591099 fast/forms/select/option-script.html [ Failure ]
-crbug.com/591099 fast/forms/select/option-strip-whitespace.html [ Failure ]
 crbug.com/591099 fast/forms/select/option-text-clip.html [ Failure ]
 crbug.com/591099 fast/forms/select/popup-closes-on-blur.html [ Failure ]
 crbug.com/591099 fast/forms/select/popup-with-display-none-optgroup.html [ Failure ]
@@ -3416,22 +3396,17 @@
 crbug.com/591099 fast/forms/select/select-align.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-baseline.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-block-background.html [ Failure ]
-crbug.com/591099 fast/forms/select/select-change-listbox-size.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-change-listbox-to-popup.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-change-popup-to-listbox.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-clientheight-with-multiple-attr.html [ Failure ]
-crbug.com/591099 fast/forms/select/select-disabled-appearance.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-disabled.html [ Failure ]
-crbug.com/591099 fast/forms/select/select-display-none-style-resolve.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-empty-list.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-empty-option-height.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-generated-content.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-initial-position.html [ Failure ]
-crbug.com/591099 fast/forms/select/select-item-background-clip.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-list-box-with-height.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-live-pseudo-selectors.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-multiple-elements-with-mouse-drag-with-options-less-than-size.html [ Failure ]
-crbug.com/591099 fast/forms/select/select-multiple-rtl.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-overflow-scroll-inherited.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-overflow-scroll.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-popup-pagekeys.html [ Failure ]
@@ -3441,7 +3416,6 @@
 crbug.com/591099 fast/forms/select/select-style.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-visual-hebrew.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-with-display-none-options.html [ Failure ]
-crbug.com/591099 fast/forms/select/select-writing-direction-natural.html [ Failure ]
 crbug.com/591099 fast/forms/selection-direction.html [ Timeout ]
 crbug.com/591099 fast/forms/selection-functions.html [ Failure ]
 crbug.com/591099 fast/forms/selection-start-end-readonly.html [ Failure ]
@@ -3468,14 +3442,12 @@
 crbug.com/714962 fast/forms/suggestion-picker/week-suggestion-picker-appearance-with-scroll-bar.html [ Failure ]
 crbug.com/714962 fast/forms/suggestion-picker/week-suggestion-picker-appearance.html [ Failure ]
 crbug.com/591099 fast/forms/tabbing-input-iframe.html [ Failure ]
-crbug.com/591099 fast/forms/targeted-frame-submission.html [ Failure ]
 crbug.com/591099 fast/forms/text-control-intrinsic-widths.html [ Timeout ]
 crbug.com/591099 fast/forms/text-style-color.html [ Failure ]
 crbug.com/591099 fast/forms/text/input-appearance-bkcolor.html [ Failure ]
 crbug.com/591099 fast/forms/text/input-appearance-default-bkcolor.html [ Failure ]
 crbug.com/591099 fast/forms/text/input-appearance-disabled.html [ Failure ]
 crbug.com/591099 fast/forms/text/input-appearance-elementFromPoint.html [ Failure ]
-crbug.com/591099 fast/forms/text/input-appearance-focus.html [ Failure ]
 crbug.com/591099 fast/forms/text/input-appearance-preventDefault.html [ Failure ]
 crbug.com/591099 fast/forms/text/input-appearance-readonly.html [ Failure ]
 crbug.com/591099 fast/forms/text/input-appearance-selection.html [ Failure ]
@@ -3503,18 +3475,15 @@
 crbug.com/591099 fast/forms/text/input-text-double-click.html [ Failure ]
 crbug.com/591099 fast/forms/text/input-text-drag-down.html [ Failure ]
 crbug.com/591099 fast/forms/text/input-text-option-delete.html [ Failure ]
-crbug.com/591099 fast/forms/text/input-text-scroll-left-on-blur.html [ Failure ]
 crbug.com/591099 fast/forms/text/input-text-self-emptying-click.html [ Failure ]
 crbug.com/591099 fast/forms/text/input-text-word-wrap.html [ Failure ]
 crbug.com/591099 fast/forms/text/input-width.html [ Failure ]
 crbug.com/591099 fast/forms/text/text-appearance-basic.html [ Failure ]
 crbug.com/591099 fast/forms/text/text-appearance-datalist.html [ Failure ]
 crbug.com/591099 fast/forms/text/text-reset.html [ Failure ]
-crbug.com/591099 fast/forms/text/textfield-focus-ring.html [ Failure ]
 crbug.com/714962 fast/forms/text/textfield-inside-anchor.html [ Failure ]
 crbug.com/591099 fast/forms/text/textfield-outline.html [ Failure ]
 crbug.com/591099 fast/forms/text/textfield-overflow.html [ Failure ]
-crbug.com/591099 fast/forms/textarea/basic-textareas-quirks.html [ Failure ]
 crbug.com/591099 fast/forms/textarea/basic-textareas.html [ Failure ]
 crbug.com/591099 fast/forms/textarea/drag-into-textarea.html [ Failure ]
 crbug.com/714962 fast/forms/textarea/drag-out-of-textarea.html [ Failure ]
@@ -3548,17 +3517,12 @@
 crbug.com/591099 fast/forms/time-multiple-fields/time-multiple-fields-spinbutton-click-in-iframe.html [ Failure ]
 crbug.com/591099 fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer.html [ Timeout ]
 crbug.com/591099 fast/forms/time-multiple-fields/time-multiple-fields-wheel-event.html [ Failure ]
-crbug.com/591099 fast/forms/time/time-appearance-basic.html [ Failure ]
-crbug.com/591099 fast/forms/time/time-appearance-pseudo-elements.html [ Failure ]
 crbug.com/714962 fast/forms/type-after-focus-rule-shrink-width.html [ Timeout ]
-crbug.com/714962 fast/forms/validation-bubble-appearance-rtl-ui.html [ Failure ]
 crbug.com/591099 fast/forms/visual-hebrew-text-field.html [ Failure ]
 crbug.com/714962 fast/forms/week-multiple-fields/week-multiple-fields-clearbutton-change-and-input-events.html [ Failure ]
 crbug.com/714962 fast/forms/week-multiple-fields/week-multiple-fields-mouse-events.html [ Failure ]
 crbug.com/714962 fast/forms/week-multiple-fields/week-multiple-fields-spinbutton-change-and-input-events.html [ Failure ]
 crbug.com/591099 fast/forms/week-multiple-fields/week-multiple-fields-wheel-event.html [ Failure ]
-crbug.com/591099 fast/forms/week/week-appearance-basic.html [ Failure ]
-crbug.com/591099 fast/forms/week/week-appearance-pseudo-elements.html [ Failure ]
 crbug.com/591099 fast/frames/001.html [ Failure ]
 crbug.com/591099 fast/frames/002.html [ Failure ]
 crbug.com/591099 fast/frames/calculate-fixed.html [ Failure ]
@@ -3660,7 +3624,6 @@
 crbug.com/591099 fast/inline-block/vertical-align-top-and-bottom-2.html [ Failure ]
 crbug.com/591099 fast/inline/absolute-positioned-inline-in-centred-block.html [ Failure ]
 crbug.com/591099 fast/inline/bpm-inline-ancestors.html [ Failure ]
-crbug.com/591099 fast/inline/br-client-rect.html [ Failure Pass ]
 crbug.com/714962 fast/inline/continuation-outlines-with-layers-2.html [ Failure ]
 crbug.com/591099 fast/inline/continuation-outlines-with-layers.html [ Failure ]
 crbug.com/591099 fast/inline/continuation-outlines.html [ Failure ]
@@ -3723,7 +3686,6 @@
 crbug.com/591099 fast/layers/layer-visibility.html [ Failure ]
 crbug.com/591099 fast/layers/nested-layers-1.html [ Failure ]
 crbug.com/591099 fast/layers/opacity-outline.html [ Failure ]
-crbug.com/591099 fast/layers/opacity-transforms.html [ Failure ]
 crbug.com/591099 fast/layers/overflow-hidden-rounded-corners-occlusion.html [ Failure ]
 crbug.com/591099 fast/layers/overflow-scroll-auto-switch.html [ Failure ]
 crbug.com/591099 fast/layers/perspective-inline-no-display.html [ Failure ]
@@ -4577,7 +4539,7 @@
 crbug.com/591099 fast/table/percent-height-content-in-fixed-height-border-box-sized-cell-with-collapsed-border.html [ Failure ]
 crbug.com/591099 fast/table/percent-height-content-in-fixed-height-content-box-sized-cell.html [ Failure ]
 crbug.com/591099 fast/table/percent-height-overflow-auto-content-in-cell.html [ Failure Pass ]
-crbug.com/591099 fast/table/percent-height-overflow-scroll-content-in-cell.html [ Failure ]
+crbug.com/591099 fast/table/percent-height-overflow-scroll-content-in-cell.html [ Failure Pass ]
 crbug.com/591099 fast/table/percent-widths-stretch-vertical.html [ Failure ]
 crbug.com/591099 fast/table/recalc-section-first-body-crash-main.html [ Failure ]
 crbug.com/591099 fast/table/row-in-inline-block.html [ Failure ]
@@ -4949,7 +4911,7 @@
 crbug.com/591099 fullscreen/full-screen-css.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-element-stack.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-iframe-not-allowed.html [ Failure ]
-crbug.com/591099 fullscreen/full-screen-ruleset-crash.html [ Crash Pass ]
+crbug.com/591099 fullscreen/full-screen-ruleset-crash.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-twice-newapi.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-with-css-reference-filter.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-with-flex-item.html [ Crash ]
@@ -5069,7 +5031,7 @@
 crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-2.js [ Timeout ]
 crbug.com/714962 http/tests/devtools/editor/text-editor-enter-behaviour.js [ Timeout ]
 crbug.com/714962 http/tests/devtools/editor/text-editor-formatter.js [ Timeout ]
-crbug.com/714962 http/tests/devtools/editor/text-editor-indent-autodetection.js [ Timeout ]
+crbug.com/714962 http/tests/devtools/editor/text-editor-indent-autodetection.js [ Pass Timeout ]
 crbug.com/714962 http/tests/devtools/editor/text-editor-reveal-line.js [ Timeout ]
 crbug.com/591099 http/tests/devtools/editor/text-editor-word-jumps.js [ Timeout ]
 crbug.com/714962 http/tests/devtools/elements/breadcrumb-updates.js [ Crash ]
@@ -5142,7 +5104,6 @@
 crbug.com/714962 http/tests/devtools/elements/styles/undo-property-toggle.js [ Crash Pass ]
 crbug.com/714962 http/tests/devtools/elements/styles/undo-set-selector-text.js [ Crash ]
 crbug.com/591099 http/tests/devtools/extensions/extensions-sidebar.js [ Crash ]
-crbug.com/591099 http/tests/devtools/indexeddb/resources-panel.js [ Failure ]
 crbug.com/714962 http/tests/devtools/jump-to-previous-editing-location.js [ Failure ]
 crbug.com/714962 http/tests/devtools/layers/layer-canvas-log.js [ Failure ]
 crbug.com/591099 http/tests/devtools/network/network-datareceived.js [ Failure ]
@@ -5158,7 +5119,7 @@
 crbug.com/591099 http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/sources/debugger-pause/debugger-pause-on-promise-rejection.js [ Crash ]
-crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-into-custom-element-callbacks.js [ Crash ]
+crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-into-custom-element-callbacks.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Crash ]
@@ -5308,7 +5269,7 @@
 crbug.com/591099 http/tests/security/local-JavaScript-from-remote.html [ Failure ]
 crbug.com/591099 http/tests/security/local-iFrame-from-remote.html [ Failure ]
 crbug.com/591099 http/tests/security/local-image-from-remote.html [ Failure ]
-crbug.com/591099 http/tests/security/setDomainRelaxationForbiddenForURLScheme.html [ Crash Pass ]
+crbug.com/591099 http/tests/security/setDomainRelaxationForbiddenForURLScheme.html [ Crash ]
 crbug.com/591099 http/tests/security/shape-image-cors-allow-origin.html [ Failure ]
 crbug.com/591099 http/tests/security/shape-image-cors-data-url.html [ Failure ]
 crbug.com/591099 http/tests/security/shape-image-cors-same-origin.html [ Failure ]
@@ -5422,7 +5383,7 @@
 crbug.com/591099 images/webp-flip.html [ Failure ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-ignoredNodes.js [ Failure Timeout ]
 crbug.com/714962 inspector-protocol/accessibility/accessibility-ignoredNodesModal.js [ Failure ]
-crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-img-figure.js [ Pass Timeout ]
+crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-img-figure.js [ Timeout ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-input-buttons.js [ Timeout ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-input.js [ Timeout ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-labelledby.js [ Timeout ]
@@ -5460,7 +5421,6 @@
 crbug.com/714962 intersection-observer/text-target.html [ Failure ]
 crbug.com/591099 media/autoplay/document-user-activation.html [ Failure ]
 crbug.com/591099 media/controls/lazy-loaded-style.html [ Failure ]
-crbug.com/591099 media/controls/volumechange-muted-attribute.html [ Failure Pass ]
 crbug.com/714962 media/controls/volumechange-stopimmediatepropagation.html [ Failure Pass ]
 crbug.com/591099 media/media-document-audio-repaint.html [ Failure ]
 crbug.com/591099 media/video-aspect-ratio.html [ Failure ]
@@ -5808,7 +5768,7 @@
 crbug.com/591099 paint/invalidation/reflection/scroll-fixed-reflected-layer.html [ Failure ]
 crbug.com/591099 paint/invalidation/remove-block-after-layout.html [ Failure ]
 crbug.com/591099 paint/invalidation/remove-inline-after-layout.html [ Failure ]
-crbug.com/591099 paint/invalidation/remove-inline-layer-after-layout.html [ Crash Failure ]
+crbug.com/591099 paint/invalidation/remove-inline-layer-after-layout.html [ Crash ]
 crbug.com/591099 paint/invalidation/renderer-destruction-by-invalidateSelection-crash.html [ Failure ]
 crbug.com/714962 paint/invalidation/repaint-across-writing-mode-boundary.html [ Failure ]
 crbug.com/591099 paint/invalidation/repaint-descandant-on-ancestor-layer-move.html [ Failure ]
@@ -6343,7 +6303,6 @@
 crbug.com/714962 svg/batik/text/smallFonts.svg [ Failure ]
 crbug.com/714962 svg/batik/text/textAnchor.svg [ Failure ]
 crbug.com/714962 svg/canvas/canvas-pattern-svg.html [ Failure ]
-crbug.com/714962 svg/clip-path/clip-path-evenodd-nonzero.svg [ Failure Pass ]
 crbug.com/591099 svg/css/css-box-min-width.html [ Failure ]
 crbug.com/591099 svg/css/max-height.html [ Failure ]
 crbug.com/591099 svg/css/max-width.html [ Failure ]
@@ -6455,7 +6414,7 @@
 crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-hidden.xhtml [ Failure ]
 crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-scroll.xhtml [ Failure ]
 crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-visible.xhtml [ Failure ]
-crbug.com/591099 svg/parser/whitespace-length-invalid-1.html [ Timeout ]
+crbug.com/591099 svg/parser/whitespace-length-invalid-1.html [ Pass Timeout ]
 crbug.com/591099 svg/parser/whitespace-length-invalid-2.html [ Pass Timeout ]
 crbug.com/591099 svg/parser/whitespace-length-invalid-3.html [ Pass Timeout ]
 crbug.com/591099 svg/parser/whitespace-length-invalid-4.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v175 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v175
index 1e22463d..7ddaf2e 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v175
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v175
@@ -15,16 +15,10 @@
 # Subpixel differences
 crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-color-5.html [ Failure ]
 crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-5.html [ Failure ]
-# This will pass with --root-layer-scrolls.
-crbug.com/771643 scrollbars/custom-scrollbars-paint-outside-iframe.html [ Failure ]
 # Difficult ancestor clip mask issue.
 crbug.com/771643 virtual/prefer_compositing_to_lcd_text/compositing/overflow/nested-border-radius-clipping.html [ Failure ]
 
 crbug.com/805134 http/tests/devtools/tracing/scroll-invalidations.js [ Failure ]
 crbug.com/805134 virtual/threaded/http/tests/devtools/tracing/scroll-invalidations.js [ Failure ]
 
-crbug.com/711468 fast/frames/frame-set-scaling-rotate.html [ Failure ]
-crbug.com/711468 fast/frames/frame-set-scaling-skew.html [ Failure ]
-crbug.com/711468 fast/sub-pixel/should-not-repaint-subpixel-composited-layer.html [ Failure ]
 crbug.com/711468 plugins/webview-plugin-nested-iframe-scroll.html [ Failure ]
-crbug.com/711468 svg/hixie/perf/007.xml [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/NeverFixTests b/third_party/WebKit/LayoutTests/NeverFixTests
index 35181c8d..050a39cb 100644
--- a/third_party/WebKit/LayoutTests/NeverFixTests
+++ b/third_party/WebKit/LayoutTests/NeverFixTests
@@ -1828,6 +1828,11 @@
 crbug.com/254753 external/wpt/css/css-images/css-image-fallbacks-and-annotations004.html [ WontFix ]
 crbug.com/254753 external/wpt/css/css-images/css-image-fallbacks-and-annotations005.html [ WontFix ]
 
+# ::marker has not been implemented
+crbug.com/457718 external/wpt/css/css-pseudo/marker-and-other-pseudo-elements.html [ WontFix ]
+crbug.com/457718 external/wpt/css/css-pseudo/marker-color.html [ WontFix ]
+crbug.com/457718 external/wpt/css/css-pseudo/marker-font-properties.html [ WontFix ]
+
 # https://github.com/w3c/web-platform-tests/issues/8633
 external/wpt/css/css-style-attr/style-attr-braces-002-quirks.htm [ WontFix ]
 
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 6cfd57a..dccef02 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1663,6 +1663,11 @@
 
 crbug.com/604875 external/wpt/css/css-images/tiled-gradients.html [ Failure ]
 
+crbug.com/808834 [ Linux Win ] external/wpt/css/css-pseudo/first-letter-001.html [ Failure ]
+
+crbug.com/808837 [ Linux ] external/wpt/css/css-pseudo/first-letter-002.html [ Failure ]
+crbug.com/808837 [ Linux ] external/wpt/css/css-pseudo/first-letter-003.html [ Failure ]
+
 crbug.com/655458 crbug.com/721814 external/wpt/mediacapture-image/idlharness.html [ Skip ]
 crbug.com/626703 external/wpt/web-nfc/idlharness.https.html [ Skip ]
 
@@ -3286,15 +3291,11 @@
 #
 # These entries were copied from FlagExpectations/root-layer-scrolls
 ################################################################################
-crbug.com/417782 compositing/iframes/become-composited-nested-iframes.html [ Failure ]
 crbug.com/417782 compositing/overflow/tiled-mask.html [ Failure ]
-crbug.com/417782 compositing/squashing/squash-above-fixed-1.html [ Failure ]
-crbug.com/417782 compositing/squashing/squash-above-fixed-3.html [ Failure ]
 crbug.com/417782 compositing/visibility/visibility-image-layers-dynamic.html [ Failure ]
 crbug.com/417782 css3/filters/effect-reference-subregion-nested.html [ Failure ]
 crbug.com/417782 fast/css/sticky/replaced-sticky.html [ Failure ]
 crbug.com/417782 fast/css/sticky/sticky-style-change.html [ Failure ]
-crbug.com/417782 fast/events/scale-and-scroll-iframe-window.html [ Failure ]
 crbug.com/417782 fast/frames/iframe-scaling-with-scroll.html [ Failure ]
 crbug.com/417782 fast/overflow/scrollRevealButton.html [ Failure ]
 crbug.com/417782 fast/scroll-behavior/scroll-into-view-sticky.html [ Crash ]
@@ -3327,7 +3328,6 @@
 crbug.com/417782 [ Linux ] virtual/android/fullscreen/full-screen-iframe-allowed-video.html [ Failure ]
 crbug.com/417782 [ Linux ] virtual/android/fullscreen/video-controls-timeline.html [ Failure ]
 crbug.com/417782 [ Linux ] virtual/android/fullscreen/video-scrolled-iframe.html [ Failure ]
-crbug.com/417782 virtual/mouseevent_fractional/fast/events/scale-and-scroll-iframe-window.html [ Failure ]
 crbug.com/417782 virtual/prefer_compositing_to_lcd_text/compositing/overflow/tiled-mask.html [ Failure ]
 crbug.com/417782 virtual/scroll_customization/fast/events/touch/compositor-touch-hit-rects-iframes.html [ Failure ]
 crbug.com/417782 virtual/scroll_customization/fast/scroll-behavior/scroll-into-view-sticky.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations
index 92e60c3..b4f4b53 100644
--- a/third_party/WebKit/LayoutTests/W3CImportExpectations
+++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -89,7 +89,6 @@
 external/wpt/css/css-lists [ Skip ]
 external/wpt/css/css-masking [ Skip ]
 external/wpt/css/css-page [ Skip ]
-external/wpt/css/css-pseudo [ Skip ]
 external/wpt/css/css-regions [ Skip ]
 external/wpt/css/css-round-display [ Skip ]
 external/wpt/css/css-ruby [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/compositing/iframes/become-composited-nested-iframes-expected.txt b/third_party/WebKit/LayoutTests/compositing/iframes/become-composited-nested-iframes-expected.txt
index 9ac0b68b..3339f9a 100644
--- a/third_party/WebKit/LayoutTests/compositing/iframes/become-composited-nested-iframes-expected.txt
+++ b/third_party/WebKit/LayoutTests/compositing/iframes/become-composited-nested-iframes-expected.txt
@@ -3,6 +3,16 @@
   "layers": [
     {
       "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [785, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
       "bounds": [785, 1500],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
@@ -13,68 +23,34 @@
       "bounds": [284, 204]
     },
     {
-      "name": "Frame Overflow Controls Host Layer",
-      "position": [22, 122],
-      "bounds": [280, 200],
-      "drawsContent": false
-    },
-    {
-      "name": "Frame Clipping Layer",
-      "position": [22, 122],
-      "bounds": [280, 200],
-      "drawsContent": false
-    },
-    {
-      "name": "Frame Scrolling Layer",
-      "position": [22, 122],
-      "drawsContent": false
-    },
-    {
-      "name": "Content Root Layer",
-      "position": [22, 122],
-      "bounds": [280, 200],
-      "drawsContent": false
-    },
-    {
       "name": "LayoutView #document",
       "position": [22, 122],
       "bounds": [280, 200]
     },
     {
+      "name": "Child Containment Layer",
+      "position": [22, 122],
+      "bounds": [280, 200],
+      "drawsContent": false
+    },
+    {
       "name": "LayoutIFrame IFRAME",
       "position": [30, 130],
       "bounds": [252, 172]
     },
     {
-      "name": "Frame Overflow Controls Host Layer",
-      "position": [31, 131],
-      "bounds": [250, 170],
-      "drawsContent": false
-    },
-    {
-      "name": "Frame Clipping Layer",
-      "position": [31, 131],
-      "bounds": [250, 170],
-      "drawsContent": false
-    },
-    {
-      "name": "Frame Scrolling Layer",
-      "position": [31, 131],
-      "drawsContent": false
-    },
-    {
-      "name": "Content Root Layer",
-      "position": [31, 131],
-      "bounds": [250, 230],
-      "drawsContent": false
-    },
-    {
       "name": "LayoutView #document",
       "position": [31, 131],
-      "bounds": [250, 230],
+      "bounds": [250, 170],
       "backgroundColor": "#C0C0C0"
     },
     {
+      "name": "Child Containment Layer",
+      "position": [31, 131],
+      "bounds": [250, 170],
+      "drawsContent": false
+    },
+    {
       "name": "LayoutBlockFlow DIV id='iframe-content' class='box'",
       "bounds": [210, 210],
       "contentsOpaque": true,
@@ -87,68 +63,34 @@
       "bounds": [284, 204]
     },
     {
-      "name": "Frame Overflow Controls Host Layer",
-      "position": [22, 346],
-      "bounds": [280, 200],
-      "drawsContent": false
-    },
-    {
-      "name": "Frame Clipping Layer",
-      "position": [22, 346],
-      "bounds": [280, 200],
-      "drawsContent": false
-    },
-    {
-      "name": "Frame Scrolling Layer",
-      "position": [22, 346],
-      "drawsContent": false
-    },
-    {
-      "name": "Content Root Layer",
-      "position": [22, 346],
-      "bounds": [280, 200],
-      "drawsContent": false
-    },
-    {
       "name": "LayoutView #document",
       "position": [22, 346],
       "bounds": [280, 200]
     },
     {
+      "name": "Child Containment Layer",
+      "position": [22, 346],
+      "bounds": [280, 200],
+      "drawsContent": false
+    },
+    {
       "name": "LayoutIFrame IFRAME",
       "position": [30, 354],
       "bounds": [252, 172]
     },
     {
-      "name": "Frame Overflow Controls Host Layer",
-      "position": [31, 355],
-      "bounds": [250, 170],
-      "drawsContent": false
-    },
-    {
-      "name": "Frame Clipping Layer",
-      "position": [31, 355],
-      "bounds": [250, 170],
-      "drawsContent": false
-    },
-    {
-      "name": "Frame Scrolling Layer",
-      "position": [31, 355],
-      "drawsContent": false
-    },
-    {
-      "name": "Content Root Layer",
-      "position": [31, 355],
-      "bounds": [250, 230],
-      "drawsContent": false
-    },
-    {
       "name": "LayoutView #document",
       "position": [31, 355],
-      "bounds": [250, 230],
+      "bounds": [250, 170],
       "backgroundColor": "#C0C0C0"
     },
     {
+      "name": "Child Containment Layer",
+      "position": [31, 355],
+      "bounds": [250, 170],
+      "drawsContent": false
+    },
+    {
       "name": "LayoutBlockFlow DIV id='iframe-content' class='box'",
       "bounds": [210, 210],
       "contentsOpaque": true,
diff --git a/third_party/WebKit/LayoutTests/compositing/squashing/squash-above-fixed-1-expected.txt b/third_party/WebKit/LayoutTests/compositing/squashing/squash-above-fixed-1-expected.txt
index 867cb55..b433a5e1 100644
--- a/third_party/WebKit/LayoutTests/compositing/squashing/squash-above-fixed-1-expected.txt
+++ b/third_party/WebKit/LayoutTests/compositing/squashing/squash-above-fixed-1-expected.txt
@@ -7,6 +7,16 @@
   "layers": [
     {
       "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [785, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
       "bounds": [785, 1400],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
@@ -52,6 +62,16 @@
   "layers": [
     {
       "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [785, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
       "bounds": [785, 1400],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF",
@@ -148,7 +168,8 @@
         [0, 1, 0, 0],
         [0, 0, 1, 0],
         [0, -80, 0, 1]
-      ]
+      ],
+      "flattenInheritedTransform": false
     },
     {
       "id": 2,
@@ -205,6 +226,16 @@
   "layers": [
     {
       "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [785, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
       "bounds": [785, 1400],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF",
@@ -245,7 +276,8 @@
         [0, 1, 0, 0],
         [0, 0, 1, 0],
         [0, -120, 0, 1]
-      ]
+      ],
+      "flattenInheritedTransform": false
     },
     {
       "id": 2,
@@ -264,6 +296,16 @@
   "layers": [
     {
       "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [785, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
       "bounds": [785, 1400],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF",
@@ -360,7 +402,8 @@
         [0, 1, 0, 0],
         [0, 0, 1, 0],
         [0, -170, 0, 1]
-      ]
+      ],
+      "flattenInheritedTransform": false
     },
     {
       "id": 2,
diff --git a/third_party/WebKit/LayoutTests/compositing/squashing/squash-above-fixed-3-expected.txt b/third_party/WebKit/LayoutTests/compositing/squashing/squash-above-fixed-3-expected.txt
index 93f57dc..f63eb4a 100644
--- a/third_party/WebKit/LayoutTests/compositing/squashing/squash-above-fixed-3-expected.txt
+++ b/third_party/WebKit/LayoutTests/compositing/squashing/squash-above-fixed-3-expected.txt
@@ -7,6 +7,16 @@
   "layers": [
     {
       "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [785, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
       "bounds": [785, 4100],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
@@ -56,6 +66,16 @@
   "layers": [
     {
       "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [785, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
       "bounds": [785, 4100],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF",
@@ -100,7 +120,8 @@
         [0, 1, 0, 0],
         [0, 0, 1, 0],
         [0, -10, 0, 1]
-      ]
+      ],
+      "flattenInheritedTransform": false
     },
     {
       "id": 2,
@@ -129,6 +150,16 @@
   "layers": [
     {
       "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [785, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
       "bounds": [785, 4100],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF",
@@ -171,7 +202,8 @@
         [0, 1, 0, 0],
         [0, 0, 1, 0],
         [0, -110, 0, 1]
-      ]
+      ],
+      "flattenInheritedTransform": false
     },
     {
       "id": 2,
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-001-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-001-ref.html
new file mode 100644
index 0000000..d832a30
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-001-ref.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+<head>
+	<meta charset="utf-8">
+	<title>CSS Reference File</title>
+	<link rel="author" title="Florian Rivoal" href="mailto:florian@rivoal.net">
+	<style>
+	div {
+		font-size: 50px;
+		position: absolute;
+		left: 30px;
+		top: 50px;
+	}
+	div span {
+		color: green;
+		background: green;
+		float: left;
+	}
+	</style>
+</head>
+<body>
+	<p>Test passes if there is a <strong>filled green rectangle</strong> and <strong>no red</strong>.</p>
+	<div><span>a</span></div>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-001.html
new file mode 100644
index 0000000..aaa76e04
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-001.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+<head>
+	<meta charset="utf-8">
+	<title>CSS Test: ::first-letter formatting</title>
+	<link rel="author" title="Florian Rivoal" href="mailto:florian@rivoal.net">
+	<link rel="match" href="first-letter-001-ref.html">
+	<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-letter-styling">
+	<meta name="flags" content="">
+	<meta name="assert" content="Test checks that a floated ::first-letter follows the usual formating rules for floats.">
+	<style>
+	div {
+		font-size: 50px;
+		position: absolute;
+		left: 30px;
+		top: 50px;
+		background: red;
+	}
+	span {
+		background : white;
+	}
+	div::first-letter {
+		color: green;
+		background: green;
+		float: left;
+	}
+	</style>
+</head>
+<body>
+	<p>Test passes if there is a <strong>filled green rectangle</strong> and <strong>no red</strong>.</p>
+	<div>a<span>&nbsp;</span></div>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-002.html
new file mode 100644
index 0000000..6123dfe
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-002.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<html>
+<head>
+	<meta charset="utf-8">
+	<title>CSS Test: ::first-letter formatting</title>
+	<link rel="author" title="Florian Rivoal" href="mailto:florian@rivoal.net">
+	<link rel="match" href="first-letter-001-ref.html">
+	<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-letter-styling">
+	<meta name="flags" content="">
+	<meta name="assert" content="Test checks that a floated ::first-letter is formatted identically to a floated non-pseudo element with the same content.">
+	<style>
+	div {
+		font-size: 50px;
+		position: absolute;
+		left: 30px;
+		top: 50px;
+	}
+	#d1 span {
+		color: red;
+		background: red;
+		float: left;
+	}
+	#d2::first-letter {
+		color: green;
+		background: green;
+		float: left;
+	}
+	</style>
+</head>
+<body>
+	<p>Test passes if there is a <strong>filled green rectangle</strong> and <strong>no red</strong>.</p>
+	<div id="d1"><span>a</span></div>
+	<div id="d2">a</div>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-003.html
new file mode 100644
index 0000000..b292d50
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-003.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<html>
+<head>
+	<meta charset="utf-8">
+	<title>CSS Test: ::first-letter formatting</title>
+	<link rel="author" title="Florian Rivoal" href="mailto:florian@rivoal.net">
+	<link rel="match" href="first-letter-001-ref.html">
+	<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-letter-styling">
+	<meta name="flags" content="">
+	<meta name="assert" content="Test checks that a floated ::first-letter is formatted identically to a floated non-pseudo element with the same content.">
+	<style>
+	div {
+		font-size: 50px;
+		position: absolute;
+		left: 30px;
+		top: 50px;
+	}
+	#d1::first-letter {
+		color: red;
+		background: red;
+		float: left;
+	}
+	#d2 span {
+		color: green;
+		background: green;
+		float: left;
+	}
+	</style>
+</head>
+<body>
+	<p>Test passes if there is a <strong>filled green rectangle</strong> and <strong>no red</strong>.</p>
+	<div id="d1">a</div>
+	<div id="d2"><span>a</span></div>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-004-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-004-ref.html
new file mode 100644
index 0000000..75a0149
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-004-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Reference</title>
+<style>
+    div {
+        font-size: 36px;
+    }
+    span {
+        color: green;
+    }
+</style>
+<body>
+    <p>Test passes if the "T" and surrounding punctuation below are green.</p>
+    <div><span>&#x104e;&#x300;T&#x300;&#x104e;&#x300;</span>est</div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-004.html
new file mode 100644
index 0000000..9079126d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/first-letter-004.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>CSS Test: ::first-letter formatting</title>
+    <link rel="author" title="Chris Nardi" href="mailto:csnardi1@gmail.com">
+    <link rel="match" href="first-letter-004-ref.html">
+    <link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-letter-pseudo">
+    <meta name="flags" content="">
+    <meta name="assert" content="Test checks that punctuation and letters with combining characters still have proper ::first-letter styling.">
+    <style>
+        div {
+            font-size: 36px;
+        }
+        div::first-letter {
+            color: green;
+        }
+    </style>
+</head>
+<body>
+    <p>Test passes if the "T" and surrounding punctuation below are green.</p>
+    <div>&#x104e;&#x300;T&#x300;&#x104e;&#x300;est</div>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-and-other-pseudo-elements-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-and-other-pseudo-elements-ref.html
new file mode 100644
index 0000000..796acbf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-and-other-pseudo-elements-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Test: ::marker interaction with ::before, ::after, and ::first-letter pseudo elements reference file</title>
+<link rel="author" title="Daniel Bates" href="mailto:dbates@webkit.org">
+<style>
+li {
+    color: green;
+    font-size: 20px;
+}
+
+.first-letter {
+    color: white;
+    background-color: green;
+}
+</style>
+</head>
+<body>
+<ol>
+    <li><span class="first-letter">P</span>ASSED if the list marker is green.</li>
+</ol>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-and-other-pseudo-elements.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-and-other-pseudo-elements.html
new file mode 100644
index 0000000..f393db58
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-and-other-pseudo-elements.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Test: ::marker interaction with ::before, ::after, and ::first-letter pseudo elements</title>
+<link rel="author" title="Daniel Bates" href="mailto:dbates@webkit.org">
+<link rel="match" href="marker-and-other-pseudo-elements-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
+<meta name="assert" content="Tests ::marker interaction with ::before, ::after, and ::first-letter pseudo elements">
+<style>
+li {
+    color: red;
+    font-size: 20px;
+}
+
+li::before {
+    color: green;
+    content: "PA";
+}
+
+li::after {
+    color: green;
+    content: "SSED if the list marker is green.";
+}
+
+li::marker {
+    color: green;
+}
+
+li::first-letter {
+    color: white;
+    background-color: green;
+}
+</style>
+</head>
+<body>
+<ol>
+    <li></li>
+</ol>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-color-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-color-ref.html
new file mode 100644
index 0000000..f2269f7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-color-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Test: ::marker formatting with color property reference file</title>
+<link rel="author" title="Daniel Bates" href="mailto:dbates@webkit.org">
+<style>
+li {
+    color: green;
+    font-size: 40px;
+    list-style-type: square;
+}
+</style>
+</head>
+<body>
+<ol>
+    <li><!-- The list marker should be a green square.--></li>
+</ol>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-color.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-color.html
new file mode 100644
index 0000000..d45c766
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-color.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Test: ::marker formatting with color property</title>
+<link rel="author" title="Daniel Bates" href="mailto:dbates@webkit.org">
+<link rel="match" href="marker-color-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
+<meta name="assert" content="Tests ::marker rendering with color property">
+<style>
+li {
+    color: red;
+    font-size: 40px;
+    list-style-type: square;
+}
+
+li::marker {
+    color: green;
+}
+</style>
+</head>
+<body>
+<ol>
+    <li><!-- The list marker should be a green square.--></li>
+</ol>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-font-properties-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-font-properties-ref.html
new file mode 100644
index 0000000..a8fb980
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-font-properties-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Test: ::marker formatting with font properties reference file</title>
+<link rel="author" title="Daniel Bates" href="mailto:dbates@webkit.org">
+<style>
+ol {
+    line-height: 30px;
+}
+
+li {
+    font-family: sans-serif;
+    font-size: 24px;
+    font-style: italic;
+    font-variant: small-caps;
+    font-weight: bold;
+    list-style-type: lower-alpha;
+    font-variant-numeric: tabular-nums;
+}
+</style>
+</head>
+<body>
+<ol>
+    <li></li>
+</ol>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-font-properties.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-font-properties.html
new file mode 100644
index 0000000..a108792
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-font-properties.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Test: ::marker formatting with font properties</title>
+<link rel="author" title="Daniel Bates" href="mailto:dbates@webkit.org">
+<link rel="match" href="marker-font-properties-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
+<meta name="assert" content="Tests ::marker rendering with font properties">
+<style>
+ol {
+    line-height: 30px;
+}
+
+li {
+    list-style-type: lower-alpha;
+}
+
+li::marker {
+    font-family: sans-serif;
+    font-size: 24px;
+    font-style: italic;
+    font-variant: small-caps;
+    font-weight: bold;
+}
+</style>
+</head>
+<body>
+<ol>
+    <li><span style="font-size: 24px"><!-- FIXME: Needed to ensure consistent baseline position with expected result in WebKit (why?). --></span></li>
+</ol>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-inherit-values-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-inherit-values-ref.html
new file mode 100644
index 0000000..6cce146
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-inherit-values-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Test: ::marker inherits values from originating element reference file</title>
+<link rel="author" title="Daniel Bates" href="mailto:dbates@webkit.org">
+<style>
+li {
+    color: green;
+    font-family: sans-serif;
+    font-size: x-large;
+    font-style: italic;
+    font-variant: small-caps;
+    font-weight: bold;
+    list-style-type: lower-alpha;
+}
+</style>
+</head>
+<body>
+<ol>
+    <li></li>
+</ol>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-inherit-values.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-inherit-values.html
new file mode 100644
index 0000000..82456af
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/marker-inherit-values.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Test: ::marker inherits values from originating element</title>
+<link rel="author" title="Daniel Bates" href="mailto:dbates@webkit.org">
+<link rel="match" href="marker-inherit-values-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
+<meta name="assert" content="Tests ::marker inherits values from originating element">
+<style>
+ol {
+    color: red;
+}
+
+li { /* Originating element */
+    color: green;
+    font-family: sans-serif;
+    font-size: x-large;
+    font-style: italic;
+    font-variant: small-caps;
+    font-weight: bold;
+    list-style-type: lower-alpha;
+}
+
+li::marker {
+    color: inherit;
+    font-family: inherit;
+    font-size: inherit;
+    font-style: inherit;
+    font-variant: inherit;
+    font-weight: inherit;
+}
+</style>
+</head>
+<body>
+<ol>
+    <li></li>
+</ol>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/pointerevents/pointerlock/pointerevent_pointerlock_after_pointercapture-manual.html b/third_party/WebKit/LayoutTests/external/wpt/pointerevents/pointerlock/pointerevent_pointerlock_after_pointercapture-manual.html
index 92fe7f26..8ac35f8 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/pointerevents/pointerlock/pointerevent_pointerlock_after_pointercapture-manual.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/pointerevents/pointerlock/pointerevent_pointerlock_after_pointercapture-manual.html
@@ -20,7 +20,7 @@
                 var test_pointerEvent = setup_pointerevent_test("no pointercapture while pointerlock", ['mouse']);
                 var div1 = document.getElementById("div1");
                 var div2 = document.getElementById("div2");
-                
+
                 on_event(div1, 'pointerdown', function(event) {
                     div2.setPointerCapture(event.pointerId);
                 });
@@ -33,8 +33,11 @@
                         test_pointerEvent.done(); 
                     }
                 });
+                on_event(document, 'contextmenu', function(event) {
+                    event.preventDefault();
+                });
                 on_event(div2, 'pointermove', function(event) {
-                    if (got_capture && !lock_requested) {
+                    if (event.button == 2 && got_capture && !lock_requested) {
                         div1.requestPointerLock();
                         lock_requested = true;
                     }
@@ -45,6 +48,9 @@
                 on_event(div2, 'lostpointercapture', function(event) {
                     lost_capture = true;
                 });
+                on_event(document,"pointerlockerror", function() {
+                    assert_unreached("Pointer lock error");
+                })
             }
         </script>
     </head>
@@ -56,6 +62,8 @@
             <ol>
                  <li>Press left button down on the green rectangle and hold it.</li>
                  <li>Move the mouse inside the green rectangle.</li>
+                 <li>Click right button while keeping left button down</li>
+                 <li>Keep moving the mouse inside the green rectangle.</li>
             </ol>
 
             Test passes if the pointer capture is released on the yellow rectangle when the green rectangle gets the pointer lock.
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/distance-model-testing.js b/third_party/WebKit/LayoutTests/external/wpt/webaudio/resources/distance-model-testing.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/webaudio/resources/distance-model-testing.js
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/resources/distance-model-testing.js
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/panner-formulas.js b/third_party/WebKit/LayoutTests/external/wpt/webaudio/resources/panner-formulas.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/webaudio/resources/panner-formulas.js
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/resources/panner-formulas.js
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webaudio/resources/panner-model-testing.js b/third_party/WebKit/LayoutTests/external/wpt/webaudio/resources/panner-model-testing.js
new file mode 100644
index 0000000..662fb1d6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/resources/panner-model-testing.js
@@ -0,0 +1,181 @@
+let sampleRate = 44100.0;
+
+let numberOfChannels = 1;
+
+// Time step when each panner node starts.
+let timeStep = 0.001;
+
+// Length of the impulse signal.
+let pulseLengthFrames = Math.round(timeStep * sampleRate);
+
+// How many panner nodes to create for the test
+let nodesToCreate = 100;
+
+// Be sure we render long enough for all of our nodes.
+let renderLengthSeconds = timeStep * (nodesToCreate + 1);
+
+// These are global mostly for debugging.
+let context;
+let impulse;
+let bufferSource;
+let panner;
+let position;
+let time;
+
+let renderedBuffer;
+let renderedLeft;
+let renderedRight;
+
+function createGraph(context, nodeCount, positionSetter) {
+  bufferSource = new Array(nodeCount);
+  panner = new Array(nodeCount);
+  position = new Array(nodeCount);
+  time = new Array(nodeCount);
+  // Angle between panner locations.  (nodeCount - 1 because we want
+  // to include both 0 and 180 deg.
+  let angleStep = Math.PI / (nodeCount - 1);
+
+  if (numberOfChannels == 2) {
+    impulse = createStereoImpulseBuffer(context, pulseLengthFrames);
+  } else
+    impulse = createImpulseBuffer(context, pulseLengthFrames);
+
+  for (let k = 0; k < nodeCount; ++k) {
+    bufferSource[k] = context.createBufferSource();
+    bufferSource[k].buffer = impulse;
+
+    panner[k] = context.createPanner();
+    panner[k].panningModel = 'equalpower';
+    panner[k].distanceModel = 'linear';
+
+    let angle = angleStep * k;
+    position[k] = {angle: angle, x: Math.cos(angle), z: Math.sin(angle)};
+    positionSetter(panner[k], position[k].x, 0, position[k].z);
+
+    bufferSource[k].connect(panner[k]);
+    panner[k].connect(context.destination);
+
+    // Start the source
+    time[k] = k * timeStep;
+    bufferSource[k].start(time[k]);
+  }
+}
+
+function createTestAndRun(
+    context, should, nodeCount, numberOfSourceChannels, positionSetter) {
+  numberOfChannels = numberOfSourceChannels;
+
+  createGraph(context, nodeCount, positionSetter);
+
+  return context.startRendering().then(buffer => checkResult(buffer, should));
+}
+
+// Map our position angle to the azimuth angle (in degrees).
+//
+// An angle of 0 corresponds to an azimuth of 90 deg; pi, to -90 deg.
+function angleToAzimuth(angle) {
+  return 90 - angle * 180 / Math.PI;
+}
+
+// The gain caused by the EQUALPOWER panning model
+function equalPowerGain(angle) {
+  let azimuth = angleToAzimuth(angle);
+
+  if (numberOfChannels == 1) {
+    let panPosition = (azimuth + 90) / 180;
+
+    let gainL = Math.cos(0.5 * Math.PI * panPosition);
+    let gainR = Math.sin(0.5 * Math.PI * panPosition);
+
+    return {left: gainL, right: gainR};
+  } else {
+    if (azimuth <= 0) {
+      let panPosition = (azimuth + 90) / 90;
+
+      let gainL = 1 + Math.cos(0.5 * Math.PI * panPosition);
+      let gainR = Math.sin(0.5 * Math.PI * panPosition);
+
+      return {left: gainL, right: gainR};
+    } else {
+      let panPosition = azimuth / 90;
+
+      let gainL = Math.cos(0.5 * Math.PI * panPosition);
+      let gainR = 1 + Math.sin(0.5 * Math.PI * panPosition);
+
+      return {left: gainL, right: gainR};
+    }
+  }
+}
+
+function checkResult(renderedBuffer, should) {
+  renderedLeft = renderedBuffer.getChannelData(0);
+  renderedRight = renderedBuffer.getChannelData(1);
+
+  // The max error we allow between the rendered impulse and the
+  // expected value.  This value is experimentally determined.  Set
+  // to 0 to make the test fail to see what the actual error is.
+  let maxAllowedError = 1.3e-6;
+
+  let success = true;
+
+  // Number of impulses found in the rendered result.
+  let impulseCount = 0;
+
+  // Max (relative) error and the index of the maxima for the left
+  // and right channels.
+  let maxErrorL = 0;
+  let maxErrorIndexL = 0;
+  let maxErrorR = 0;
+  let maxErrorIndexR = 0;
+
+  // Number of impulses that don't match our expected locations.
+  let timeCount = 0;
+
+  // Locations of where the impulses aren't at the expected locations.
+  let timeErrors = new Array();
+
+  for (let k = 0; k < renderedLeft.length; ++k) {
+    // We assume that the left and right channels start at the same instant.
+    if (renderedLeft[k] != 0 || renderedRight[k] != 0) {
+      // The expected gain for the left and right channels.
+      let pannerGain = equalPowerGain(position[impulseCount].angle);
+      let expectedL = pannerGain.left;
+      let expectedR = pannerGain.right;
+
+      // Absolute error in the gain.
+      let errorL = Math.abs(renderedLeft[k] - expectedL);
+      let errorR = Math.abs(renderedRight[k] - expectedR);
+
+      if (Math.abs(errorL) > maxErrorL) {
+        maxErrorL = Math.abs(errorL);
+        maxErrorIndexL = impulseCount;
+      }
+      if (Math.abs(errorR) > maxErrorR) {
+        maxErrorR = Math.abs(errorR);
+        maxErrorIndexR = impulseCount;
+      }
+
+      // Keep track of the impulses that didn't show up where we
+      // expected them to be.
+      let expectedOffset = timeToSampleFrame(time[impulseCount], sampleRate);
+      if (k != expectedOffset) {
+        timeErrors[timeCount] = {actual: k, expected: expectedOffset};
+        ++timeCount;
+      }
+      ++impulseCount;
+    }
+  }
+
+  should(impulseCount, 'Number of impulses found').beEqualTo(nodesToCreate);
+
+  should(
+      timeErrors.map(x => x.actual),
+      'Offsets of impulses at the wrong position')
+      .beEqualToArray(timeErrors.map(x => x.expected));
+
+  should(maxErrorL, 'Error in left channel gain values')
+      .beLessThanOrEqualTo(maxAllowedError);
+
+  should(maxErrorR, 'Error in right channel gain values')
+      .beLessThanOrEqualTo(maxAllowedError);
+}
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-exponential.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/distance-exponential.html
similarity index 69%
rename from third_party/WebKit/LayoutTests/webaudio/Panner/distance-exponential.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/distance-exponential.html
index 9b3c4d7..383e2c6 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-exponential.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/distance-exponential.html
@@ -4,11 +4,11 @@
     <title>
       distance-exponential.html
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
-    <script src="../resources/distance-model-testing.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="../../resources/audit-util.js"></script>
+    <script src="../../resources/audit.js"></script>
+    <script src="../../resources/distance-model-testing.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-inverse.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/distance-inverse.html
similarity index 63%
rename from third_party/WebKit/LayoutTests/webaudio/Panner/distance-inverse.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/distance-inverse.html
index 79b9a6d..a4ff984 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-inverse.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/distance-inverse.html
@@ -4,11 +4,11 @@
     <title>
       distance-inverse.html
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
-    <script src="../resources/distance-model-testing.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="../../resources/audit-util.js"></script>
+    <script src="../../resources/audit.js"></script>
+    <script src="../../resources/distance-model-testing.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-linear.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/distance-linear.html
similarity index 67%
rename from third_party/WebKit/LayoutTests/webaudio/Panner/distance-linear.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/distance-linear.html
index c02926fe..812fea3 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Panner/distance-linear.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/distance-linear.html
@@ -4,11 +4,11 @@
     <title>
       distance-linear.html
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
-    <script src="../resources/distance-model-testing.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="../../resources/audit-util.js"></script>
+    <script src="../../resources/audit.js"></script>
+    <script src="../../resources/distance-model-testing.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-automation-basic.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-automation-basic.html
similarity index 96%
rename from third_party/WebKit/LayoutTests/webaudio/Panner/panner-automation-basic.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-automation-basic.html
index 1e9a2c1..5c3df0e6f 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-automation-basic.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-automation-basic.html
@@ -4,11 +4,11 @@
     <title>
       Test Basic PannerNode with Automation Position Properties
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
-    <script src="../resources/panner-formulas.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="../../resources/audit-util.js"></script>
+    <script src="../../resources/audit.js"></script>
+    <script src="../../resources/panner-formulas.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-automation-equalpower-stereo.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-automation-equalpower-stereo.html
similarity index 81%
rename from third_party/WebKit/LayoutTests/webaudio/Panner/panner-automation-equalpower-stereo.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-automation-equalpower-stereo.html
index 2b1d464..7afc9c2a39 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-automation-equalpower-stereo.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-automation-equalpower-stereo.html
@@ -4,11 +4,11 @@
     <title>
       panner-automation-equalpower-stereo.html
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
-    <script src="../resources/panner-model-testing.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="../../resources/audit-util.js"></script>
+    <script src="../../resources/audit.js"></script>
+    <script src="../../resources/panner-model-testing.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-automation-position.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-automation-position.html
similarity index 96%
rename from third_party/WebKit/LayoutTests/webaudio/Panner/panner-automation-position.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-automation-position.html
index 7beabb2e..8e09e86 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-automation-position.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-automation-position.html
@@ -4,11 +4,11 @@
     <title>
       Test Automation of PannerNode Positions
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
-    <script src="../resources/panner-formulas.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="../../resources/audit-util.js"></script>
+    <script src="../../resources/audit.js"></script>
+    <script src="../../resources/panner-formulas.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-distance-clamping.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-distance-clamping.html
similarity index 96%
rename from third_party/WebKit/LayoutTests/webaudio/Panner/panner-distance-clamping.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-distance-clamping.html
index a4df2eb..dae58c9 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-distance-clamping.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-distance-clamping.html
@@ -4,10 +4,10 @@
     <title>
       Test Clamping of Distance for PannerNode
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="../../resources/audit-util.js"></script>
+    <script src="../../resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-equalpower-stereo.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower-stereo.html
similarity index 79%
rename from third_party/WebKit/LayoutTests/webaudio/Panner/panner-equalpower-stereo.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower-stereo.html
index 16c7550..2a0225b 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-equalpower-stereo.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower-stereo.html
@@ -4,11 +4,11 @@
     <title>
       panner-equalpower-stereo.html
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
-    <script src="../resources/panner-model-testing.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="../../resources/audit-util.js"></script>
+    <script src="../../resources/audit.js"></script>
+    <script src="../../resources/panner-model-testing.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-equalpower.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower.html
similarity index 90%
rename from third_party/WebKit/LayoutTests/webaudio/Panner/panner-equalpower.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower.html
index 79b8b8b..3ff21b65 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-equalpower.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower.html
@@ -4,11 +4,11 @@
     <title>
       panner-equalpower.html
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
-    <script src="../resources/panner-model-testing.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="../../resources/audit-util.js"></script>
+    <script src="../../resources/audit.js"></script>
+    <script src="../../resources/panner-model-testing.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
@@ -78,7 +78,7 @@
                   // position
                   let c0 = renderedBuffer.getChannelData(0);
                   let c1 = renderedBuffer.getChannelData(1);
-                  should(c0, 'Left and right channels').beEqualToArray(c1);
+                  should(c0, 'Mono: Left and right channels').beEqualToArray(c1);
                 })
                 .then(() => task.done());
           });
@@ -128,7 +128,7 @@
                   // position.
                   let c0 = renderedBuffer.getChannelData(0);
                   let c1 = renderedBuffer.getChannelData(1);
-                  should(c0, 'Left and right channels').beEqualToArray(c1);
+                  should(c0, 'Stereo: Left and right channels').beEqualToArray(c1);
                 })
                 .then(() => task.done());
           });
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-rolloff-clamping.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-rolloff-clamping.html
similarity index 94%
rename from third_party/WebKit/LayoutTests/webaudio/Panner/panner-rolloff-clamping.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-rolloff-clamping.html
index 779e6fb..e1519f8 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-rolloff-clamping.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/panner-rolloff-clamping.html
@@ -4,10 +4,10 @@
     <title>
       Test Clamping of PannerNode rolloffFactor
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="../../resources/audit-util.js"></script>
+    <script src="../../resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/pannernode-basic.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/pannernode-basic.html
similarity index 95%
rename from third_party/WebKit/LayoutTests/webaudio/Panner/pannernode-basic.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/pannernode-basic.html
index bf9fdf89..32402f5e 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Panner/pannernode-basic.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-pannernode-interface/pannernode-basic.html
@@ -4,10 +4,10 @@
     <title>
       pannernode-basic.html
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="../../resources/audit-util.js"></script>
+    <script src="../../resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/external/wpt_automation/pointerevents/pointerlock/pointerevent_pointerlock_after_pointercapture-manual-automation.js b/third_party/WebKit/LayoutTests/external/wpt_automation/pointerevents/pointerlock/pointerevent_pointerlock_after_pointercapture-manual-automation.js
index 94765a11..07d31b6f 100644
--- a/third_party/WebKit/LayoutTests/external/wpt_automation/pointerevents/pointerlock/pointerevent_pointerlock_after_pointercapture-manual-automation.js
+++ b/third_party/WebKit/LayoutTests/external/wpt_automation/pointerevents/pointerlock/pointerevent_pointerlock_after_pointercapture-manual-automation.js
@@ -1,5 +1,29 @@
 importAutomationScript('/pointerevents/pointerevent_common_input.js');
 
 function inject_input() {
-  return mouseRequestPointerLockAndCaptureInTarget('#div1');
+  const targetDocument = document;
+  const targetSelector = '#div1'
+  return new Promise(function(resolve, reject) {
+    if (window.chrome && chrome.gpuBenchmarking) {
+      scrollPageIfNeeded(targetSelector, targetDocument);
+      var target = targetDocument.querySelector(targetSelector);
+      var targetRect = target.getBoundingClientRect();
+      var xPosition = targetRect.left + boundaryOffset;
+      var yPosition = targetRect.top + boundaryOffset;
+
+      chrome.gpuBenchmarking.pointerActionSequence( [
+        {source: 'mouse',
+         actions: [
+            {name: 'pointerMove', x: xPosition, y: yPosition},
+            {name: 'pointerDown', x: xPosition, y: yPosition, button: 'left'},
+            {name: 'pointerMove', x: xPosition + 30, y: yPosition + 30},
+            {name: 'pointerMove', x: xPosition + 30, y: yPosition},
+            {name: 'pointerDown', x: xPosition + 30, y: yPosition, button: 'right'},
+            {name: 'pointerMove', x: xPosition + 60, y: yPosition + 30},
+            {name: 'pointerMove', x: xPosition + 30, y: yPosition + 20},
+        ]}], resolve);
+    } else {
+      reject();
+    }
+  });
 }
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/resources/LowSlashUnderscoreFont.otf b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/resources/LowSlashUnderscoreFont.otf
new file mode 100644
index 0000000..cc8830f5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/resources/LowSlashUnderscoreFont.otf
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip-ink-links-expected.html b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip-ink-links-expected.html
new file mode 100644
index 0000000..ffdd7c9b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip-ink-links-expected.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<style>
+p {
+width: 600px;
+}
+
+@font-face {
+font-family: LowSlashUnderscoreFont;
+src: url(resources/LowSlashUnderscoreFont.otf);
+unicode-range: U+2F, U+5C, U+5F;
+}
+
+.decoration {
+font-family: LowSlashUnderscoreFont, sans-serif;
+text-decoration-color: red;
+text-decoration-skip-ink: none;
+text-decoration-line: underline;
+}
+</style>
+<p><a href="https://crbug.com/784493">crbug.com/784493</a> Text decoration for text including a slash /, a backslash \ and an underscore _ should not ink-skip for those characters.</p>
+<div class="decoration">
+Slash / backslash \ and underscore _.
+</div>
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip-ink-links.html b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip-ink-links.html
new file mode 100644
index 0000000..48c48782
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-skip-ink-links.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<style>
+p {
+width: 600px;
+}
+
+@font-face {
+font-family: LowSlashUnderscoreFont;
+src: url(resources/LowSlashUnderscoreFont.otf);
+unicode-range: U+2F, U+5C, U+5F;
+}
+
+.decoration {
+font-family: LowSlashUnderscoreFont, sans-serif;
+text-decoration-color: red;
+text-decoration-skip-ink: auto;
+text-decoration-line: underline;
+}
+</style>
+<p><a href="https://crbug.com/784493">crbug.com/784493</a> Text decoration for text including a slash /, a backslash \ and an underscore _ should not ink-skip for those characters.</p>
+<div class="decoration">
+Slash / backslash \ and underscore _.
+</div>
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/basic/015-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/basic/015-expected.txt
new file mode 100644
index 0000000..60933749
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/basic/015-expected.txt
@@ -0,0 +1,162 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x452
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x451.88
+    LayoutNGBlockFlow {BODY} at (8,21.44) size 784x414.44
+      LayoutNGBlockFlow {H1} at (0,0) size 784x37
+        LayoutText {#text} at (0,0) size 456x36
+          text run at (0,0) width 456: "Minimum and Maximum Widths"
+      LayoutNGBlockFlow {DIV} at (0,58.44) size 784x26 [border: (3px solid #800080)]
+        LayoutText {#text} at (3,3) size 32x19
+          text run at (3,3) width 32: "This "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (35,6) size 24x16
+            text run at (35,6) width 24: "div"
+        LayoutText {#text} at (59,3) size 408x19
+          text run at (59,3) width 408: " should have a medium solid purple border, as should all the rest."
+      LayoutNGBlockFlow {DIV} at (0,84.44) size 319.59x66 [border: (3px solid #800080)]
+        LayoutText {#text} at (3,3) size 32x19
+          text run at (3,3) width 32: "This "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (35,6) size 24x16
+            text run at (35,6) width 24: "div"
+        LayoutText {#text} at (59,3) size 298x39
+          text run at (59,3) width 242: " should have a width of 40%. This is a"
+          text run at (3,23) width 62: "reference "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (65,26) size 24x16
+            text run at (65,26) width 24: "div"
+        LayoutText {#text} at (89,23) size 180x19
+          text run at (89,23) width 180: " and should work as long as "
+        LayoutInline {CODE} at (0,0) size 40x16
+          LayoutText {#text} at (269,26) size 40x16
+            text run at (269,26) width 40: "width"
+        LayoutText {#text} at (3,43) size 43x19
+          text run at (3,43) width 43: "works."
+      LayoutNGBlockFlow {DIV} at (0,150.44) size 319.59x26 [border: (3px solid #800080)]
+        LayoutText {#text} at (3,3) size 32x19
+          text run at (3,3) width 32: "This "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (35,6) size 24x16
+            text run at (35,6) width 24: "div"
+        LayoutText {#text} at (59,3) size 185x19
+          text run at (59,3) width 185: " should have a width of 40%."
+      LayoutNGBlockFlow {DIV} at (0,176.44) size 319.59x26 [border: (3px solid #800080)]
+        LayoutText {#text} at (3,3) size 32x19
+          text run at (3,3) width 32: "This "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (35,6) size 24x16
+            text run at (35,6) width 24: "div"
+        LayoutText {#text} at (59,3) size 185x19
+          text run at (59,3) width 185: " should have a width of 40%."
+      LayoutNGBlockFlow {DIV} at (0,202.44) size 319.59x26 [border: (3px solid #800080)]
+        LayoutText {#text} at (3,3) size 32x19
+          text run at (3,3) width 32: "This "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (35,6) size 24x16
+            text run at (35,6) width 24: "div"
+        LayoutText {#text} at (59,3) size 185x19
+          text run at (59,3) width 185: " should have a width of 40%."
+      LayoutNGBlockFlow {DIV} at (0,228.44) size 319.59x26 [border: (3px solid #800080)]
+        LayoutText {#text} at (3,3) size 32x19
+          text run at (3,3) width 32: "This "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (35,6) size 24x16
+            text run at (35,6) width 24: "div"
+        LayoutText {#text} at (59,3) size 185x19
+          text run at (59,3) width 185: " should have a width of 40%."
+      LayoutNGBlockFlow {DIV} at (0,254.44) size 319.59x26 [border: (3px solid #800080)]
+        LayoutText {#text} at (3,3) size 32x19
+          text run at (3,3) width 32: "This "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (35,6) size 24x16
+            text run at (35,6) width 24: "div"
+        LayoutText {#text} at (59,3) size 185x19
+          text run at (59,3) width 185: " should have a width of 40%."
+      LayoutNGBlockFlow {DIV} at (0,280.44) size 319.59x26 [border: (3px solid #800080)]
+        LayoutText {#text} at (3,3) size 32x19
+          text run at (3,3) width 32: "This "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (35,6) size 24x16
+            text run at (35,6) width 24: "div"
+        LayoutText {#text} at (59,3) size 185x19
+          text run at (59,3) width 185: " should have a width of 40%."
+      LayoutNGBlockFlow {DIV} at (0,306.44) size 319.59x26 [border: (3px solid #800080)]
+        LayoutText {#text} at (3,3) size 32x19
+          text run at (3,3) width 32: "This "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (35,6) size 24x16
+            text run at (35,6) width 24: "div"
+        LayoutText {#text} at (59,3) size 185x19
+          text run at (59,3) width 185: " should have a width of 40%."
+      LayoutNGBlockFlow {DIV} at (0,332.44) size 319.59x26 [border: (3px solid #800080)]
+        LayoutText {#text} at (3,3) size 32x19
+          text run at (3,3) width 32: "This "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (35,6) size 24x16
+            text run at (35,6) width 24: "div"
+        LayoutText {#text} at (59,3) size 185x19
+          text run at (59,3) width 185: " should have a width of 40%."
+      LayoutNGBlockFlow {P} at (0,374.44) size 784x40
+        LayoutText {#text} at (0,0) size 200x19
+          text run at (0,0) width 200: "If the browser does not support "
+        LayoutInline {CODE} at (0,0) size 72x16
+          LayoutText {#text} at (200,3) size 72x16
+            text run at (200,3) width 72: "min-width"
+        LayoutText {#text} at (272,0) size 31x19
+          text run at (272,0) width 31: " and "
+        LayoutInline {CODE} at (0,0) size 72x16
+          LayoutText {#text} at (303,3) size 72x16
+            text run at (303,3) width 72: "max-width"
+        LayoutText {#text} at (375,0) size 173x19
+          text run at (375,0) width 173: ", then the widths should be "
+        LayoutInline {CODE} at (0,0) size 32x16
+          LayoutText {#text} at (548,3) size 32x16
+            text run at (548,3) width 32: "auto"
+        LayoutText {#text} at (580,0) size 8x19
+          text run at (580,0) width 8: ", "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (588,3) size 24x16
+            text run at (588,3) width 24: "40%"
+        LayoutText {#text} at (612,0) size 8x19
+          text run at (612,0) width 8: ", "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (620,3) size 24x16
+            text run at (620,3) width 24: "30%"
+        LayoutText {#text} at (644,0) size 8x19
+          text run at (644,0) width 8: ", "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (652,3) size 24x16
+            text run at (652,3) width 24: "50%"
+        LayoutText {#text} at (676,0) size 8x19
+          text run at (676,0) width 8: ", "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (684,3) size 24x16
+            text run at (684,3) width 24: "50%"
+        LayoutText {#text} at (708,0) size 8x19
+          text run at (708,0) width 8: ", "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (716,3) size 24x16
+            text run at (716,3) width 24: "40%"
+        LayoutText {#text} at (740,0) size 8x19
+          text run at (740,0) width 8: ", "
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (748,3) size 24x16
+            text run at (748,3) width 24: "30%"
+        LayoutText {#text} at (772,0) size 4x19
+          text run at (772,0) width 4: ","
+        LayoutInline {CODE} at (0,0) size 24x16
+          LayoutText {#text} at (0,23) size 24x16
+            text run at (0,23) width 24: "40%"
+        LayoutText {#text} at (24,20) size 8x19
+          text run at (24,20) width 8: ", "
+        LayoutInline {CODE} at (0,0) size 32x16
+          LayoutText {#text} at (32,23) size 32x16
+            text run at (32,23) width 32: "auto"
+        LayoutText {#text} at (64,20) size 192x19
+          text run at (64,20) width 192: " (with 70% margin-right), and "
+        LayoutInline {CODE} at (0,0) size 33x16
+          LayoutText {#text} at (255,23) size 33x16
+            text run at (255,23) width 33: "auto"
+        LayoutText {#text} at (287,20) size 5x19
+          text run at (287,20) width 5: "."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/avoidance-percent-width-strict-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/avoidance-percent-width-strict-expected.txt
new file mode 100644
index 0000000..85c0bcb7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/avoidance-percent-width-strict-expected.txt
@@ -0,0 +1,26 @@
+layer at (0,0) size 800x600 scrollWidth 812
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x148
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x148
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x132
+      LayoutNGBlockFlow (floating) {DIV} at (0,0) size 554x24 [border: (2px solid #FF0000)]
+        LayoutText {#text} at (2,2) size 501x19
+          text run at (2,2) width 501: "(Parent DIV have no border set) There should be a green table below this block"
+      LayoutTable {TABLE} at (0,24) size 784x30 [border: (2px solid #008000)]
+        LayoutTableSection {TBODY} at (2,2) size 780x26
+          LayoutTableRow {TR} at (0,2) size 780x22
+            LayoutNGTableCell {TD} at (2,2) size 776x22 [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 21x19
+                text run at (1,1) width 21: "test"
+      LayoutNGBlockFlow (anonymous) at (0,54) size 784x20
+        LayoutBR {BR} at (0,0) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,74) size 804x58 [border: (2px solid #0000FF)]
+        LayoutNGBlockFlow (floating) {DIV} at (2,2) size 554x24 [border: (2px solid #FF0000)]
+          LayoutText {#text} at (2,2) size 540x19
+            text run at (2,2) width 540: "(Parent DIV have 2px blue border set) There should be a green table below this block"
+        LayoutTable {TABLE} at (2,26) size 800x30 [border: (2px solid #008000)]
+          LayoutTableSection {TBODY} at (2,2) size 796x26
+            LayoutTableRow {TR} at (0,2) size 796x22
+              LayoutNGTableCell {TD} at (2,2) size 792x22 [r=0 c=0 rs=1 cs=1]
+                LayoutText {#text} at (1,1) size 21x19
+                  text run at (1,1) width 21: "test"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/centered-float-avoidance-complexity-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/centered-float-avoidance-complexity-expected.txt
new file mode 100644
index 0000000..7d769d9d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/centered-float-avoidance-complexity-expected.txt
@@ -0,0 +1,96 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 663
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x663 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 785x663.03
+    LayoutNGBlockFlow {BODY} at (8,21.44) size 769x622.88
+      LayoutNGBlockFlow {H1} at (0,0) size 769x74
+        LayoutText {#text} at (0,0) size 543x36
+          text run at (0,0) width 543: "Margins and block formating contexts ("
+        LayoutInline {A} at (0,0) size 751x73 [color=#0000EE]
+          LayoutText {#text} at (543,0) size 751x73
+            text run at (543,0) width 208: "additional tests"
+            text run at (0,37) width 252: "from Alan Gresley"
+        LayoutText {#text} at (251,37) size 12x36
+          text run at (251,37) width 12: ")"
+      LayoutNGBlockFlow {H3} at (0,95.44) size 769x69
+        LayoutText {#text} at (0,0) size 704x22
+          text run at (0,0) width 704: "The orange stripe has 'overflow: auto', 'margin-left: 100px' and 'margin-right: 100px'"
+        LayoutBR {BR} at (704,0) size 0x0
+        LayoutText {#text} at (0,23) size 663x22
+          text run at (0,23) width 663: "The lime stripes are floats with various width (topmost is 0, bottommost is 150px)"
+        LayoutBR {BR} at (662,23) size 0x0
+        LayoutText {#text} at (0,46) size 402x22
+          text run at (0,46) width 402: "The wrapping container has a solid silver border."
+      LayoutNGBlockFlow {DIV} at (16,183.16) size 650x30 [border: (5px solid #C0C0C0)]
+        LayoutNGBlockFlow (floating) {DIV} at (5,5) size 0x16 [bgcolor=#00FF00]
+          LayoutText {#text} at (0,0) size 38x19
+            text run at (0,0) width 38: "floatL"
+      LayoutNGBlockFlow {DIV} at (16,229.16) size 650x30 [border: (5px solid #C0C0C0)]
+        LayoutNGBlockFlow (floating) {DIV} at (5,5) size 50x16 [bgcolor=#00FF00]
+          LayoutText {#text} at (0,0) size 38x19
+            text run at (0,0) width 38: "floatL"
+      LayoutNGBlockFlow {DIV} at (16,275.16) size 650x30 [border: (5px solid #C0C0C0)]
+        LayoutNGBlockFlow (floating) {DIV} at (5,5) size 100x16 [bgcolor=#00FF00]
+          LayoutText {#text} at (0,0) size 38x19
+            text run at (0,0) width 38: "floatL"
+      LayoutNGBlockFlow {DIV} at (16,321.16) size 650x30 [border: (5px solid #C0C0C0)]
+        LayoutNGBlockFlow (floating) {DIV} at (5,5) size 150x16 [bgcolor=#00FF00]
+          LayoutText {#text} at (0,0) size 82x19
+            text run at (0,0) width 82: "floatL 150px"
+      LayoutNGBlockFlow {DIV} at (16,367.16) size 650x30 [border: (5px solid #C0C0C0)]
+        LayoutNGBlockFlow (floating) {DIV} at (645,5) size 0x16 [bgcolor=#00FF00]
+          LayoutText {#text} at (0,0) size 39x19
+            text run at (0,0) width 39: "floatR"
+      LayoutNGBlockFlow {DIV} at (16,413.16) size 650x30 [border: (5px solid #C0C0C0)]
+        LayoutNGBlockFlow (floating) {DIV} at (595,5) size 50x16 [bgcolor=#00FF00]
+          LayoutText {#text} at (0,0) size 39x19
+            text run at (0,0) width 39: "floatR"
+      LayoutNGBlockFlow {DIV} at (16,459.16) size 650x30 [border: (5px solid #C0C0C0)]
+        LayoutNGBlockFlow (floating) {DIV} at (545,5) size 100x16 [bgcolor=#00FF00]
+          LayoutText {#text} at (0,0) size 39x19
+            text run at (0,0) width 39: "floatR"
+      LayoutNGBlockFlow {DIV} at (16,505.16) size 650x30 [border: (5px solid #C0C0C0)]
+        LayoutNGBlockFlow (floating) {DIV} at (495,5) size 150x16 [bgcolor=#00FF00]
+          LayoutText {#text} at (0,0) size 83x19
+            text run at (0,0) width 83: "floatR 150px"
+      LayoutNGBlockFlow {H3} at (0,553.88) size 769x69
+        LayoutText {#text} at (0,0) size 676x22
+          text run at (0,0) width 676: "The orange stripe has 'overflow: auto', 'margin-left: auto' and 'margin-right: auto'"
+        LayoutBR {BR} at (676,0) size 0x0
+        LayoutText {#text} at (0,23) size 663x22
+          text run at (0,23) width 663: "The lime stripes are floats with various width (topmost is 0, bottommost is 150px)"
+        LayoutBR {BR} at (662,23) size 0x0
+        LayoutText {#text} at (0,46) size 402x22
+          text run at (0,46) width 402: "The wrapping container has a solid silver border."
+layer at (129,210) size 440x20
+  LayoutNGBlockFlow {DIV} at (105,5) size 440x20 [bgcolor=#FFA500]
+    LayoutText {#text} at (0,0) size 172x19
+      text run at (0,0) width 172: "<div> with 'overflow: auto'"
+layer at (129,256) size 440x20
+  LayoutNGBlockFlow {DIV} at (105,5) size 440x20 [bgcolor=#FFA500]
+    LayoutText {#text} at (0,0) size 172x19
+      text run at (0,0) width 172: "<div> with 'overflow: auto'"
+layer at (129,302) size 440x20
+  LayoutNGBlockFlow {DIV} at (105,5) size 440x20 [bgcolor=#FFA500]
+    LayoutText {#text} at (0,0) size 172x19
+      text run at (0,0) width 172: "<div> with 'overflow: auto'"
+layer at (179,348) size 390x20
+  LayoutNGBlockFlow {DIV} at (155,5) size 390x20 [bgcolor=#FFA500]
+    LayoutText {#text} at (0,0) size 172x19
+      text run at (0,0) width 172: "<div> with 'overflow: auto'"
+layer at (129,394) size 440x20
+  LayoutNGBlockFlow {DIV} at (105,5) size 440x20 [bgcolor=#FFA500]
+    LayoutText {#text} at (0,0) size 172x19
+      text run at (0,0) width 172: "<div> with 'overflow: auto'"
+layer at (129,440) size 440x20
+  LayoutNGBlockFlow {DIV} at (105,5) size 440x20 [bgcolor=#FFA500]
+    LayoutText {#text} at (0,0) size 172x19
+      text run at (0,0) width 172: "<div> with 'overflow: auto'"
+layer at (129,486) size 440x20
+  LayoutNGBlockFlow {DIV} at (105,5) size 440x20 [bgcolor=#FFA500]
+    LayoutText {#text} at (0,0) size 172x19
+      text run at (0,0) width 172: "<div> with 'overflow: auto'"
+layer at (129,532) size 390x20
+  LayoutNGBlockFlow {DIV} at (105,5) size 390x20 [bgcolor=#FFA500]
+    LayoutText {#text} at (0,0) size 172x19
+      text run at (0,0) width 172: "<div> with 'overflow: auto'"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/independent-align-positioning-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/independent-align-positioning-expected.txt
new file mode 100644
index 0000000..51053cd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/independent-align-positioning-expected.txt
@@ -0,0 +1,27 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x172
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x172
+    LayoutNGBlockFlow {BODY} at (8,16) size 784x140
+      LayoutNGBlockFlow (floating) {DIV} at (556.28,0) size 227.72x60 [bgcolor=#CC6666]
+        LayoutText {#text} at (20,20) size 188x19
+          text run at (20,20) width 188: "DIV NUMBER 1: float:right;"
+      LayoutNGBlockFlow (floating) {DIV} at (485.28,60) size 298.72x60 [bgcolor=#99CC66]
+        LayoutText {#text} at (20,20) size 259x19
+          text run at (20,20) width 259: "DIV NUMBER 2: clear:right; float:right;"
+      LayoutNGBlockFlow (floating) {DIV} at (0,60) size 218.72x60 [bgcolor=#6699FF]
+        LayoutText {#text} at (20,20) size 179x19
+          text run at (20,20) width 179: "DIV NUMBER 3: float:left;"
+      LayoutNGBlockFlow {P} at (0,0) size 784x140
+        LayoutText {#text} at (0,0) size 556x119
+          text run at (0,0) width 528: "The first element is floated to the right. The second element clears the right float and"
+          text run at (0,20) width 556: "also floats right. The third element is floated to the left, but is forced below the bottom of"
+          text run at (0,40) width 523: "the first element. Yet, somehow this paragraph comes at the end of the markup, and"
+          text run at (218,60) width 239: "manages to rise to the top of the page."
+          text run at (218,80) width 262: "This behavior is present in Firefox, Safari"
+          text run at (218,100) width 75: "and Opera. "
+        LayoutInline {A} at (0,0) size 472x39 [color=#0000EE]
+          LayoutInline {STRONG} at (0,0) size 472x39
+            LayoutText {#text} at (292,100) size 472x39
+              text run at (292,100) width 180: "Click here for a real world"
+              text run at (0,120) width 135: "example of this bug."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/overhanging-float-remove-from-fixed-position-block-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/overhanging-float-remove-from-fixed-position-block-expected.txt
new file mode 100644
index 0000000..dae4f116c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/overhanging-float-remove-from-fixed-position-block-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x108
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x108
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x0
+layer at (8,8) size 18x0
+  LayoutNGBlockFlow (relative positioned) {DIV} at (0,0) size 18x0
+    LayoutNGBlockFlow (floating) {DIV} at (8,0) size 10x100 [bgcolor=#C0C0C0]
+layer at (8,8) size 62x70
+  LayoutNGBlockFlow (positioned) {DIV} at (8,8) size 62.13x70
+    LayoutNGBlockFlow {DIV} at (0,0) size 62.13x20
+      LayoutNGBlockFlow (floating) {DIV} at (57.13,0) size 5x50 [bgcolor=#FFA500]
+      LayoutNGBlockFlow {DIV} at (0,0) size 62.13x20 [bgcolor=#0000FF]
+        LayoutText {#text} at (0,0) size 58x19
+          text run at (0,0) width 58: "A B C D"
+        LayoutNGBlockFlow (floating) {DIV} at (52.13,20) size 5x50 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/overhanging-float-remove-from-fixed-position-block2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/overhanging-float-remove-from-fixed-position-block2-expected.txt
new file mode 100644
index 0000000..dae4f116c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/overhanging-float-remove-from-fixed-position-block2-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x108
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x108
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x0
+layer at (8,8) size 18x0
+  LayoutNGBlockFlow (relative positioned) {DIV} at (0,0) size 18x0
+    LayoutNGBlockFlow (floating) {DIV} at (8,0) size 10x100 [bgcolor=#C0C0C0]
+layer at (8,8) size 62x70
+  LayoutNGBlockFlow (positioned) {DIV} at (8,8) size 62.13x70
+    LayoutNGBlockFlow {DIV} at (0,0) size 62.13x20
+      LayoutNGBlockFlow (floating) {DIV} at (57.13,0) size 5x50 [bgcolor=#FFA500]
+      LayoutNGBlockFlow {DIV} at (0,0) size 62.13x20 [bgcolor=#0000FF]
+        LayoutText {#text} at (0,0) size 58x19
+          text run at (0,0) width 58: "A B C D"
+        LayoutNGBlockFlow (floating) {DIV} at (52.13,20) size 5x50 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/canvas/fillrect_gradient-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/canvas/fillrect_gradient-expected.png
new file mode 100644
index 0000000..2a3a3c2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/canvas/fillrect_gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css3-text/css3-text-justify/text-justify-8bits-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css3-text/css3-text-justify/text-justify-8bits-expected.png
new file mode 100644
index 0000000..ba08e614
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css3-text/css3-text-justify/text-justify-8bits-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css3-text/css3-text-justify/text-justify-8bits-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css3-text/css3-text-justify/text-justify-8bits-expected.txt
new file mode 100644
index 0000000..008ebf7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css3-text/css3-text-justify/text-justify-8bits-expected.txt
@@ -0,0 +1,60 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x444
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x444
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x428
+      LayoutNGBlockFlow {DIV} at (0,0) size 784x60
+        LayoutText {#text} at (0,0) size 340x19
+          text run at (0,0) width 340: "Test all of the values of text-justify for 8bits characters"
+        LayoutBR {BR} at (339,0) size 0x0
+        LayoutText {#text} at (0,20) size 607x19
+          text run at (0,20) width 607: "This test checks that all of the values for text-justify property works properly for 8bits characters."
+        LayoutBR {BR} at (607,20) size 0x0
+        LayoutText {#text} at (0,40) size 450x19
+          text run at (0,40) width 450: "Every block has been set as 'text-align: justify' and 'text-align-last: start'."
+      LayoutNGBlockFlow (anonymous) at (0,60) size 784x40
+        LayoutBR {BR} at (0,0) size 0x0
+        LayoutInline {B} at (0,0) size 111x19
+          LayoutText {#text} at (0,20) size 111x19
+            text run at (0,20) width 111: "text-justify: auto"
+        LayoutBR {BR} at (111,20) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,100) size 302x47 [border: (1px solid #000000)]
+        LayoutText {#text} at (1,1) size 300x45
+          text run at (1,1) width 300: "Lorem ipsum dolor sit amet, consectetuer"
+          text run at (1,16) width 300: "adipiscing elit. Aenean commodo ligula"
+          text run at (1,31) width 77: "eget dolor."
+      LayoutNGBlockFlow (anonymous) at (0,147) size 784x40
+        LayoutBR {BR} at (0,0) size 0x0
+        LayoutInline {B} at (0,0) size 114x19
+          LayoutText {#text} at (0,20) size 114x19
+            text run at (0,20) width 114: "text-justify: none"
+        LayoutBR {BR} at (114,20) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,187) size 302x47 [border: (1px solid #000000)]
+        LayoutText {#text} at (1,1) size 280x45
+          text run at (1,1) width 280: "Lorem ipsum dolor sit amet, consectetuer"
+          text run at (1,16) width 266: "adipiscing elit. Aenean commodo ligula"
+          text run at (1,31) width 77: "eget dolor."
+      LayoutNGBlockFlow (anonymous) at (0,234) size 784x40
+        LayoutBR {BR} at (0,0) size 0x0
+        LayoutInline {B} at (0,0) size 154x19
+          LayoutText {#text} at (0,20) size 154x19
+            text run at (0,20) width 154: "text-justify: inter-word"
+        LayoutBR {BR} at (153,20) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,274) size 302x47 [border: (1px solid #000000)]
+        LayoutText {#text} at (1,1) size 300x45
+          text run at (1,1) width 300: "Lorem ipsum dolor sit amet, consectetuer"
+          text run at (1,16) width 300: "adipiscing elit. Aenean commodo ligula"
+          text run at (1,31) width 77: "eget dolor."
+      LayoutNGBlockFlow (anonymous) at (0,321) size 784x40
+        LayoutBR {BR} at (0,0) size 0x0
+        LayoutInline {B} at (0,0) size 146x19
+          LayoutText {#text} at (0,20) size 146x19
+            text run at (0,20) width 146: "text-justify: distribute"
+        LayoutBR {BR} at (146,20) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,361) size 302x47 [border: (1px solid #000000)]
+        LayoutText {#text} at (1,1) size 283x45
+          text run at (1,1) width 283: "Lorem ipsum dolor sit amet, consectetuer"
+          text run at (1,16) width 270: "adipiscing elit. Aenean commodo ligula"
+          text run at (1,31) width 77: "eget dolor."
+      LayoutNGBlockFlow (anonymous) at (0,408) size 784x20
+        LayoutBR {BR} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/006-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/006-expected.png
new file mode 100644
index 0000000..3349309
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/006-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/006-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/006-expected.txt
new file mode 100644
index 0000000..53be7e2ca
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/006-expected.txt
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x92
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x91.59
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x75.59
+      LayoutNGBlockFlow {DIV} at (0,0) size 784x75.59 [border: (5px solid #000000)]
+        LayoutFieldset {FIELDSET} at (7,5) size 770x65.59 [border: (10px groove #FF0000)]
+          LayoutNGBlockFlow {LEGEND} at (42,0) size 121.89x20
+            LayoutText {#text} at (2,0) size 118x19
+              text run at (2,0) width 118: "Test without forms"
+          LayoutNGBlockFlow {DIV} at (22,25.59) size 726x20
+            LayoutText {#text} at (0,0) size 275x19
+              text run at (0,0) width 275: "A DIV inside a fieldset, not related to forms"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/button-text-transform-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/button-text-transform-expected.png
new file mode 100644
index 0000000..01ea6df5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/button-text-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/button-text-transform-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/button-text-transform-expected.txt
new file mode 100644
index 0000000..b9617cbad
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/button-text-transform-expected.txt
@@ -0,0 +1,53 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x140
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x140
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x116
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 1096x39
+          LayoutInline {A} at (0,0) size 302x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 302x19
+              text run at (51,0) width 302: "http://bugs.webkit.org/show_bug.cgi?id=15181"
+          LayoutText {#text} at (352,0) size 744x39
+            text run at (352,0) width 392: " text-transform: uppercase not working in input (submit, reset,"
+            text run at (0,20) width 104: "button) elements"
+        LayoutText {#text} at (104,20) size 4x19
+          text run at (104,20) width 4: "."
+      LayoutNGBlockFlow {P} at (0,56) size 784x22
+        LayoutButton {BUTTON} at (0,0) size 97x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+          LayoutNGBlockFlow (anonymous) at (8,3) size 81x16
+            LayoutText {#text} at (0,0) size 81x16
+              text run at (0,0) width 81: "UPPERCASE"
+        LayoutText {#text} at (97,1) size 4x19
+          text run at (97,1) width 4: " "
+        LayoutButton {BUTTON} at (101,0) size 74x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+          LayoutNGBlockFlow (anonymous) at (8,3) size 58x16
+            LayoutText {#text} at (0,0) size 58x16
+              text run at (0,0) width 58: "lowercase"
+        LayoutText {#text} at (175,1) size 4x19
+          text run at (175,1) width 4: " "
+        LayoutButton {BUTTON} at (179,0) size 73x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+          LayoutNGBlockFlow (anonymous) at (8,3) size 57x16
+            LayoutText {#text} at (0,0) size 57x16
+              text run at (0,0) width 57: "Capitalize"
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {P} at (0,94) size 784x22
+        LayoutButton {INPUT} at (0,0) size 97x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+          LayoutNGBlockFlow (anonymous) at (8,3) size 81x16
+            LayoutText {#text} at (0,0) size 81x16
+              text run at (0,0) width 81: "UPPERCASE"
+        LayoutText {#text} at (97,1) size 4x19
+          text run at (97,1) width 4: " "
+        LayoutButton {INPUT} at (101,0) size 74x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+          LayoutNGBlockFlow (anonymous) at (8,3) size 58x16
+            LayoutText {#text} at (0,0) size 58x16
+              text run at (0,0) width 58: "lowercase"
+        LayoutText {#text} at (175,1) size 4x19
+          text run at (175,1) width 4: " "
+        LayoutButton {INPUT} at (179,0) size 73x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+          LayoutNGBlockFlow (anonymous) at (8,3) size 57x16
+            LayoutText {#text} at (0,0) size 57x16
+              text run at (0,0) width 57: "Capitalize"
+        LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
new file mode 100644
index 0000000..b71577e2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png
new file mode 100644
index 0000000..e25a701
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/color/color-suggestion-picker-appearance-zoom200-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/color/input-appearance-color-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/color/input-appearance-color-expected.png
new file mode 100644
index 0000000..9394812
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/color/input-appearance-color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/color/input-appearance-color-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/color/input-appearance-color-expected.txt
new file mode 100644
index 0000000..7f90d948
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/color/input-appearance-color-expected.txt
@@ -0,0 +1,159 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x477
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x477.47
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x461.47
+      LayoutNGBlockFlow {H3} at (0,0) size 784x23
+        LayoutText {#text} at (0,0) size 163x22
+          text run at (0,0) width 163: "Default Appearance"
+      LayoutNGBlockFlow (anonymous) at (0,41.72) size 784x43
+        LayoutText {#text} at (0,0) size 284x19
+          text run at (0,0) width 284: "List color controls have different appearance."
+        LayoutBR {BR} at (283,0) size 0x0
+        LayoutBlockFlow {INPUT} at (0,20) size 44x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 38x19
+            LayoutBlockFlow {DIV} at (2,4) size 34x11 [bgcolor=#000000] [border: (1px solid #777777)]
+        LayoutBlockFlow {INPUT} at (44,20) size 88x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 82x19
+            LayoutBlockFlow {DIV} at (8,4) size 50x11 [bgcolor=#000000] [border: (1px solid #000000)]
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {H3} at (0,103.44) size 784x23
+        LayoutText {#text} at (0,0) size 160x22
+          text run at (0,0) width 160: "Different Font Sizes"
+      LayoutNGBlockFlow (anonymous) at (0,145.16) size 784x43
+        LayoutText {#text} at (0,0) size 577x19
+          text run at (0,0) width 577: "List color controls have different sizes depending on font sizes. Normal color controls don't."
+        LayoutBR {BR} at (576,0) size 0x0
+        LayoutBlockFlow {INPUT} at (0,20) size 44x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 38x19
+            LayoutBlockFlow {DIV} at (2,4) size 34x11 [bgcolor=#00FF00] [border: (1px solid #777777)]
+        LayoutText {#text} at (44,21) size 4x19
+          text run at (44,21) width 4: " "
+        LayoutBlockFlow {INPUT} at (48,20) size 44x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 38x19
+            LayoutBlockFlow {DIV} at (2,4) size 34x11 [bgcolor=#00FF00] [border: (1px solid #777777)]
+        LayoutText {#text} at (92,21) size 4x19
+          text run at (92,21) width 4: " "
+        LayoutBlockFlow {INPUT} at (96,20) size 44x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 38x19
+            LayoutBlockFlow {DIV} at (2,4) size 34x11 [bgcolor=#00FF00] [border: (1px solid #777777)]
+        LayoutText {#text} at (140,21) size 4x19
+          text run at (140,21) width 4: " "
+        LayoutBlockFlow {INPUT} at (144,20) size 88x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 82x19
+            LayoutBlockFlow {DIV} at (8,4) size 50x11 [bgcolor=#00FF00] [border: (1px solid #000000)]
+        LayoutText {#text} at (232,21) size 4x19
+          text run at (232,21) width 4: " "
+        LayoutBlockFlow {INPUT} at (236,20) size 88x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 82x19
+            LayoutBlockFlow {DIV} at (8,4) size 50x11 [bgcolor=#00FF00] [border: (1px solid #000000)]
+        LayoutText {#text} at (324,21) size 4x19
+          text run at (324,21) width 4: " "
+        LayoutBlockFlow {INPUT} at (328,20) size 88x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 82x19
+            LayoutBlockFlow {DIV} at (8,4) size 50x11 [bgcolor=#00FF00] [border: (1px solid #000000)]
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {H3} at (0,206.88) size 784x23
+        LayoutText {#text} at (0,0) size 123x22
+          text run at (0,0) width 123: "Various Colors"
+      LayoutNGBlockFlow (anonymous) at (0,248.59) size 784x23
+        LayoutBlockFlow {INPUT} at (0,0) size 44x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 38x19
+            LayoutBlockFlow {DIV} at (2,4) size 34x11 [bgcolor=#FF0000] [border: (1px solid #777777)]
+        LayoutText {#text} at (44,1) size 4x19
+          text run at (44,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (48,0) size 44x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 38x19
+            LayoutBlockFlow {DIV} at (2,4) size 34x11 [bgcolor=#00FF00] [border: (1px solid #777777)]
+        LayoutText {#text} at (92,1) size 4x19
+          text run at (92,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (96,0) size 44x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 38x19
+            LayoutBlockFlow {DIV} at (2,4) size 34x11 [bgcolor=#0000FF] [border: (1px solid #777777)]
+        LayoutText {#text} at (140,1) size 4x19
+          text run at (140,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (144,0) size 44x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 38x19
+            LayoutBlockFlow {DIV} at (2,4) size 34x11 [bgcolor=#EC008C] [border: (1px solid #777777)]
+        LayoutText {#text} at (188,1) size 4x19
+          text run at (188,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (192,0) size 44x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 38x19
+            LayoutBlockFlow {DIV} at (2,4) size 34x11 [bgcolor=#40E0D0] [border: (1px solid #777777)]
+        LayoutText {#text} at (236,1) size 4x19
+          text run at (236,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (240,0) size 88x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 82x19
+            LayoutBlockFlow {DIV} at (8,4) size 50x11 [bgcolor=#FF0000] [border: (1px solid #000000)]
+        LayoutText {#text} at (328,1) size 4x19
+          text run at (328,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (332,0) size 88x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 82x19
+            LayoutBlockFlow {DIV} at (8,4) size 50x11 [bgcolor=#00FF00] [border: (1px solid #000000)]
+        LayoutText {#text} at (420,1) size 4x19
+          text run at (420,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (424,0) size 88x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 82x19
+            LayoutBlockFlow {DIV} at (8,4) size 50x11 [bgcolor=#0000FF] [border: (1px solid #000000)]
+        LayoutText {#text} at (512,1) size 4x19
+          text run at (512,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (516,0) size 88x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 82x19
+            LayoutBlockFlow {DIV} at (8,4) size 50x11 [bgcolor=#EC008C] [border: (1px solid #000000)]
+        LayoutText {#text} at (604,1) size 4x19
+          text run at (604,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (608,0) size 88x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 82x19
+            LayoutBlockFlow {DIV} at (8,4) size 50x11 [bgcolor=#40E0D0] [border: (1px solid #000000)]
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {H3} at (0,290.31) size 784x23
+        LayoutText {#text} at (0,0) size 117x22
+          text run at (0,0) width 117: "Arbitrary Size"
+      LayoutNGBlockFlow (anonymous) at (0,332.03) size 784x46
+        LayoutBlockFlow {INPUT} at (0,9) size 100x30 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 94x26
+            LayoutBlockFlow {DIV} at (2,4) size 90x18 [bgcolor=#FF0000] [border: (1px solid #777777)]
+        LayoutText {#text} at (100,17) size 4x19
+          text run at (100,17) width 4: " "
+        LayoutBlockFlow {INPUT} at (104,0) size 88x46 [bgcolor=#DDDDDD] [border: (2px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (6,4) size 76x38
+            LayoutBlockFlow {DIV} at (4,8) size 68x22 [bgcolor=#FF0000] [border: (2px solid #777777)]
+        LayoutText {#text} at (192,17) size 4x19
+          text run at (192,17) width 4: " "
+        LayoutBlockFlow {INPUT} at (196,0) size 176x46 [bgcolor=#DDDDDD] [border: (2px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (6,4) size 164x38
+            LayoutBlockFlow {DIV} at (16,8) size 100x22 [bgcolor=#FF0000] [border: (2px solid #000000)]
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {H3} at (0,396.75) size 784x23
+        LayoutText {#text} at (0,0) size 96x22
+          text run at (0,0) width 96: "Other styles"
+      LayoutNGBlockFlow (anonymous) at (0,438.47) size 784x23
+        LayoutBlockFlow {INPUT} at (0,0) size 44x23 [bgcolor=#FFFF00] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 38x19
+            LayoutBlockFlow {DIV} at (2,4) size 34x11 [bgcolor=#FF0000] [border: (1px solid #777777)]
+        LayoutText {#text} at (44,1) size 4x19
+          text run at (44,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (48,0) size 88x23 [bgcolor=#FFFF00] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 82x19
+            LayoutBlockFlow {DIV} at (8,4) size 50x11 [bgcolor=#FF0000] [border: (1px solid #000000)]
+        LayoutText {#text} at (136,1) size 4x19
+          text run at (136,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (140,0) size 44x23 [bgcolor=#DDDDDD] [border: (1px solid #00FF00)]
+          LayoutFlexibleBox {DIV} at (3,2) size 38x19
+            LayoutBlockFlow {DIV} at (2,4) size 34x11 [bgcolor=#FF0000] [border: (1px solid #777777)]
+        LayoutText {#text} at (184,1) size 4x19
+          text run at (184,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (188,0) size 88x23 [bgcolor=#DDDDDD] [border: (1px solid #00FF00)]
+          LayoutFlexibleBox {DIV} at (3,2) size 82x19
+            LayoutBlockFlow {DIV} at (8,4) size 50x11 [bgcolor=#FF0000] [border: (1px solid #000000)]
+        LayoutText {#text} at (276,1) size 4x19
+          text run at (276,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (280,0) size 44x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 38x19
+            LayoutBlockFlow {DIV} at (2,4) size 34x11 [bgcolor=#40E0D0] [border: (1px solid #777777)]
+        LayoutText {#text} at (324,1) size 4x19
+          text run at (324,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (328,0) size 88x23 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)]
+          LayoutFlexibleBox {DIV} at (3,2) size 82x19
+            LayoutBlockFlow {DIV} at (24,4) size 50x11 [bgcolor=#FF0000] [border: (1px solid #000000)]
+        LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/datalist/input-appearance-range-with-padding-with-datalist-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/datalist/input-appearance-range-with-padding-with-datalist-expected.png
new file mode 100644
index 0000000..9c6c9d1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/datalist/input-appearance-range-with-padding-with-datalist-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/datalist/input-appearance-range-with-transform-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/datalist/input-appearance-range-with-transform-expected.png
new file mode 100644
index 0000000..59d6942
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/datalist/input-appearance-range-with-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/date/date-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/date/date-appearance-basic-expected.png
new file mode 100644
index 0000000..b8f78c0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/date/date-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/date/date-appearance-basic-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/date/date-appearance-basic-expected.txt
new file mode 100644
index 0000000..38179098
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/date/date-appearance-basic-expected.txt
@@ -0,0 +1,15 @@
+Basic  
+:hover 
+Disabled  
+Read-only  
+RTL 
+With max  
+text-align: 
+text-transform: 
+background, color: 
+font-size, font-weight: 
+font-size with fixed input width:  
+Fixed input height:  
+-webkit-appearance:none: 
+display: none: inline: inline-block: block:table-cell:   
+padding: 
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/date/date-appearance-pseudo-elements-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/date/date-appearance-pseudo-elements-expected.png
new file mode 100644
index 0000000..cc4846b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/date/date-appearance-pseudo-elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/datetimelocal/datetimelocal-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/datetimelocal/datetimelocal-appearance-basic-expected.png
new file mode 100644
index 0000000..57f9a6d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/datetimelocal/datetimelocal-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/datetimelocal/datetimelocal-appearance-basic-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/datetimelocal/datetimelocal-appearance-basic-expected.txt
new file mode 100644
index 0000000..9f7f2dcc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/datetimelocal/datetimelocal-appearance-basic-expected.txt
@@ -0,0 +1,17 @@
+step=none  
+step=1  
+step=0.001  
+step=3600  
+step=86400  
+step mismatched 
+RTL 
+Disabled  
+Readonly, step=3600  
+text-align: 
+text-transform: 
+background, color: 
+font-size, font-weight: 
+font-size with fixed input width: 
+Fixed input height: 
+-webkit-appearance:none: 
+padding: 
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.png
new file mode 100644
index 0000000..9b407a5f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.txt
new file mode 100644
index 0000000..e446122
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.txt
@@ -0,0 +1,277 @@
+layer at (0,0) size 800x600 scrollHeight 653
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x653 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x652.88
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x636.88
+      LayoutNGBlockFlow {H1} at (0,0) size 784x37
+        LayoutText {#text} at (0,0) size 419x36
+          text run at (0,0) width 419: "Form Element Geometry Tests"
+      LayoutNGBlockFlow {P} at (0,58.44) size 784x20
+        LayoutText {#text} at (0,0) size 540x19
+          text run at (0,0) width 540: "These tests help us tune the widget classes in KWQ to have all the right fudge factors."
+      LayoutNGBlockFlow {H2} at (0,98.34) size 784x27
+        LayoutText {#text} at (0,0) size 165x26
+          text run at (0,0) width 165: "Bounding Boxes"
+      LayoutTable {TABLE} at (0,145.25) size 166x32
+        LayoutTableSection {TBODY} at (0,0) size 166x32
+          LayoutTableRow {TR} at (0,2) size 166x28
+            LayoutNGTableCell {TD} at (2,2) size 58x28 [r=0 c=0 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 56x26 [border: (2px solid #0000FF)]
+                LayoutInline {FONT} at (0,0) size 52x22
+                  LayoutButton {INPUT} at (2,2) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+                    LayoutNGBlockFlow (anonymous) at (8,3) size 36x16
+                      LayoutText {#text} at (0,0) size 36x16
+                        text run at (0,0) width 36: "button"
+            LayoutNGTableCell {TD} at (62,3) size 60x26 [r=0 c=1 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 58x24 [border: (2px solid #0000FF)]
+                LayoutInline {FONT} at (0,0) size 54x20
+                  LayoutMenuList {SELECT} at (2,2) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+                    LayoutNGBlockFlow (anonymous) at (1,1) size 52x18
+                      LayoutText (anonymous) at (4,1) size 32x16
+                        text run at (4,1) width 32: "menu"
+            LayoutNGTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+                LayoutInline {FONT} at (0,0) size 13x13
+                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
+            LayoutNGTableCell {TD} at (145,6) size 19x19 [r=0 c=3 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+                LayoutInline {FONT} at (0,0) size 13x13
+                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
+      LayoutTable {TABLE} at (0,177.25) size 166x32
+        LayoutTableSection {TBODY} at (0,0) size 166x32
+          LayoutTableRow {TR} at (0,2) size 166x28
+            LayoutNGTableCell {TD} at (2,2) size 58x28 [r=0 c=0 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 56x26 [border: (2px solid #0000FF)]
+                LayoutButton {INPUT} at (2,2) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+                  LayoutNGBlockFlow (anonymous) at (8,3) size 36x16
+                    LayoutText {#text} at (0,0) size 36x16
+                      text run at (0,0) width 36: "button"
+            LayoutNGTableCell {TD} at (62,3) size 60x26 [r=0 c=1 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 58x24 [border: (2px solid #0000FF)]
+                LayoutMenuList {SELECT} at (2,2) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+                  LayoutNGBlockFlow (anonymous) at (1,1) size 52x18
+                    LayoutText (anonymous) at (4,1) size 32x16
+                      text run at (4,1) width 32: "menu"
+            LayoutNGTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,2) size 13x13
+            LayoutNGTableCell {TD} at (145,6) size 19x19 [r=0 c=3 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+                LayoutBlockFlow {INPUT} at (2,2) size 13x13
+      LayoutTable {TABLE} at (0,209.25) size 166x32
+        LayoutTableSection {TBODY} at (0,0) size 166x32
+          LayoutTableRow {TR} at (0,2) size 166x28
+            LayoutNGTableCell {TD} at (2,2) size 58x28 [r=0 c=0 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 56x26 [border: (2px solid #0000FF)]
+                LayoutInline {FONT} at (0,0) size 52x22
+                  LayoutButton {INPUT} at (2,2) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+                    LayoutNGBlockFlow (anonymous) at (8,3) size 36x16
+                      LayoutText {#text} at (0,0) size 36x16
+                        text run at (0,0) width 36: "button"
+            LayoutNGTableCell {TD} at (62,3) size 60x26 [r=0 c=1 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 58x24 [border: (2px solid #0000FF)]
+                LayoutInline {FONT} at (0,0) size 54x20
+                  LayoutMenuList {SELECT} at (2,2) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+                    LayoutNGBlockFlow (anonymous) at (1,1) size 52x18
+                      LayoutText (anonymous) at (4,1) size 32x16
+                        text run at (4,1) width 32: "menu"
+            LayoutNGTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+                LayoutInline {FONT} at (0,0) size 13x13
+                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
+            LayoutNGTableCell {TD} at (145,6) size 19x19 [r=0 c=3 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 17x17 [border: (2px solid #0000FF)]
+                LayoutInline {FONT} at (0,0) size 13x13
+                  LayoutBlockFlow {INPUT} at (2,2) size 13x13
+      LayoutTable {TABLE} at (0,241.25) size 583x80
+        LayoutTableSection {TBODY} at (0,0) size 583x80
+          LayoutTableRow {TR} at (0,2) size 583x76
+            LayoutNGTableCell {TD} at (2,2) size 100x28 [r=0 c=0 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 98x26 [border: (2px solid #0000FF)]
+                LayoutTextControl {INPUT} at (2,2) size 94x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+            LayoutNGTableCell {TD} at (104,2) size 44x76 [r=0 c=1 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 42x74 [border: (2px solid #0000FF)]
+            LayoutNGTableCell {TD} at (150,2) size 244x28 [r=0 c=2 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 242x26 [border: (2px solid #0000FF)]
+                LayoutFileUploadControl {INPUT} at (2,2) size 238x22 "No file chosen"
+                  LayoutButton {INPUT} at (0,0) size 85x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+                    LayoutNGBlockFlow (anonymous) at (8,3) size 69x16
+                      LayoutText {#text} at (0,0) size 69x16
+                        text run at (0,0) width 69: "Choose File"
+            LayoutNGTableCell {TD} at (396,2) size 185x42 [r=0 c=3 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 183x40 [border: (2px solid #0000FF)]
+      LayoutNGBlockFlow {H2} at (0,341.16) size 784x27
+        LayoutText {#text} at (0,0) size 199x26
+          text run at (0,0) width 199: "Baseline Alignment"
+      LayoutNGBlockFlow {DIV} at (0,388.06) size 784x28
+        LayoutInline {FONT} at (0,0) size 397x32
+          LayoutText {#text} at (0,0) size 43x27
+            text run at (0,0) width 43: "text "
+          LayoutButton {INPUT} at (43,5) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+            LayoutNGBlockFlow (anonymous) at (8,3) size 36x16
+              LayoutText {#text} at (0,0) size 36x16
+                text run at (0,0) width 36: "button"
+          LayoutText {#text} at (95,0) size 6x27
+            text run at (95,0) width 6: " "
+          LayoutMenuList {SELECT} at (101,6) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 52x18
+              LayoutText (anonymous) at (4,1) size 32x16
+                text run at (4,1) width 32: "menu"
+          LayoutText {#text} at (155,0) size 6x27
+            text run at (155,0) width 6: " "
+          LayoutBlockFlow {INPUT} at (166,8) size 13x13
+          LayoutText {#text} at (182,0) size 6x27
+            text run at (182,0) width 6: " "
+          LayoutBlockFlow {INPUT} at (192,8) size 13x13
+          LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,416.06) size 784x22
+        LayoutText {#text} at (0,1) size 27x19
+          text run at (0,1) width 27: "text "
+        LayoutButton {INPUT} at (27,0) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+          LayoutNGBlockFlow (anonymous) at (8,3) size 36x16
+            LayoutText {#text} at (0,0) size 36x16
+              text run at (0,0) width 36: "button"
+        LayoutText {#text} at (79,1) size 4x19
+          text run at (79,1) width 4: " "
+        LayoutMenuList {SELECT} at (83,1) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+          LayoutNGBlockFlow (anonymous) at (1,1) size 52x18
+            LayoutText (anonymous) at (4,1) size 32x16
+              text run at (4,1) width 32: "menu"
+        LayoutText {#text} at (137,1) size 4x19
+          text run at (137,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (146,3) size 13x13
+        LayoutText {#text} at (162,1) size 4x19
+          text run at (162,1) width 4: " "
+        LayoutBlockFlow {INPUT} at (170,3) size 13x13
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,438.06) size 784x22
+        LayoutInline {FONT} at (0,0) size 329x24
+          LayoutText {#text} at (0,6) size 18x12
+            text run at (0,6) width 18: "text "
+          LayoutButton {INPUT} at (18,0) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+            LayoutNGBlockFlow (anonymous) at (8,3) size 36x16
+              LayoutText {#text} at (0,0) size 36x16
+                text run at (0,0) width 36: "button"
+          LayoutText {#text} at (70,6) size 3x12
+            text run at (70,6) width 3: " "
+          LayoutMenuList {SELECT} at (73,1) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 52x18
+              LayoutText (anonymous) at (4,1) size 32x16
+                text run at (4,1) width 32: "menu"
+          LayoutText {#text} at (127,6) size 3x12
+            text run at (127,6) width 3: " "
+          LayoutBlockFlow {INPUT} at (135,3) size 13x13
+          LayoutText {#text} at (151,6) size 3x12
+            text run at (151,6) width 3: " "
+          LayoutBlockFlow {INPUT} at (158,3) size 13x13
+          LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,460.06) size 784x42
+        LayoutText {#text} at (0,21) size 27x19
+          text run at (0,21) width 27: "text "
+        LayoutTextControl {INPUT} at (27,20) size 94x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutText {#text} at (121,21) size 4x19
+          text run at (121,21) width 4: " "
+        LayoutFileUploadControl {INPUT} at (125,20) size 238x22 "No file chosen"
+          LayoutButton {INPUT} at (0,0) size 85x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+            LayoutNGBlockFlow (anonymous) at (8,3) size 69x16
+              LayoutText {#text} at (0,0) size 69x16
+                text run at (0,0) width 69: "Choose File"
+        LayoutText {#text} at (363,21) size 4x19
+          text run at (363,21) width 4: " "
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {H2} at (0,521.97) size 784x27
+        LayoutText {#text} at (0,0) size 197x26
+          text run at (0,0) width 197: "Pop-up Menu Sizes"
+      LayoutNGBlockFlow {DIV} at (0,568.88) size 784x28
+        LayoutInline {FONT} at (0,0) size 196x32
+          LayoutText {#text} at (0,0) size 0x0
+          LayoutMenuList {SELECT} at (0,6) size 22x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 20x18
+              LayoutText (anonymous) at (4,1) size 4x16
+                text run at (4,1) width 4: " "
+          LayoutText {#text} at (22,0) size 6x27
+            text run at (22,0) width 6: " "
+          LayoutMenuList {SELECT} at (28,6) size 25x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 23x18
+              LayoutText (anonymous) at (4,1) size 3x16
+                text run at (4,1) width 3: "|"
+          LayoutText {#text} at (53,0) size 6x27
+            text run at (53,0) width 6: " "
+          LayoutMenuList {SELECT} at (59,6) size 78x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 76x18
+              LayoutText (anonymous) at (4,1) size 56x16
+                text run at (4,1) width 56: "xxxxxxxx"
+          LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,596.88) size 784x20
+        LayoutMenuList {SELECT} at (0,0) size 22x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+          LayoutNGBlockFlow (anonymous) at (1,1) size 20x18
+            LayoutText (anonymous) at (4,1) size 4x16
+              text run at (4,1) width 4: " "
+        LayoutText {#text} at (22,0) size 4x19
+          text run at (22,0) width 4: " "
+        LayoutMenuList {SELECT} at (26,0) size 25x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+          LayoutNGBlockFlow (anonymous) at (1,1) size 23x18
+            LayoutText (anonymous) at (4,1) size 3x16
+              text run at (4,1) width 3: "|"
+        LayoutText {#text} at (51,0) size 4x19
+          text run at (51,0) width 4: " "
+        LayoutMenuList {SELECT} at (55,0) size 78x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+          LayoutNGBlockFlow (anonymous) at (1,1) size 76x18
+            LayoutText (anonymous) at (4,1) size 56x16
+              text run at (4,1) width 56: "xxxxxxxx"
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,616.88) size 784x20
+        LayoutInline {FONT} at (0,0) size 184x22
+          LayoutText {#text} at (0,0) size 0x0
+          LayoutMenuList {SELECT} at (0,0) size 22x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 20x18
+              LayoutText (anonymous) at (4,1) size 4x16
+                text run at (4,1) width 4: " "
+          LayoutText {#text} at (22,5) size 3x12
+            text run at (22,5) width 3: " "
+          LayoutMenuList {SELECT} at (25,0) size 25x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 23x18
+              LayoutText (anonymous) at (4,1) size 3x16
+                text run at (4,1) width 3: "|"
+          LayoutText {#text} at (50,5) size 3x12
+            text run at (50,5) width 3: " "
+          LayoutMenuList {SELECT} at (53,0) size 78x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 76x18
+              LayoutText (anonymous) at (4,1) size 56x16
+                text run at (4,1) width 56: "xxxxxxxx"
+          LayoutText {#text} at (0,0) size 0x0
+layer at (15,257) size 90x16
+  LayoutBlockFlow {DIV} at (2,3) size 90x16
+    LayoutText {#text} at (0,0) size 50x16
+      text run at (0,0) width 50: "text field"
+layer at (115,254) size 38x70 clip at (116,255) size 21x68 scrollHeight 85
+  LayoutListBox {SELECT} at (2,2) size 38x70 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {OPTION} at (1,1) size 21x17
+      LayoutText {#text} at (2,0) size 17x16
+        text run at (2,0) width 17: "list"
+    LayoutBlockFlow {OPTION} at (1,18) size 21x17
+      LayoutText {#text} at (2,0) size 7x16
+        text run at (2,0) width 7: "2"
+    LayoutBlockFlow {OPTION} at (1,35) size 21x17
+      LayoutText {#text} at (2,0) size 7x16
+        text run at (2,0) width 7: "3"
+    LayoutBlockFlow {OPTION} at (1,52) size 21x17
+      LayoutText {#text} at (2,0) size 7x16
+        text run at (2,0) width 7: "4"
+    LayoutBlockFlow {OPTION} at (1,69) size 21x17
+      LayoutText {#text} at (2,0) size 7x16
+        text run at (2,0) width 7: "5"
+layer at (407,254) size 179x36 clip at (408,255) size 177x34
+  LayoutTextControl {TEXTAREA} at (2,2) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 175x16
+      LayoutText {#text} at (0,0) size 64x16
+        text run at (0,0) width 64: "textarea"
+layer at (37,491) size 90x16
+  LayoutBlockFlow {DIV} at (2,3) size 90x16
+    LayoutText {#text} at (0,0) size 50x16
+      text run at (0,0) width 50: "text field"
+layer at (375,468) size 179x36 clip at (376,469) size 177x34
+  LayoutTextControl {TEXTAREA} at (367,0) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 175x16
+      LayoutText {#text} at (0,0) size 64x16
+        text run at (0,0) width 64: "textarea"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/image-alt-text-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/image-alt-text-expected.png
new file mode 100644
index 0000000..b362c6a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/image-alt-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/image-alt-text-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/image-alt-text-expected.txt
new file mode 100644
index 0000000..a43cba4b8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/image-alt-text-expected.txt
@@ -0,0 +1,29 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x173
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x173
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x149
+      LayoutNGBlockFlow (anonymous) at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 746x39
+          text run at (0,0) width 746: "This tests whether alt text is shown for image-type form input elements with no src attribute. You should see \"Success\""
+          text run at (0,20) width 225: "twice, followed by a blue rectangle."
+      LayoutNGBlockFlow {P} at (0,56) size 784x0
+      LayoutNGBlockFlow {FORM} at (0,56) size 784x93
+        LayoutBlockFlow {INPUT} at (0,0) size 67x16
+          LayoutInline {SPAN} at (0,0) size 51x16
+            LayoutImage (floating) {IMG} at (0,0) size 16x16
+            LayoutInline {SPAN} at (0,0) size 51x16
+              LayoutText {#text} at (16,0) size 51x16
+                text run at (16,0) width 51: "Success"
+        LayoutBR {BR} at (67,13) size 0x0
+        LayoutBlockFlow {INPUT} at (0,16) size 102x52 [border: (1px solid #000000)]
+        LayoutBR {BR} at (102,67) size 0x0
+        LayoutImage {INPUT} at (0,68) size 75x25
+        LayoutBR {BR} at (75,93) size 0x0
+layer at (9,81) size 100x50 clip at (10,82) size 98x48
+  LayoutBlockFlow {SPAN} at (1,1) size 100x50 [border: (1px solid #C0C0C0)]
+    LayoutImage (floating) {IMG} at (2,2) size 16x16
+    LayoutNGBlockFlow (anonymous) at (2,2) size 96x16
+      LayoutInline {SPAN} at (0,0) size 51x16
+        LayoutText {#text} at (16,0) size 51x16
+          text run at (16,0) width 51: "Success"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/month/month-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/month/month-appearance-basic-expected.png
new file mode 100644
index 0000000..0513366
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/month/month-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/month/month-appearance-pseudo-elements-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/month/month-appearance-pseudo-elements-expected.png
new file mode 100644
index 0000000..052f61a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/month/month-appearance-pseudo-elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/placeholder-position-expected.png
new file mode 100644
index 0000000..10626c3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/placeholder-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/placeholder-position-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/placeholder-position-expected.txt
new file mode 100644
index 0000000..323e928c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/placeholder-position-expected.txt
@@ -0,0 +1,175 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x378
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x378
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x362
+      LayoutTextControl {INPUT} at (0,0) size 156x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutFlexibleBox {DIV} at (3,3) size 150x16
+          LayoutBlockFlow {DIV} at (0,0) size 137x16
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutBR {BR} at (156,16) size 0x0
+      LayoutTextControl {INPUT} at (0,22) size 94x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+      LayoutText {#text} at (94,23) size 4x19
+        text run at (94,23) width 4: " "
+      LayoutTextControl {INPUT} at (98,22) size 94x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+      LayoutText {#text} at (192,23) size 4x19
+        text run at (192,23) width 4: " "
+      LayoutTextControl {INPUT} at (196,22) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutBR {BR} at (350,23) size 0x0
+      LayoutTextControl {INPUT} at (0,44) size 156x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutFlexibleBox {DIV} at (3,3) size 150x16
+          LayoutBlockFlow {DIV} at (12,0) size 138x16
+      LayoutBR {BR} at (156,45) size 0x0
+      LayoutTextControl {INPUT} at (0,66) size 156x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutFlexibleBox {DIV} at (3,3) size 150x16
+          LayoutBlockFlow {DIV} at (0,0) size 137x16
+      LayoutBR {BR} at (156,67) size 0x0
+      LayoutBR {BR} at (179,109) size 0x0
+      LayoutTextControl {INPUT} at (0,124) size 154x36 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+      LayoutBR {BR} at (154,125) size 0x0
+      LayoutBR {BR} at (179,194) size 0x0
+      LayoutTextControl {INPUT} at (5,214) size 183x29 [bgcolor=#FFFFFF] [border: (5px solid #000000)]
+      LayoutBR {BR} at (193,219) size 0x0
+      LayoutTextControl {INPUT} at (0,248) size 154x31 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+      LayoutText {#text} at (154,253) size 4x19
+        text run at (154,253) width 4: " "
+      LayoutTextControl {INPUT} at (158,248) size 154x31 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+      LayoutText {#text} at (312,253) size 4x19
+        text run at (312,253) width 4: " "
+      LayoutTextControl {INPUT} at (316,250.50) size 154x25 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+      LayoutText {#text} at (470,253) size 4x19
+        text run at (470,253) width 4: " "
+      LayoutTextControl {INPUT} at (474,251) size 154x25 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutTextControl {INPUT} at (0,279) size 154x25 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutBR {BR} at (154,281) size 0x0
+      LayoutTextControl {INPUT} at (0,304) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+      LayoutText {#text} at (154,305) size 4x19
+        text run at (154,305) width 4: " "
+      LayoutTextControl {INPUT} at (158,304) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+      LayoutText {#text} at (312,305) size 4x19
+        text run at (312,305) width 4: " "
+      LayoutTextControl {INPUT} at (316,304) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutBR {BR} at (470,305) size 0x0
+      LayoutBR {BR} at (154,341) size 0x0
+layer at (11,11) size 137x16
+  LayoutBlockFlow {DIV} at (3,3) size 137x16 [color=#757575]
+    LayoutText {#text} at (0,0) size 66x16
+      text run at (0,0) width 66: "placeholder"
+layer at (11,11) size 137x16
+  LayoutBlockFlow {DIV} at (0,0) size 137x16
+layer at (10,33) size 90x16
+  LayoutBlockFlow {DIV} at (2,3) size 90x16 [color=#757575]
+    LayoutText {#text} at (0,0) size 66x16
+      text run at (0,0) width 66: "placeholder"
+layer at (10,33) size 90x16
+  LayoutBlockFlow {DIV} at (2,3) size 90x16
+layer at (108,33) size 90x16
+  LayoutBlockFlow {DIV} at (2,3) size 90x16 [color=#757575]
+    LayoutText {#text} at (0,0) size 66x16
+      text run at (0,0) width 66: "placeholder"
+layer at (108,33) size 90x16
+  LayoutBlockFlow {DIV} at (2,3) size 90x16
+layer at (206,33) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16 [color=#757575]
+    LayoutText {#text} at (0,0) size 105x16
+      text run at (0,0) width 105: "\x{65E5}\x{672C}\x{8A9E}placeholder"
+layer at (206,33) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16
+layer at (23,55) size 138x16
+  LayoutBlockFlow {DIV} at (15,3) size 138x16 [color=#757575]
+    LayoutText {#text} at (72,0) size 66x16
+      text run at (72,0) width 66: "placeholder"
+layer at (23,55) size 138x16
+  LayoutBlockFlow {DIV} at (0,0) size 138x16
+layer at (11,77) size 137x16
+  LayoutBlockFlow {DIV} at (3,3) size 137x16 [color=#757575]
+    LayoutText {#text} at (0,0) size 66x16
+      text run at (0,0) width 66: "placeholder"
+layer at (11,77) size 137x16
+  LayoutBlockFlow {DIV} at (0,0) size 137x16
+layer at (8,96) size 179x36 clip at (9,97) size 177x34
+  LayoutTextControl {TEXTAREA} at (0,88) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 175x16 [color=#757575]
+      LayoutText {#text} at (0,0) size 88x16
+        text run at (0,0) width 88: "placeholder"
+    LayoutBlockFlow {DIV} at (3,3) size 175x16
+layer at (10,135) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16 [color=#757575]
+    LayoutText {#text} at (0,0) size 66x16
+      text run at (0,0) width 66: "placeholder"
+layer at (10,135) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16
+layer at (8,168) size 179x49 clip at (9,169) size 177x47
+  LayoutTextControl {TEXTAREA} at (0,160) size 179x49 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,16) size 175x16 [color=#757575]
+      LayoutText {#text} at (0,0) size 88x16
+        text run at (0,0) width 88: "placeholder"
+    LayoutBlockFlow {DIV} at (3,16) size 175x16
+layer at (18,228) size 173x17
+  LayoutBlockFlow {DIV} at (5,6) size 173x17 [color=#757575]
+    LayoutText {#text} at (0,0) size 75x17
+      text run at (0,0) width 75: "placeholder"
+layer at (18,228) size 173x17
+  LayoutBlockFlow {DIV} at (5,6) size 173x17
+layer at (10,259) size 150x25
+  LayoutBlockFlow {DIV} at (2,3) size 150x25
+    LayoutText {#text} at (0,4) size 32x16
+      text run at (0,4) width 32: "Value"
+layer at (168,263) size 150x16
+  LayoutBlockFlow {DIV} at (2,7) size 150x16 [color=#757575]
+    LayoutText {#text} at (0,0) size 66x16
+      text run at (0,0) width 66: "placeholder"
+layer at (168,259) size 150x25
+  LayoutBlockFlow {DIV} at (2,3) size 150x25
+layer at (326,263) size 150x16
+  LayoutBlockFlow {DIV} at (2,4.50) size 150x16 [color=#757575]
+    LayoutText {#text} at (0,0) size 66x16
+      text run at (0,0) width 66: "placeholder"
+layer at (326,263) size 150x16
+  LayoutBlockFlow {DIV} at (2,4.50) size 150x16
+layer at (484,263) size 150x16
+  LayoutBlockFlow {DIV} at (2,4) size 150x16 [color=#757575]
+    LayoutText {#text} at (0,0) size 66x16
+      text run at (0,0) width 66: "placeholder"
+layer at (484,259) size 150x25 backgroundClip at (484,261) size 150x21 clip at (484,261) size 150x21
+  LayoutBlockFlow {DIV} at (2,0) size 150x25
+layer at (10,292) size 150x16
+  LayoutBlockFlow {DIV} at (2,4.50) size 150x16 [color=#757575]
+    LayoutText {#text} at (0,0) size 66x16
+      text run at (0,0) width 66: "placeholder"
+layer at (10,292) size 150x16
+  LayoutBlockFlow {DIV} at (2,4.50) size 150x16
+layer at (10,315) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16
+    LayoutText {#text} at (59,0) size 32x16
+      text run at (59,0) width 32: "Value"
+layer at (168,315) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16 [color=#757575]
+    LayoutText {#text} at (42,0) size 66x16
+      text run at (42,0) width 66: "placeholder"
+layer at (168,315) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16
+layer at (326,315) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16 [color=#757575]
+    LayoutText {#text} at (42,0) size 66x16
+      text run at (42,0) width 66: "placeholder"
+layer at (326,315) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16
+layer at (149,15) size 9x9 transparent
+  LayoutBlockFlow {DIV} at (138,3.50) size 9x9
+layer at (11,59) size 9x9 transparent
+  LayoutBlockFlow {DIV} at (0,3.50) size 9x9
+layer at (149,81) size 9x9 transparent
+  LayoutBlockFlow {DIV} at (138,3.50) size 9x9
+layer at (8,334) size 154x36 backgroundClip at (9,328) size 152x108 clip at (10,336) size 150x32
+  LayoutTextControl {INPUT} at (0,326) size 154x36 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+layer at (10,351) size 150x16 backgroundClip at (13,344) size 137x88 clip at (13,351) size 137x16
+  LayoutBlockFlow {DIV} at (2,17) size 150x16 [color=#757575]
+    LayoutText {#text} at (0,0) size 66x16
+      text run at (0,0) width 66: "placeholder"
+layer at (10,351) size 150x16 backgroundClip at (13,344) size 137x88 clip at (13,351) size 137x16
+  LayoutBlockFlow {DIV} at (2,17) size 150x16
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/plaintext-mode-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/plaintext-mode-2-expected.png
new file mode 100644
index 0000000..0da669f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/plaintext-mode-2-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/plaintext-mode-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/plaintext-mode-2-expected.txt
new file mode 100644
index 0000000..8980f0be
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/plaintext-mode-2-expected.txt
@@ -0,0 +1,43 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x122
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x122
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x98
+      LayoutNGBlockFlow (anonymous) at (0,0) size 784x22
+        LayoutTextControl {INPUT} at (0,0) size 600x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutText {#text} at (0,0) size 0x0
+        LayoutBR {BR} at (600,16) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,22) size 784x20
+        LayoutText {#text} at (0,0) size 32x19
+          text run at (0,0) width 32: "This "
+        LayoutInline {B} at (0,0) size 109x19
+          LayoutText {#text} at (32,0) size 43x19
+            text run at (32,0) width 43: "styled "
+          LayoutInline {I} at (0,0) size 23x19
+            LayoutText {#text} at (75,0) size 23x19
+              text run at (75,0) width 23: "text"
+        LayoutText {#text} at (98,0) size 35x19
+          text run at (98,0) width 35: ", and "
+        LayoutInline {A} at (0,0) size 24x19 [color=#0000EE]
+          LayoutText {#text} at (133,0) size 24x19
+            text run at (133,0) width 24: "link"
+        LayoutText {#text} at (157,0) size 403x19
+          text run at (157,0) width 403: " will be pasted into the textfield. All richness should be stripped."
+      LayoutNGBlockFlow {OL} at (0,58) size 784x40
+        LayoutNGListItem {LI} at (40,0) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-16,0) size 16x20
+            LayoutText (anonymous) at (0,0) size 16x19
+              text run at (0,0) width 16: "1. "
+          LayoutText {#text} at (0,0) size 328x19
+            text run at (0,0) width 328: "Success: document.execCommand(\"Copy\") == true"
+        LayoutNGListItem {LI} at (40,20) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-16,0) size 16x20
+            LayoutText (anonymous) at (0,0) size 16x19
+              text run at (0,0) width 16: "2. "
+          LayoutText {#text} at (0,0) size 326x19
+            text run at (0,0) width 326: "Success: document.execCommand(\"Paste\") == true"
+layer at (10,11) size 596x16
+  LayoutBlockFlow {DIV} at (2,3) size 596x16
+    LayoutText {#text} at (0,0) size 513x16
+      text run at (0,0) width 513: "This styled text, and link will be pasted into the textfield. All richness should be stripped."
+caret: position 94 of child 0 {#text} of child 0 {DIV} of {#document-fragment} of child 0 {INPUT} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/range/slider-thumb-shared-style-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/range/slider-thumb-shared-style-expected.png
new file mode 100644
index 0000000..4b0a1f13
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/range/slider-thumb-shared-style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/range/slider-thumb-shared-style-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/range/slider-thumb-shared-style-expected.txt
new file mode 100644
index 0000000..179e075
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/range/slider-thumb-shared-style-expected.txt
@@ -0,0 +1,30 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x138
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x138
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x122
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 1009x19
+          LayoutInline {A} at (0,0) size 302x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 302x19
+              text run at (51,0) width 302: "http://bugs.webkit.org/show_bug.cgi?id=13800"
+          LayoutText {#text} at (352,0) size 408x19
+            text run at (352,0) width 408: " REGRESSION: Moving a slider moves another unrelated slider"
+        LayoutText {#text} at (759,0) size 5x19
+          text run at (759,0) width 5: "."
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (0,0) size 282x19
+          text run at (0,0) width 282: "The first slider\x{2019}s thumb should be on the left."
+      LayoutNGBlockFlow {DIV} at (0,72) size 784x50
+        LayoutSlider {INPUT} at (2,2) size 129x21 [color=#9D968E] [bgcolor=#FFFFFF]
+          LayoutFlexibleBox {DIV} at (0,0) size 129x21
+            LayoutBlockFlow {DIV} at (0,0) size 129x21
+              LayoutBlockFlow {DIV} at (0,0) size 11x21
+        LayoutBR {BR} at (133,23) size 0x0
+        LayoutSlider {INPUT} at (2,27) size 129x21 [color=#9D968E] [bgcolor=#FFFFFF]
+          LayoutFlexibleBox {DIV} at (0,0) size 129x21
+            LayoutBlockFlow {DIV} at (0,0) size 129x21
+              LayoutBlockFlow {DIV} at (118,0) size 11x21
+        LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select-popup/popup-menu-appearance-transform-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
new file mode 100644
index 0000000..cb372b2c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select-popup/popup-menu-appearance-zoom-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select-popup/popup-menu-appearance-zoom-expected.png
new file mode 100644
index 0000000..505d3714e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select-popup/popup-menu-appearance-zoom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/listbox-scrollbar-incremental-load-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/listbox-scrollbar-incremental-load-expected.png
new file mode 100644
index 0000000..6ced729
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/listbox-scrollbar-incremental-load-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/listbox-scrollbar-incremental-load-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/listbox-scrollbar-incremental-load-expected.txt
new file mode 100644
index 0000000..7e9a543
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/listbox-scrollbar-incremental-load-expected.txt
@@ -0,0 +1,46 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x198
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x198
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x182
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 1116x39
+          LayoutInline {A} at (0,0) size 302x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 302x19
+              text run at (51,0) width 302: "http://bugs.webkit.org/show_bug.cgi?id=13500"
+          LayoutText {#text} at (352,0) size 764x39
+            text run at (352,0) width 412: " REGRESSION: Listbox scrollbar does not reflect actual scrolled"
+            text run at (0,20) width 319: "position when selected option is added after layout"
+        LayoutText {#text} at (319,20) size 4x19
+          text run at (319,20) width 4: "."
+      LayoutNGBlockFlow {P} at (0,56) size 784x40
+        LayoutText {#text} at (0,0) size 780x39
+          text run at (0,0) width 780: "The list box should be scrolled all the way down, showing the selected option \x{201C}Seven\x{201D}. The scroller should be at the bottom"
+          text run at (0,20) width 187: "of the scroll bar to reflect this."
+      LayoutNGBlockFlow (anonymous) at (0,112) size 784x70
+        LayoutText {#text} at (0,0) size 0x0
+layer at (8,120) size 58x70 clip at (9,121) size 41x68 scrollY 51.00 scrollHeight 119
+  LayoutListBox {SELECT} at (0,0) size 58x70 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {OPTION} at (1,1) size 41x17
+      LayoutText {#text} at (2,0) size 24x16
+        text run at (2,0) width 24: "One"
+    LayoutBlockFlow {OPTION} at (1,18) size 41x17
+      LayoutText {#text} at (2,0) size 24x16
+        text run at (2,0) width 24: "Two"
+    LayoutBlockFlow {OPTION} at (1,35) size 41x17
+      LayoutText {#text} at (2,0) size 33x16
+        text run at (2,0) width 33: "Three"
+    LayoutBlockFlow {OPTION} at (1,52) size 41x17
+      LayoutText {#text} at (2,0) size 26x16
+        text run at (2,0) width 26: "Four"
+    LayoutBlockFlow {OPTION} at (1,69) size 41x17
+      LayoutText {#text} at (2,0) size 25x16
+        text run at (2,0) width 25: "Five"
+    LayoutBlockFlow {OPTION} at (1,86) size 41x17
+      LayoutText {#text} at (2,0) size 19x16
+        text run at (2,0) width 19: "Six"
+    LayoutBlockFlow {OPTION} at (1,103) size 41x17 [color=#FFFFFF] [bgcolor=#999999]
+      LayoutText {#text} at (2,0) size 37x16
+        text run at (2,0) width 37: "Seven"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/menulist-appearance-none-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/menulist-appearance-none-expected.png
new file mode 100644
index 0000000..14a717a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/menulist-appearance-none-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/menulist-appearance-none-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/menulist-appearance-none-expected.txt
new file mode 100644
index 0000000..0381107
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/menulist-appearance-none-expected.txt
@@ -0,0 +1,23 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x114
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x114
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x98
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 117x19
+          text run at (0,0) width 117: "Rendering test for "
+        LayoutInline {I} at (0,0) size 1303x39
+          LayoutInline {A} at (0,0) size 407x19 [color=#0000EE]
+            LayoutText {#text} at (117,0) size 407x19
+              text run at (117,0) width 407: "https://bugs.chromium.org/p/chromium/issues/detail?id=626278"
+          LayoutText {#text} at (523,0) size 780x39
+            text run at (523,0) width 257: " Regression: HTML Select's text appears"
+            text run at (0,20) width 231: "chopped if appearance is set to none"
+        LayoutText {#text} at (231,20) size 4x19
+          text run at (231,20) width 4: "."
+      LayoutNGBlockFlow (anonymous) at (0,56) size 784x42
+        LayoutMenuList {SELECT} at (0,0) size 27x42 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+          LayoutNGBlockFlow (anonymous) at (1,1) size 25x40
+            LayoutText (anonymous) at (0,12) size 25x16
+              text run at (0,12) width 25: "Test"
+        LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/menulist-option-wrap-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/menulist-option-wrap-expected.png
new file mode 100644
index 0000000..f6c553c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/menulist-option-wrap-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/menulist-option-wrap-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/menulist-option-wrap-expected.txt
new file mode 100644
index 0000000..5154757
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/menulist-option-wrap-expected.txt
@@ -0,0 +1,42 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x116
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x92
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 873x19
+          LayoutInline {A} at (0,0) size 300x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 301x19
+              text run at (51,0) width 301: "http://bugs.webkit.org/show_bug.cgi?id=11362"
+          LayoutText {#text} at (351,0) size 274x19
+            text run at (351,0) width 274: " Native popup with size=\"1\" wraps options"
+        LayoutText {#text} at (624,0) size 5x19
+          text run at (624,0) width 5: "."
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (0,0) size 35x19
+          text run at (0,0) width 35: "With "
+        LayoutInline {TT} at (0,0) size 65x16
+          LayoutText {#text} at (34,3) size 65x16
+            text run at (34,3) width 65: "size=\"1\""
+        LayoutText {#text} at (98,0) size 9x19
+          text run at (98,0) width 9: ": "
+        LayoutMenuList {SELECT} at (106.36,1) size 100x18 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+          LayoutNGBlockFlow (anonymous) at (1,1) size 98x16
+            LayoutText (anonymous) at (0,0) size 189x16
+              text run at (0,0) width 189: "Very long option that does not fit"
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {P} at (0,72) size 784x20
+        LayoutText {#text} at (0,0) size 55x19
+          text run at (0,0) width 55: "Without "
+        LayoutInline {TT} at (0,0) size 33x16
+          LayoutText {#text} at (54,3) size 33x16
+            text run at (54,3) width 33: "size"
+        LayoutText {#text} at (86,0) size 9x19
+          text run at (86,0) width 9: ": "
+        LayoutMenuList {SELECT} at (94.36,1) size 100x18 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+          LayoutNGBlockFlow (anonymous) at (1,1) size 98x16
+            LayoutText (anonymous) at (0,0) size 189x16
+              text run at (0,0) width 189: "Very long option that does not fit"
+        LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-script-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-script-expected.png
new file mode 100644
index 0000000..bbe17bd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-script-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-script-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-script-expected.txt
new file mode 100644
index 0000000..0ee47cb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-script-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x76
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x76
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x60
+      LayoutText {#text} at (0,0) size 340x19
+        text run at (0,0) width 340: "TEST PASSED: If the popup menu only says \"Text\"."
+      LayoutBR {BR} at (339,0) size 0x0
+      LayoutText {#text} at (0,20) size 419x19
+        text run at (0,20) width 419: "TEST FAILED: If the popup menu says \"document.write('Text')\"."
+      LayoutBR {BR} at (418,20) size 0x0
+      LayoutMenuList {SELECT} at (0,40) size 47x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+        LayoutNGBlockFlow (anonymous) at (1,1) size 45x18
+          LayoutText (anonymous) at (4,1) size 25x16
+            text run at (4,1) width 25: "Text"
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-strip-whitespace-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-strip-whitespace-expected.png
index 2ea51b3..86d5350 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-strip-whitespace-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-strip-whitespace-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-strip-whitespace-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-strip-whitespace-expected.txt
index 3d47dec..43eb93d1f 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-strip-whitespace-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/option-strip-whitespace-expected.txt
@@ -40,11 +40,11 @@
         LayoutText {#text} at (0,0) size 0x0
 layer at (78,44) size 77x70 clip at (79,45) size 60x68
   LayoutListBox {SELECT} at (69.59,0) size 77.53x70 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
-    LayoutNGBlockFlow {OPTION} at (1,1) size 60.53x17
+    LayoutBlockFlow {OPTION} at (1,1) size 60.53x17
       LayoutText {#text} at (2,0) size 57x16
         text run at (2,0) width 57: "Five Tabs"
 layer at (92,135) size 78x70 clip at (93,136) size 61x68
   LayoutListBox {SELECT} at (84,91) size 77.53x70 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
-    LayoutNGBlockFlow {OPTION} at (1,1) size 60.53x17
+    LayoutBlockFlow {OPTION} at (1,1) size 60.53x17
       LayoutText {#text} at (2,0) size 57x16
         text run at (2,0) width 57: "Five Tabs"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-change-listbox-size-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-change-listbox-size-expected.png
new file mode 100644
index 0000000..1da9857
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-change-listbox-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-change-listbox-size-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-change-listbox-size-expected.txt
new file mode 100644
index 0000000..19e4401
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-change-listbox-size-expected.txt
@@ -0,0 +1,42 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x212
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x212
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x196
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 1136x39
+          LayoutInline {A} at (0,0) size 302x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 302x19
+              text run at (51,0) width 302: "http://bugs.webkit.org/show_bug.cgi?id=12986"
+          LayoutText {#text} at (352,0) size 784x39
+            text run at (352,0) width 432: " REGRESSION(NativeListBox): Listboxes not updated when resized"
+            text run at (0,20) width 77: "dynamically"
+        LayoutText {#text} at (77,20) size 4x19
+          text run at (77,20) width 4: "."
+      LayoutNGBlockFlow {P} at (0,56) size 784x20
+        LayoutText {#text} at (0,0) size 316x19
+          text run at (0,0) width 316: "This list box should be tall enough to fit 6 options."
+      LayoutNGBlockFlow (anonymous) at (0,92) size 784x104
+        LayoutText {#text} at (0,0) size 0x0
+layer at (8,100) size 54x104 clip at (9,101) size 37x102
+  LayoutListBox {SELECT} at (0,0) size 54x104 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {OPTION} at (1,1) size 37x17
+      LayoutText {#text} at (2,0) size 24x16
+        text run at (2,0) width 24: "One"
+    LayoutBlockFlow {OPTION} at (1,18) size 37x17
+      LayoutText {#text} at (2,0) size 24x16
+        text run at (2,0) width 24: "Two"
+    LayoutBlockFlow {OPTION} at (1,35) size 37x17
+      LayoutText {#text} at (2,0) size 33x16
+        text run at (2,0) width 33: "Three"
+    LayoutBlockFlow {OPTION} at (1,52) size 37x17
+      LayoutText {#text} at (2,0) size 26x16
+        text run at (2,0) width 26: "Four"
+    LayoutBlockFlow {OPTION} at (1,69) size 37x17
+      LayoutText {#text} at (2,0) size 25x16
+        text run at (2,0) width 25: "Five"
+    LayoutBlockFlow {OPTION} at (1,86) size 37x17
+      LayoutText {#text} at (2,0) size 19x16
+        text run at (2,0) width 19: "Six"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-disabled-appearance-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-disabled-appearance-expected.png
new file mode 100644
index 0000000..1302801
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-disabled-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-disabled-appearance-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-disabled-appearance-expected.txt
new file mode 100644
index 0000000..73f8cb79
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-disabled-appearance-expected.txt
@@ -0,0 +1,28 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x116
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x92
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 953x19
+          LayoutInline {A} at (0,0) size 302x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 302x19
+              text run at (51,0) width 302: "http://bugs.webkit.org/show_bug.cgi?id=12345"
+          LayoutText {#text} at (352,0) size 352x19
+            text run at (352,0) width 352: " REGRESSION: Disabled pop-up text is not grayed out"
+        LayoutText {#text} at (703,0) size 5x19
+          text run at (703,0) width 5: "."
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutMenuList {SELECT} at (0,0) size 162x20 [color=#808080] [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+          LayoutNGBlockFlow (anonymous) at (1,1) size 160x18
+            LayoutText (anonymous) at (4,1) size 140x16
+              text run at (4,1) width 140: "This text should be gray"
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {P} at (0,72) size 784x20
+        LayoutMenuList {SELECT} at (0,0) size 168x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+          LayoutNGBlockFlow (anonymous) at (1,1) size 166x18
+            LayoutText (anonymous) at (4,1) size 146x16
+              text run at (4,1) width 146: "This text should be black"
+        LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-display-none-style-resolve-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-display-none-style-resolve-expected.png
new file mode 100644
index 0000000..2cfc56c8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-display-none-style-resolve-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-display-none-style-resolve-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-display-none-style-resolve-expected.txt
new file mode 100644
index 0000000..0b12e6c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-display-none-style-resolve-expected.txt
@@ -0,0 +1,20 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x100
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x100
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x76
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 1122x39
+          LayoutInline {A} at (0,0) size 302x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 302x19
+              text run at (51,0) width 302: "http://bugs.webkit.org/show_bug.cgi?id=13896"
+          LayoutText {#text} at (352,0) size 770x39
+            text run at (352,0) width 418: " REGRESSION (NativePopup): Reproductible crasher on Google"
+            text run at (0,20) width 123: "Coop control panel"
+        LayoutText {#text} at (122,20) size 5x19
+          text run at (122,20) width 5: "."
+      LayoutNGBlockFlow {P} at (0,56) size 784x20
+        LayoutText {#text} at (0,0) size 180x19
+          text run at (0,0) width 180: "No crash means SUCCESS."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-item-background-clip-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-item-background-clip-expected.png
new file mode 100644
index 0000000..6ef7662
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-item-background-clip-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-item-background-clip-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-item-background-clip-expected.txt
new file mode 100644
index 0000000..8e761b8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-item-background-clip-expected.txt
@@ -0,0 +1,33 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x140
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x139.75
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x123.75
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 1123x39
+          LayoutInline {A} at (0,0) size 302x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 302x19
+              text run at (51,0) width 302: "http://bugs.webkit.org/show_bug.cgi?id=12364"
+          LayoutText {#text} at (352,0) size 771x39
+            text run at (352,0) width 419: " REGRESSSION (NativeListBox): Selected option's background is"
+            text run at (0,20) width 158: "not clipped to the list box"
+        LayoutText {#text} at (158,20) size 4x19
+          text run at (158,20) width 4: "."
+      LayoutNGBlockFlow (anonymous) at (0,56) size 784x67.75
+        LayoutText {#text} at (0,0) size 0x0
+layer at (8,64) size 60x68 clip at (11,67) size 39x62 scrollHeight 74
+  LayoutListBox {SELECT} at (0,0) size 60x67.75 [bgcolor=#FFFFFF] [border: (3px solid #0000FF)]
+    LayoutBlockFlow {OPTION} at (6,6) size 33x17
+      LayoutText {#text} at (2,0) size 21x16
+        text run at (2,0) width 21: "one"
+    LayoutBlockFlow {OPTION} at (6,23) size 33x17
+      LayoutText {#text} at (2,0) size 20x16
+        text run at (2,0) width 20: "two"
+    LayoutBlockFlow {OPTION} at (6,40) size 33x17
+      LayoutText {#text} at (2,0) size 29x16
+        text run at (2,0) width 29: "three"
+    LayoutBlockFlow {OPTION} at (6,57) size 33x17 [bgcolor=#800080]
+      LayoutText {#text} at (2,0) size 22x16
+        text run at (2,0) width 22: "four"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-multiple-rtl-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-multiple-rtl-expected.png
new file mode 100644
index 0000000..7b1eb531
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-multiple-rtl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-writing-direction-natural-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-writing-direction-natural-expected.png
new file mode 100644
index 0000000..6fa6d25
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-writing-direction-natural-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-writing-direction-natural-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-writing-direction-natural-expected.txt
new file mode 100644
index 0000000..a3463bc6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/select/select-writing-direction-natural-expected.txt
@@ -0,0 +1,140 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x188
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x188
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x172
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 1061x39
+          LayoutInline {A} at (0,0) size 302x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 302x19
+              text run at (51,0) width 302: "http://bugs.webkit.org/show_bug.cgi?id=13775"
+          LayoutText {#text} at (352,0) size 709x39
+            text run at (352,0) width 357: " REGRESSION: Popup button text should use \"natural\""
+            text run at (0,20) width 324: "directionality to match the items in the popup menu"
+        LayoutText {#text} at (323,20) size 5x19
+          text run at (323,20) width 5: "."
+      LayoutNGBlockFlow {P} at (0,56) size 784x20
+        LayoutText {#text} at (0,0) size 659x19
+          text run at (0,0) width 506: "In all of the popup buttons below, the letter A should be on the left and the letter "
+          text run at (505,0) width 9: "\x{5D0}"
+          text run at (513,0) width 146: " should be on the right."
+      LayoutNGBlockFlow {DIV} at (0,92) size 784x40
+        LayoutNGBlockFlow {DIV} at (0,0) size 784x20
+          LayoutMenuList {SELECT} at (0,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (4,1) size 16x16
+                text run at (4,1) width 7 RTL: "\x{5D0}"
+                text run at (11,1) width 9: "A"
+          LayoutText {#text} at (70,0) size 4x19
+            text run at (70,0) width 4: " "
+          LayoutMenuList {SELECT} at (74,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (4,1) size 16x16
+                text run at (4,1) width 9: "A"
+                text run at (13,1) width 7 RTL: "\x{5D0}"
+          LayoutText {#text} at (144,0) size 4x19
+            text run at (144,0) width 4: " "
+          LayoutMenuList {SELECT} at (148,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (4,1) size 20x16
+                text run at (4,1) width 4: "("
+                text run at (8,1) width 7 RTL: "\x{5D0}"
+                text run at (15,1) width 9: "A"
+          LayoutText {#text} at (218,0) size 4x19
+            text run at (218,0) width 4: " "
+          LayoutMenuList {SELECT} at (222,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (4,1) size 20x16
+                text run at (4,1) width 13: "(A"
+                text run at (17,1) width 7 RTL: "\x{5D0}"
+          LayoutText {#text} at (0,0) size 0x0
+        LayoutNGBlockFlow {DIV} at (0,20) size 784x20
+          LayoutMenuList {SELECT} at (492,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (4,1) size 16x16
+                text run at (4,1) width 7 RTL: "\x{5D0}"
+                text run at (11,1) width 9: "A"
+          LayoutText {#text} at (562,0) size 4x19
+            text run at (562,0) width 4: " "
+          LayoutMenuList {SELECT} at (566,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (4,1) size 16x16
+                text run at (4,1) width 9: "A"
+                text run at (13,1) width 7 RTL: "\x{5D0}"
+          LayoutText {#text} at (636,0) size 4x19
+            text run at (636,0) width 4: " "
+          LayoutMenuList {SELECT} at (640,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (4,1) size 20x16
+                text run at (4,1) width 4: "("
+                text run at (8,1) width 7 RTL: "\x{5D0}"
+                text run at (15,1) width 9: "A"
+          LayoutText {#text} at (710,0) size 4x19
+            text run at (710,0) width 4: " "
+          LayoutMenuList {SELECT} at (714,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (4,1) size 20x16
+                text run at (4,1) width 13: "(A"
+                text run at (17,1) width 7 RTL: "\x{5D0}"
+          LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,132) size 784x40
+        LayoutNGBlockFlow {DIV} at (0,0) size 784x20
+          LayoutMenuList {SELECT} at (222,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (48,1) size 16x16
+                text run at (48,1) width 9: "A"
+                text run at (57,1) width 7 RTL: "\x{5D0}"
+          LayoutText {#text} at (218,0) size 4x19
+            text run at (218,0) width 4: " "
+          LayoutMenuList {SELECT} at (148,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (48,1) size 16x16
+                text run at (48,1) width 7 RTL: "\x{5D0}"
+                text run at (55,1) width 9: "A"
+          LayoutText {#text} at (144,0) size 4x19
+            text run at (144,0) width 4: " "
+          LayoutMenuList {SELECT} at (74,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (44,1) size 20x16
+                text run at (44,1) width 9: "A"
+                text run at (53,1) width 11 RTL: "(\x{5D0}"
+          LayoutText {#text} at (70,0) size 4x19
+            text run at (70,0) width 4: " "
+          LayoutMenuList {SELECT} at (0,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (44,1) size 20x16
+                text run at (44,1) width 7 RTL: "\x{5D0}"
+                text run at (51,1) width 9: "A"
+                text run at (60,1) width 4 RTL: "("
+          LayoutText {#text} at (0,0) size 0x0
+        LayoutNGBlockFlow {DIV} at (0,20) size 784x20
+          LayoutMenuList {SELECT} at (714,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (48,1) size 16x16
+                text run at (48,1) width 9: "A"
+                text run at (57,1) width 7 RTL: "\x{5D0}"
+          LayoutText {#text} at (710,0) size 4x19
+            text run at (710,0) width 4: " "
+          LayoutMenuList {SELECT} at (640,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (48,1) size 16x16
+                text run at (48,1) width 7 RTL: "\x{5D0}"
+                text run at (55,1) width 9: "A"
+          LayoutText {#text} at (636,0) size 4x19
+            text run at (636,0) width 4: " "
+          LayoutMenuList {SELECT} at (566,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (44,1) size 20x16
+                text run at (44,1) width 9: "A"
+                text run at (53,1) width 11 RTL: "(\x{5D0}"
+          LayoutText {#text} at (562,0) size 4x19
+            text run at (562,0) width 4: " "
+          LayoutMenuList {SELECT} at (492,0) size 70x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
+            LayoutNGBlockFlow (anonymous) at (1,1) size 68x18
+              LayoutText (anonymous) at (44,1) size 20x16
+                text run at (44,1) width 7 RTL: "\x{5D0}"
+                text run at (51,1) width 9: "A"
+                text run at (60,1) width 4 RTL: "("
+          LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/targeted-frame-submission-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/targeted-frame-submission-expected.png
new file mode 100644
index 0000000..6c29362
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/targeted-frame-submission-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/targeted-frame-submission-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/targeted-frame-submission-expected.txt
new file mode 100644
index 0000000..bcd4199
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/targeted-frame-submission-expected.txt
@@ -0,0 +1,28 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x248
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x248
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x232
+      LayoutNGBlockFlow {FORM} at (0,0) size 784x22
+        LayoutButton {INPUT} at (0,0) size 42x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
+          LayoutNGBlockFlow (anonymous) at (8,3) size 26x16
+            LayoutText {#text} at (0,0) size 26x16
+              text run at (0,0) width 26: "form"
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,38) size 784x40
+        LayoutText {#text} at (0,0) size 760x39
+          text run at (0,0) width 760: "This tests Targeted frame submission works. If the test is successful, the text \"SUCCESS\" should be shown in the iframe"
+          text run at (0,20) width 42: "below."
+      LayoutNGBlockFlow (anonymous) at (0,78) size 784x154
+        LayoutText {#text} at (0,0) size 0x0
+layer at (8,86) size 304x154
+  LayoutIFrame {IFRAME} at (0,0) size 304x154 [border: (2px inset #EEEEEE)]
+    layer at (0,0) size 300x150
+      LayoutView at (0,0) size 300x150
+    layer at (0,0) size 300x37
+      LayoutNGBlockFlow {HTML} at (0,0) size 300x37
+        LayoutNGBlockFlow {BODY} at (8,8) size 284x16
+          LayoutNGBlockFlow {PRE} at (0,0) size 284x16
+            LayoutText {#text} at (0,0) size 56x16
+              text run at (0,0) width 56: "SUCCESS"
+              text run at (56,0) width 0: " "
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/input-appearance-focus-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/input-appearance-focus-expected.png
new file mode 100644
index 0000000..dc6b7b08
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/input-appearance-focus-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/input-appearance-focus-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/input-appearance-focus-expected.txt
new file mode 100644
index 0000000..a0d6508c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/input-appearance-focus-expected.txt
@@ -0,0 +1,34 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x178
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x178
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x154
+      LayoutNGBlockFlow (anonymous) at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 754x19
+          text run at (0,0) width 754: "This test uses the new text field to test focus() and blur() and to make sure that onFocus and onBlur events fire correctly."
+      LayoutNGBlockFlow {P} at (0,36) size 784x22
+        LayoutTextControl {INPUT} at (0,0) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutText {#text} at (154,1) size 4x19
+          text run at (154,1) width 4: " "
+        LayoutTextControl {INPUT} at (158,0) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,74) size 784x80
+        LayoutBR {BR} at (0,0) size 0x0
+        LayoutText {#text} at (0,20) size 320x19
+          text run at (0,20) width 320: "Test Passed. Text field 1's onFocus event has fired."
+        LayoutBR {BR} at (319,20) size 0x0
+        LayoutText {#text} at (0,40) size 310x19
+          text run at (0,40) width 310: "Test Passed. Text field 1's onBlur event has fired."
+        LayoutBR {BR} at (309,40) size 0x0
+        LayoutText {#text} at (0,60) size 320x19
+          text run at (0,60) width 320: "Test Passed. Text field 2's onFocus event has fired."
+      LayoutNGBlockFlow {P} at (0,170) size 784x0
+layer at (10,47) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16
+    LayoutText {#text} at (0,0) size 90x16
+      text run at (0,0) width 90: "My Text Field 1"
+layer at (168,47) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16
+    LayoutText {#text} at (0,0) size 90x16
+      text run at (0,0) width 90: "My Text Field 2"
+caret: position 0 of child 0 {#text} of child 0 {DIV} of {#document-fragment} of child 3 {INPUT} of child 1 {P} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/input-text-scroll-left-on-blur-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/input-text-scroll-left-on-blur-expected.png
new file mode 100644
index 0000000..48779cc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/input-text-scroll-left-on-blur-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/input-text-scroll-left-on-blur-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/input-text-scroll-left-on-blur-expected.txt
new file mode 100644
index 0000000..c695e76
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/input-text-scroll-left-on-blur-expected.txt
@@ -0,0 +1,31 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x102
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x102
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x78
+      LayoutNGBlockFlow (anonymous) at (0,0) size 784x22
+        LayoutTextControl {INPUT} at (0,0) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutText {#text} at (154,1) size 4x19
+          text run at (154,1) width 4: " "
+        LayoutTextControl {INPUT} at (158,0) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutText {#text} at (312,1) size 4x19
+          text run at (312,1) width 4: " "
+        LayoutTextControl {INPUT} at (316,0) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {P} at (0,38) size 784x40
+        LayoutText {#text} at (0,0) size 783x39
+          text run at (0,0) width 783: "Tests scrolling back to the beginning when a text field blurs. The first field should be scrolled to the left, the second and third"
+          text run at (0,20) width 125: "scrolled to the right."
+layer at (10,11) size 150x16 scrollWidth 340
+  LayoutBlockFlow {DIV} at (2,3) size 150x16
+    LayoutText {#text} at (0,0) size 339x16
+      text run at (0,0) width 339: "this text field has a lot of text in it so that it needs to scroll"
+layer at (168,11) size 150x16 scrollX 189.00 scrollWidth 339
+  LayoutBlockFlow {DIV} at (2,3) size 150x16
+    LayoutText {#text} at (-189,0) size 339x16
+      text run at (-189,0) width 339: "this text field has a lot of text in it so that it needs to scroll"
+layer at (326,11) size 150x16 scrollX 190.00 scrollWidth 340
+  LayoutBlockFlow {DIV} at (2,3) size 150x16
+    LayoutText {#text} at (0,0) size 339x16
+      text run at (0,0) width 339: "this text field has a lot of text in it so that it needs to scroll"
+caret: position 66 of child 0 {#text} of child 0 {DIV} of {#document-fragment} of child 4 {INPUT} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/textfield-focus-ring-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/textfield-focus-ring-expected.png
new file mode 100644
index 0000000..a306d38
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/textfield-focus-ring-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/textfield-focus-ring-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/textfield-focus-ring-expected.txt
new file mode 100644
index 0000000..d5844ff
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/text/textfield-focus-ring-expected.txt
@@ -0,0 +1,15 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x94
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x94
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x78
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 779x39
+          text run at (0,0) width 779: "Assuming the port-specific theme draws focus rings, this test can be used to ensure that a focus ring is drawn for a text input"
+          text run at (0,20) width 567: "element. This test PASSED if a focus ring is drawn around the text input element (below)."
+      LayoutNGBlockFlow (anonymous) at (0,56) size 784x22
+        LayoutTextControl {INPUT} at (0,0) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutText {#text} at (0,0) size 0x0
+layer at (10,67) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16
+caret: position 0 of child 0 {DIV} of {#document-fragment} of child 3 {INPUT} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/textarea/basic-textareas-quirks-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/textarea/basic-textareas-quirks-expected.png
new file mode 100644
index 0000000..f8f7559
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/textarea/basic-textareas-quirks-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/textarea/basic-textareas-quirks-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/textarea/basic-textareas-quirks-expected.txt
new file mode 100644
index 0000000..5647e19
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/textarea/basic-textareas-quirks-expected.txt
@@ -0,0 +1,847 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 1054
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x1054 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 785x1054
+    LayoutNGBlockFlow {BODY} at (8,8) size 769x0
+      LayoutNGBlockFlow (floating) {DIV} at (0,0) size 352x862 [border: (1px solid #FF0000)]
+        LayoutNGBlockFlow (anonymous) at (1,1) size 350x14
+          LayoutText {#text} at (0,-1) size 181x16
+            text run at (0,-1) width 181: "Plain textarea with little content"
+        LayoutNGBlockFlow {DIV} at (1,15) size 352x40 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,24) size 14x16
+            text run at (1,24) width 14: "A "
+          LayoutText {#text} at (193,24) size 14x16
+            text run at (193,24) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,55) size 350x14
+          LayoutText {#text} at (0,-1) size 77x16
+            text run at (0,-1) width 77: "Plain textarea"
+        LayoutNGBlockFlow {DIV} at (1,69) size 352x40 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,24) size 14x16
+            text run at (1,24) width 14: "A "
+          LayoutText {#text} at (193,24) size 14x16
+            text run at (193,24) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,109) size 350x14
+          LayoutText {#text} at (0,-1) size 97x16
+            text run at (0,-1) width 97: "Disabled textarea"
+        LayoutNGBlockFlow {DIV} at (1,123) size 352x40 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,24) size 14x16
+            text run at (1,24) width 14: "A "
+          LayoutText {#text} at (193,24) size 14x16
+            text run at (193,24) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,163) size 350x14
+          LayoutText {#text} at (0,-1) size 123x16
+            text run at (0,-1) width 123: "style=\"padding:10px\""
+        LayoutNGBlockFlow {DIV} at (1,177) size 352x58 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,42) size 14x16
+            text run at (1,42) width 14: "A "
+          LayoutText {#text} at (211,42) size 14x16
+            text run at (211,42) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,235) size 350x14
+          LayoutText {#text} at (0,-1) size 116x16
+            text run at (0,-1) width 116: "style=\"padding:0px\""
+        LayoutNGBlockFlow {DIV} at (1,249) size 352x38 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,22) size 14x16
+            text run at (1,22) width 14: "A "
+          LayoutText {#text} at (191,22) size 14x16
+            text run at (191,22) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,287) size 350x14
+          LayoutText {#text} at (0,-1) size 118x16
+            text run at (0,-1) width 118: "style=\"margin:10px\""
+        LayoutNGBlockFlow {DIV} at (1,301) size 352x60 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,44) size 14x16
+            text run at (1,44) width 14: "A "
+          LayoutText {#text} at (213,44) size 14x16
+            text run at (213,44) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,361) size 350x14
+          LayoutText {#text} at (0,-1) size 111x16
+            text run at (0,-1) width 111: "style=\"margin:0px\""
+        LayoutNGBlockFlow {DIV} at (1,375) size 352x40 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,24) size 14x16
+            text run at (1,24) width 14: "A "
+          LayoutText {#text} at (193,24) size 14x16
+            text run at (193,24) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,415) size 350x14
+          LayoutText {#text} at (0,-1) size 37x16
+            text run at (0,-1) width 37: "cols=3"
+        LayoutNGBlockFlow {DIV} at (1,429) size 352x40 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,24) size 14x16
+            text run at (1,24) width 14: "A "
+          LayoutText {#text} at (57,24) size 14x16
+            text run at (57,24) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,469) size 350x14
+          LayoutText {#text} at (0,-1) size 42x16
+            text run at (0,-1) width 42: "rows=3"
+        LayoutNGBlockFlow {DIV} at (1,483) size 352x56 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,40) size 14x16
+            text run at (1,40) width 14: "A "
+          LayoutText {#text} at (193,40) size 14x16
+            text run at (193,40) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,539) size 350x14
+          LayoutText {#text} at (0,-1) size 44x16
+            text run at (0,-1) width 44: "cols=10"
+        LayoutNGBlockFlow {DIV} at (1,553) size 352x40 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,24) size 14x16
+            text run at (1,24) width 14: "A "
+          LayoutText {#text} at (113,24) size 14x16
+            text run at (113,24) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,593) size 350x14
+          LayoutText {#text} at (0,-1) size 49x16
+            text run at (0,-1) width 49: "rows=10"
+        LayoutNGBlockFlow {DIV} at (1,607) size 352x168 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,152) size 14x16
+            text run at (1,152) width 14: "A "
+          LayoutText {#text} at (193,152) size 14x16
+            text run at (193,152) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,775) size 350x14
+          LayoutText {#text} at (0,-1) size 83x16
+            text run at (0,-1) width 83: "cols=5 rows=4"
+        LayoutNGBlockFlow {DIV} at (1,789) size 352x72 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,56) size 14x16
+            text run at (1,56) width 14: "A "
+          LayoutText {#text} at (73,56) size 14x16
+            text run at (73,56) width 14: " B"
+      LayoutNGBlockFlow (floating) {DIV} at (352,0) size 352x1046 [border: (1px solid #FF0000)]
+        LayoutNGBlockFlow (anonymous) at (1,1) size 350x14
+          LayoutText {#text} at (0,-1) size 110x16
+            text run at (0,-1) width 110: "style=\"width:60px\""
+        LayoutNGBlockFlow {DIV} at (1,15) size 352x40 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,24) size 14x16
+            text run at (1,24) width 14: "A "
+          LayoutText {#text} at (74,24) size 14x16
+            text run at (74,24) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,55) size 350x14
+          LayoutText {#text} at (0,-1) size 191x16
+            text run at (0,-1) width 191: "style=\"width:60px;padding:20px\""
+        LayoutNGBlockFlow {DIV} at (1,69) size 352x78 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,62) size 14x16
+            text run at (1,62) width 14: "A "
+          LayoutText {#text} at (74,62) size 14x16
+            text run at (74,62) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,147) size 350x14
+          LayoutText {#text} at (0,-1) size 170x16
+            text run at (0,-1) width 170: "style=\"width:60px;padding:0\""
+        LayoutNGBlockFlow {DIV} at (1,161) size 352x38 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,22) size 14x16
+            text run at (1,22) width 14: "A "
+          LayoutText {#text} at (74,22) size 14x16
+            text run at (74,22) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,199) size 350x14
+          LayoutText {#text} at (0,-1) size 113x16
+            text run at (0,-1) width 113: "style=\"height:60px\""
+        LayoutNGBlockFlow {DIV} at (1,213) size 352x64 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,48) size 14x16
+            text run at (1,48) width 14: "A "
+          LayoutText {#text} at (193,48) size 14x16
+            text run at (193,48) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,277) size 350x14
+          LayoutText {#text} at (0,-1) size 181x16
+            text run at (0,-1) width 181: "style=\"width:60px;height:60px\""
+        LayoutNGBlockFlow {DIV} at (1,291) size 352x64 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,48) size 14x16
+            text run at (1,48) width 14: "A "
+          LayoutText {#text} at (74,48) size 14x16
+            text run at (74,48) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,355) size 350x14
+          LayoutText {#text} at (0,-1) size 139x16
+            text run at (0,-1) width 139: "style=\"overflow:hidden\""
+        LayoutNGBlockFlow {DIV} at (1,369) size 352x40 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,24) size 14x16
+            text run at (1,24) width 14: "A "
+          LayoutText {#text} at (193,24) size 14x16
+            text run at (193,24) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,409) size 350x14
+          LayoutText {#text} at (0,-1) size 132x16
+            text run at (0,-1) width 132: "style=\"overflow:scroll\""
+        LayoutNGBlockFlow {DIV} at (1,423) size 352x55 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,39) size 14x16
+            text run at (1,39) width 14: "A "
+          LayoutText {#text} at (193,39) size 14x16
+            text run at (193,39) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,478) size 350x14
+          LayoutText {#text} at (0,-1) size 278x16
+            text run at (0,-1) width 278: "style=\"overflow:hidden;width:60px;height:60px\""
+        LayoutNGBlockFlow {DIV} at (1,492) size 352x64 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,48) size 14x16
+            text run at (1,48) width 14: "A "
+          LayoutText {#text} at (74,48) size 14x16
+            text run at (74,48) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,556) size 350x14
+          LayoutText {#text} at (0,-1) size 271x16
+            text run at (0,-1) width 271: "style=\"overflow:scroll;width:60px;height:60px\""
+        LayoutNGBlockFlow {DIV} at (1,570) size 352x64 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,48) size 14x16
+            text run at (1,48) width 14: "A "
+          LayoutText {#text} at (74,48) size 14x16
+            text run at (74,48) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,634) size 350x14
+          LayoutText {#text} at (0,-1) size 222x16
+            text run at (0,-1) width 222: "cols=5 style=\"width:60px;height:60px\""
+        LayoutNGBlockFlow {DIV} at (1,648) size 352x64 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,48) size 14x16
+            text run at (1,48) width 14: "A "
+          LayoutText {#text} at (74,48) size 14x16
+            text run at (74,48) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,712) size 350x14
+          LayoutText {#text} at (0,-1) size 227x16
+            text run at (0,-1) width 227: "rows=4 style=\"width:60px;height:60px\""
+        LayoutNGBlockFlow {DIV} at (1,726) size 352x64 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,48) size 14x16
+            text run at (1,48) width 14: "A "
+          LayoutText {#text} at (74,48) size 14x16
+            text run at (74,48) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,790) size 350x14
+          LayoutText {#text} at (0,-1) size 268x16
+            text run at (0,-1) width 268: "cols=5 rows=4 style=\"width:60px;height:60px\""
+        LayoutNGBlockFlow {DIV} at (1,804) size 352x64 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,48) size 14x16
+            text run at (1,48) width 14: "A "
+          LayoutText {#text} at (74,48) size 14x16
+            text run at (74,48) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,868) size 350x14
+          LayoutText {#text} at (0,-1) size 65x16
+            text run at (0,-1) width 65: "wrap=\"off\""
+        LayoutNGBlockFlow {DIV} at (1,882) size 352x55 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,39) size 14x16
+            text run at (1,39) width 14: "A "
+          LayoutText {#text} at (193,39) size 14x16
+            text run at (193,39) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,937) size 350x14
+          LayoutText {#text} at (0,-1) size 73x16
+            text run at (0,-1) width 73: "wrap=\"hard\""
+        LayoutNGBlockFlow {DIV} at (1,951) size 352x40 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,24) size 14x16
+            text run at (1,24) width 14: "A "
+          LayoutText {#text} at (193,24) size 14x16
+            text run at (193,24) width 14: " B"
+        LayoutNGBlockFlow (anonymous) at (1,991) size 350x14
+          LayoutText {#text} at (0,-1) size 69x16
+            text run at (0,-1) width 69: "wrap=\"soft\""
+        LayoutNGBlockFlow {DIV} at (1,1005) size 352x40 [border: (1px solid #FF0000)]
+          LayoutText {#text} at (1,24) size 14x16
+            text run at (1,24) width 14: "A "
+          LayoutText {#text} at (193,24) size 14x16
+            text run at (193,24) width 14: " B"
+layer at (23,24) size 179x36 clip at (24,25) size 177x34
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 175x16
+      LayoutText {#text} at (0,0) size 136x16
+        text run at (0,0) width 136: "Lorem ipsum dolor"
+layer at (23,78) size 179x36 clip at (24,79) size 162x34 scrollHeight 82
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 160x80
+      LayoutText {#text} at (0,0) size 160x80
+        text run at (0,0) width 136: "Lorem ipsum dolor"
+        text run at (136,0) width 8: " "
+        text run at (0,16) width 160: "ABCDEFGHIJKLMNOPQRST"
+        text run at (0,32) width 48: "UVWXYZ"
+        text run at (48,32) width 8: " "
+        text run at (0,48) width 160: "abcdefghijklmnopqrst"
+        text run at (0,64) width 16: "uv"
+        text run at (16,64) width 8: " "
+layer at (23,132) size 179x36 clip at (24,133) size 162x34 scrollHeight 82
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 179x36 [color=#545454] [bgcolor=#EBEBE4] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 160x80
+      LayoutText {#text} at (0,0) size 160x80
+        text run at (0,0) width 136: "Lorem ipsum dolor"
+        text run at (136,0) width 8: " "
+        text run at (0,16) width 160: "ABCDEFGHIJKLMNOPQRST"
+        text run at (0,32) width 48: "UVWXYZ"
+        text run at (48,32) width 8: " "
+        text run at (0,48) width 160: "abcdefghijklmnopqrst"
+        text run at (0,64) width 16: "uv"
+        text run at (16,64) width 8: " "
+layer at (23,186) size 197x54 clip at (24,187) size 180x52 scrollHeight 100
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 197x54 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (11,11) size 160x80
+      LayoutText {#text} at (0,0) size 160x80
+        text run at (0,0) width 136: "Lorem ipsum dolor"
+        text run at (136,0) width 8: " "
+        text run at (0,16) width 160: "ABCDEFGHIJKLMNOPQRST"
+        text run at (0,32) width 48: "UVWXYZ"
+        text run at (48,32) width 8: " "
+        text run at (0,48) width 160: "abcdefghijklmnopqrst"
+        text run at (0,64) width 16: "uv"
+        text run at (16,64) width 8: " "
+layer at (23,258) size 177x34 clip at (24,259) size 160x32 scrollHeight 80
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 177x34 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (1,1) size 160x80
+      LayoutText {#text} at (0,0) size 160x80
+        text run at (0,0) width 136: "Lorem ipsum dolor"
+        text run at (136,0) width 8: " "
+        text run at (0,16) width 160: "ABCDEFGHIJKLMNOPQRST"
+        text run at (0,32) width 48: "UVWXYZ"
+        text run at (48,32) width 8: " "
+        text run at (0,48) width 160: "abcdefghijklmnopqrst"
+        text run at (0,64) width 16: "uv"
+        text run at (16,64) width 8: " "
+layer at (33,320) size 179x36 clip at (34,321) size 162x34 scrollHeight 82
+  LayoutTextControl {TEXTAREA} at (24.23,11) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 160x80
+      LayoutText {#text} at (0,0) size 160x80
+        text run at (0,0) width 136: "Lorem ipsum dolor"
+        text run at (136,0) width 8: " "
+        text run at (0,16) width 160: "ABCDEFGHIJKLMNOPQRST"
+        text run at (0,32) width 48: "UVWXYZ"
+        text run at (48,32) width 8: " "
+        text run at (0,48) width 160: "abcdefghijklmnopqrst"
+        text run at (0,64) width 16: "uv"
+        text run at (16,64) width 8: " "
+layer at (23,384) size 179x36 clip at (24,385) size 162x34 scrollHeight 82
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 160x80
+      LayoutText {#text} at (0,0) size 160x80
+        text run at (0,0) width 136: "Lorem ipsum dolor"
+        text run at (136,0) width 8: " "
+        text run at (0,16) width 160: "ABCDEFGHIJKLMNOPQRST"
+        text run at (0,32) width 48: "UVWXYZ"
+        text run at (48,32) width 8: " "
+        text run at (0,48) width 160: "abcdefghijklmnopqrst"
+        text run at (0,64) width 16: "uv"
+        text run at (16,64) width 8: " "
+layer at (23,438) size 43x36 clip at (24,439) size 26x34 scrollHeight 370
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 43x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 24x368
+      LayoutText {#text} at (0,0) size 24x368
+        text run at (0,0) width 24: "Lor"
+        text run at (0,16) width 16: "em"
+        text run at (16,16) width 8: " "
+        text run at (0,32) width 24: "ips"
+        text run at (0,48) width 16: "um"
+        text run at (16,48) width 8: " "
+        text run at (0,64) width 24: "dol"
+        text run at (0,80) width 16: "or"
+        text run at (16,80) width 8: " "
+        text run at (0,96) width 24: "ABC"
+        text run at (0,112) width 24: "DEF"
+        text run at (0,128) width 24: "GHI"
+        text run at (0,144) width 24: "JKL"
+        text run at (0,160) width 24: "MNO"
+        text run at (0,176) width 24: "PQR"
+        text run at (0,192) width 24: "STU"
+        text run at (0,208) width 24: "VWX"
+        text run at (0,224) width 16: "YZ"
+        text run at (16,224) width 8: " "
+        text run at (0,240) width 24: "abc"
+        text run at (0,256) width 24: "def"
+        text run at (0,272) width 24: "ghi"
+        text run at (0,288) width 24: "jkl"
+        text run at (0,304) width 24: "mno"
+        text run at (0,320) width 24: "pqr"
+        text run at (0,336) width 24: "stu"
+        text run at (0,352) width 8: "v"
+        text run at (8,352) width 8: " "
+layer at (23,492) size 179x52 clip at (24,493) size 162x50 scrollHeight 82
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 179x52 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 160x80
+      LayoutText {#text} at (0,0) size 160x80
+        text run at (0,0) width 136: "Lorem ipsum dolor"
+        text run at (136,0) width 8: " "
+        text run at (0,16) width 160: "ABCDEFGHIJKLMNOPQRST"
+        text run at (0,32) width 48: "UVWXYZ"
+        text run at (48,32) width 8: " "
+        text run at (0,48) width 160: "abcdefghijklmnopqrst"
+        text run at (0,64) width 16: "uv"
+        text run at (16,64) width 8: " "
+layer at (23,562) size 99x36 clip at (24,563) size 82x34 scrollHeight 146
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 99x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 80x144
+      LayoutText {#text} at (0,0) size 80x144
+        text run at (0,0) width 40: "Lorem"
+        text run at (40,0) width 8: " "
+        text run at (0,16) width 40: "ipsum"
+        text run at (40,16) width 8: " "
+        text run at (0,32) width 40: "dolor"
+        text run at (40,32) width 8: " "
+        text run at (0,48) width 80: "ABCDEFGHIJ"
+        text run at (0,64) width 80: "KLMNOPQRST"
+        text run at (0,80) width 48: "UVWXYZ"
+        text run at (48,80) width 8: " "
+        text run at (0,96) width 80: "abcdefghij"
+        text run at (0,112) width 80: "klmnopqrst"
+        text run at (0,128) width 16: "uv"
+        text run at (16,128) width 8: " "
+layer at (23,616) size 179x164 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 179x164 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 175x80
+      LayoutText {#text} at (0,0) size 168x80
+        text run at (0,0) width 136: "Lorem ipsum dolor"
+        text run at (136,0) width 8: " "
+        text run at (0,16) width 168: "ABCDEFGHIJKLMNOPQRSTU"
+        text run at (0,32) width 40: "VWXYZ"
+        text run at (40,32) width 8: " "
+        text run at (0,48) width 168: "abcdefghijklmnopqrstu"
+        text run at (0,64) width 8: "v"
+        text run at (8,64) width 8: " "
+layer at (23,798) size 59x68 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 226
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 59x68 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 40x224
+      LayoutText {#text} at (0,0) size 40x224
+        text run at (0,0) width 40: "Lorem"
+        text run at (40,0) width 0: " "
+        text run at (0,16) width 40: "ipsum"
+        text run at (40,16) width 0: " "
+        text run at (0,32) width 40: "dolor"
+        text run at (40,32) width 0: " "
+        text run at (0,48) width 40: "ABCDE"
+        text run at (0,64) width 40: "FGHIJ"
+        text run at (0,80) width 40: "KLMNO"
+        text run at (0,96) width 40: "PQRST"
+        text run at (0,112) width 40: "UVWXY"
+        text run at (0,128) width 8: "Z"
+        text run at (8,128) width 8: " "
+        text run at (0,144) width 40: "abcde"
+        text run at (0,160) width 40: "fghij"
+        text run at (0,176) width 40: "klmno"
+        text run at (0,192) width 40: "pqrst"
+        text run at (0,208) width 16: "uv"
+        text run at (16,208) width 8: " "
+layer at (375,24) size 60x36 clip at (376,25) size 43x34 scrollHeight 226
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 60x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 41x224
+      LayoutText {#text} at (0,0) size 41x224
+        text run at (0,0) width 40: "Lorem"
+        text run at (40,0) width 1: " "
+        text run at (0,16) width 40: "ipsum"
+        text run at (40,16) width 1: " "
+        text run at (0,32) width 40: "dolor"
+        text run at (40,32) width 1: " "
+        text run at (0,48) width 40: "ABCDE"
+        text run at (0,64) width 40: "FGHIJ"
+        text run at (0,80) width 40: "KLMNO"
+        text run at (0,96) width 40: "PQRST"
+        text run at (0,112) width 40: "UVWXY"
+        text run at (0,128) width 8: "Z"
+        text run at (8,128) width 8: " "
+        text run at (0,144) width 40: "abcde"
+        text run at (0,160) width 40: "fghij"
+        text run at (0,176) width 40: "klmno"
+        text run at (0,192) width 40: "pqrst"
+        text run at (0,208) width 16: "uv"
+        text run at (16,208) width 8: " "
+layer at (375,78) size 60x74 clip at (376,79) size 43x72 scrollHeight 1128
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 60x74 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (21,21) size 3x1088
+      LayoutText {#text} at (0,0) size 8x1088
+        text run at (0,0) width 8: "L"
+        text run at (0,16) width 8: "o"
+        text run at (0,32) width 8: "r"
+        text run at (0,48) width 8: "e"
+        text run at (0,64) width 8: "m"
+        text run at (0,80) width 3: " "
+        text run at (0,96) width 8: "i"
+        text run at (0,112) width 8: "p"
+        text run at (0,128) width 8: "s"
+        text run at (0,144) width 8: "u"
+        text run at (0,160) width 8: "m"
+        text run at (0,176) width 3: " "
+        text run at (0,192) width 8: "d"
+        text run at (0,208) width 8: "o"
+        text run at (0,224) width 8: "l"
+        text run at (0,240) width 8: "o"
+        text run at (0,256) width 8: "r"
+        text run at (0,272) width 3: " "
+        text run at (0,288) width 8: "A"
+        text run at (0,304) width 8: "B"
+        text run at (0,320) width 8: "C"
+        text run at (0,336) width 8: "D"
+        text run at (0,352) width 8: "E"
+        text run at (0,368) width 8: "F"
+        text run at (0,384) width 8: "G"
+        text run at (0,400) width 8: "H"
+        text run at (0,416) width 8: "I"
+        text run at (0,432) width 8: "J"
+        text run at (0,448) width 8: "K"
+        text run at (0,464) width 8: "L"
+        text run at (0,480) width 8: "M"
+        text run at (0,496) width 8: "N"
+        text run at (0,512) width 8: "O"
+        text run at (0,528) width 8: "P"
+        text run at (0,544) width 8: "Q"
+        text run at (0,560) width 8: "R"
+        text run at (0,576) width 8: "S"
+        text run at (0,592) width 8: "T"
+        text run at (0,608) width 8: "U"
+        text run at (0,624) width 8: "V"
+        text run at (0,640) width 8: "W"
+        text run at (0,656) width 8: "X"
+        text run at (0,672) width 8: "Y"
+        text run at (0,688) width 8: "Z"
+        text run at (0,704) width 3: " "
+        text run at (0,720) width 8: "a"
+        text run at (0,736) width 8: "b"
+        text run at (0,752) width 8: "c"
+        text run at (0,768) width 8: "d"
+        text run at (0,784) width 8: "e"
+        text run at (0,800) width 8: "f"
+        text run at (0,816) width 8: "g"
+        text run at (0,832) width 8: "h"
+        text run at (0,848) width 8: "i"
+        text run at (0,864) width 8: "j"
+        text run at (0,880) width 8: "k"
+        text run at (0,896) width 8: "l"
+        text run at (0,912) width 8: "m"
+        text run at (0,928) width 8: "n"
+        text run at (0,944) width 8: "o"
+        text run at (0,960) width 8: "p"
+        text run at (0,976) width 8: "q"
+        text run at (0,992) width 8: "r"
+        text run at (0,1008) width 8: "s"
+        text run at (0,1024) width 8: "t"
+        text run at (0,1040) width 8: "u"
+        text run at (0,1056) width 8: "v"
+        text run at (0,1072) width 3: " "
+layer at (375,170) size 60x34 clip at (376,171) size 43x32 scrollHeight 224
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 60x34 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (1,1) size 43x224
+      LayoutText {#text} at (0,0) size 43x224
+        text run at (0,0) width 40: "Lorem"
+        text run at (40,0) width 3: " "
+        text run at (0,16) width 40: "ipsum"
+        text run at (40,16) width 3: " "
+        text run at (0,32) width 40: "dolor"
+        text run at (40,32) width 3: " "
+        text run at (0,48) width 40: "ABCDE"
+        text run at (0,64) width 40: "FGHIJ"
+        text run at (0,80) width 40: "KLMNO"
+        text run at (0,96) width 40: "PQRST"
+        text run at (0,112) width 40: "UVWXY"
+        text run at (0,128) width 8: "Z"
+        text run at (8,128) width 8: " "
+        text run at (0,144) width 40: "abcde"
+        text run at (0,160) width 40: "fghij"
+        text run at (0,176) width 40: "klmno"
+        text run at (0,192) width 40: "pqrst"
+        text run at (0,208) width 16: "uv"
+        text run at (16,208) width 8: " "
+layer at (375,222) size 179x60 clip at (376,223) size 162x58 scrollHeight 82
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 179x60 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 160x80
+      LayoutText {#text} at (0,0) size 160x80
+        text run at (0,0) width 136: "Lorem ipsum dolor"
+        text run at (136,0) width 8: " "
+        text run at (0,16) width 160: "ABCDEFGHIJKLMNOPQRST"
+        text run at (0,32) width 48: "UVWXYZ"
+        text run at (48,32) width 8: " "
+        text run at (0,48) width 160: "abcdefghijklmnopqrst"
+        text run at (0,64) width 16: "uv"
+        text run at (16,64) width 8: " "
+layer at (375,300) size 60x60 clip at (376,301) size 43x58 scrollHeight 226
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 60x60 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 41x224
+      LayoutText {#text} at (0,0) size 41x224
+        text run at (0,0) width 40: "Lorem"
+        text run at (40,0) width 1: " "
+        text run at (0,16) width 40: "ipsum"
+        text run at (40,16) width 1: " "
+        text run at (0,32) width 40: "dolor"
+        text run at (40,32) width 1: " "
+        text run at (0,48) width 40: "ABCDE"
+        text run at (0,64) width 40: "FGHIJ"
+        text run at (0,80) width 40: "KLMNO"
+        text run at (0,96) width 40: "PQRST"
+        text run at (0,112) width 40: "UVWXY"
+        text run at (0,128) width 8: "Z"
+        text run at (8,128) width 8: " "
+        text run at (0,144) width 40: "abcde"
+        text run at (0,160) width 40: "fghij"
+        text run at (0,176) width 40: "klmno"
+        text run at (0,192) width 40: "pqrst"
+        text run at (0,208) width 16: "uv"
+        text run at (16,208) width 8: " "
+layer at (375,378) size 179x36 clip at (376,379) size 177x34 scrollHeight 82
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 175x80
+      LayoutText {#text} at (0,0) size 168x80
+        text run at (0,0) width 136: "Lorem ipsum dolor"
+        text run at (136,0) width 8: " "
+        text run at (0,16) width 168: "ABCDEFGHIJKLMNOPQRSTU"
+        text run at (0,32) width 40: "VWXYZ"
+        text run at (40,32) width 8: " "
+        text run at (0,48) width 168: "abcdefghijklmnopqrstu"
+        text run at (0,64) width 8: "v"
+        text run at (8,64) width 8: " "
+layer at (375,432) size 179x51 clip at (376,433) size 162x34 scrollHeight 82
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 179x51 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 160x80
+      LayoutText {#text} at (0,0) size 160x80
+        text run at (0,0) width 136: "Lorem ipsum dolor"
+        text run at (136,0) width 8: " "
+        text run at (0,16) width 160: "ABCDEFGHIJKLMNOPQRST"
+        text run at (0,32) width 48: "UVWXYZ"
+        text run at (48,32) width 8: " "
+        text run at (0,48) width 160: "abcdefghijklmnopqrst"
+        text run at (0,64) width 16: "uv"
+        text run at (16,64) width 8: " "
+layer at (375,501) size 60x60 clip at (376,502) size 58x58 scrollHeight 178
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 60x60 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 56x176
+      LayoutText {#text} at (0,0) size 56x176
+        text run at (0,0) width 40: "Lorem"
+        text run at (40,0) width 8: " "
+        text run at (0,16) width 40: "ipsum"
+        text run at (40,16) width 8: " "
+        text run at (0,32) width 40: "dolor"
+        text run at (40,32) width 8: " "
+        text run at (0,48) width 56: "ABCDEFG"
+        text run at (0,64) width 56: "HIJKLMN"
+        text run at (0,80) width 56: "OPQRSTU"
+        text run at (0,96) width 40: "VWXYZ"
+        text run at (40,96) width 8: " "
+        text run at (0,112) width 56: "abcdefg"
+        text run at (0,128) width 56: "hijklmn"
+        text run at (0,144) width 56: "opqrstu"
+        text run at (0,160) width 8: "v"
+        text run at (8,160) width 8: " "
+layer at (375,579) size 60x60 backgroundClip at (375,579) size 60x21 clip at (376,580) size 43x20 scrollHeight 226
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 60x60 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 41x224
+      LayoutText {#text} at (0,0) size 41x224
+        text run at (0,0) width 40: "Lorem"
+        text run at (40,0) width 1: " "
+        text run at (0,16) width 40: "ipsum"
+        text run at (40,16) width 1: " "
+        text run at (0,32) width 40: "dolor"
+        text run at (40,32) width 1: " "
+        text run at (0,48) width 40: "ABCDE"
+        text run at (0,64) width 40: "FGHIJ"
+        text run at (0,80) width 40: "KLMNO"
+        text run at (0,96) width 40: "PQRST"
+        text run at (0,112) width 40: "UVWXY"
+        text run at (0,128) width 8: "Z"
+        text run at (8,128) width 8: " "
+        text run at (0,144) width 40: "abcde"
+        text run at (0,160) width 40: "fghij"
+        text run at (0,176) width 40: "klmno"
+        text run at (0,192) width 40: "pqrst"
+        text run at (0,208) width 16: "uv"
+        text run at (16,208) width 8: " "
+layer at (375,657) size 60x60 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 226
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 60x60 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 41x224
+      LayoutText {#text} at (0,0) size 41x224
+        text run at (0,0) width 40: "Lorem"
+        text run at (40,0) width 1: " "
+        text run at (0,16) width 40: "ipsum"
+        text run at (40,16) width 1: " "
+        text run at (0,32) width 40: "dolor"
+        text run at (40,32) width 1: " "
+        text run at (0,48) width 40: "ABCDE"
+        text run at (0,64) width 40: "FGHIJ"
+        text run at (0,80) width 40: "KLMNO"
+        text run at (0,96) width 40: "PQRST"
+        text run at (0,112) width 40: "UVWXY"
+        text run at (0,128) width 8: "Z"
+        text run at (8,128) width 8: " "
+        text run at (0,144) width 40: "abcde"
+        text run at (0,160) width 40: "fghij"
+        text run at (0,176) width 40: "klmno"
+        text run at (0,192) width 40: "pqrst"
+        text run at (0,208) width 16: "uv"
+        text run at (16,208) width 8: " "
+layer at (375,735) size 60x60 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 226
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 60x60 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 41x224
+      LayoutText {#text} at (0,0) size 41x224
+        text run at (0,0) width 40: "Lorem"
+        text run at (40,0) width 1: " "
+        text run at (0,16) width 40: "ipsum"
+        text run at (40,16) width 1: " "
+        text run at (0,32) width 40: "dolor"
+        text run at (40,32) width 1: " "
+        text run at (0,48) width 40: "ABCDE"
+        text run at (0,64) width 40: "FGHIJ"
+        text run at (0,80) width 40: "KLMNO"
+        text run at (0,96) width 40: "PQRST"
+        text run at (0,112) width 40: "UVWXY"
+        text run at (0,128) width 8: "Z"
+        text run at (8,128) width 8: " "
+        text run at (0,144) width 40: "abcde"
+        text run at (0,160) width 40: "fghij"
+        text run at (0,176) width 40: "klmno"
+        text run at (0,192) width 40: "pqrst"
+        text run at (0,208) width 16: "uv"
+        text run at (16,208) width 8: " "
+layer at (375,813) size 60x60 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 226
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 60x60 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 41x224
+      LayoutText {#text} at (0,0) size 41x224
+        text run at (0,0) width 40: "Lorem"
+        text run at (40,0) width 1: " "
+        text run at (0,16) width 40: "ipsum"
+        text run at (40,16) width 1: " "
+        text run at (0,32) width 40: "dolor"
+        text run at (40,32) width 1: " "
+        text run at (0,48) width 40: "ABCDE"
+        text run at (0,64) width 40: "FGHIJ"
+        text run at (0,80) width 40: "KLMNO"
+        text run at (0,96) width 40: "PQRST"
+        text run at (0,112) width 40: "UVWXY"
+        text run at (0,128) width 8: "Z"
+        text run at (8,128) width 8: " "
+        text run at (0,144) width 40: "abcde"
+        text run at (0,160) width 40: "fghij"
+        text run at (0,176) width 40: "klmno"
+        text run at (0,192) width 40: "pqrst"
+        text run at (0,208) width 16: "uv"
+        text run at (16,208) width 8: " "
+layer at (375,891) size 179x51 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollWidth 290 scrollHeight 258
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 179x51 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 160x256
+      LayoutText {#text} at (0,0) size 288x240
+        text run at (0,0) width 8: " "
+        text run at (8,0) width 0: " "
+        text run at (0,16) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,16) width 0: " "
+        text run at (0,32) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,32) width 0: " "
+        text run at (0,48) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,48) width 0: " "
+        text run at (0,64) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,64) width 0: " "
+        text run at (0,80) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,80) width 0: " "
+        text run at (0,96) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,96) width 0: " "
+        text run at (0,112) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,112) width 0: " "
+        text run at (0,128) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,128) width 0: " "
+        text run at (0,144) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,144) width 0: " "
+        text run at (0,160) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,160) width 0: " "
+        text run at (0,176) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,176) width 0: " "
+        text run at (0,192) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,192) width 0: " "
+        text run at (0,208) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,208) width 0: " "
+        text run at (0,224) width 288: "This is a text area with wrap=\"soft\""
+        text run at (288,224) width 0: " "
+      LayoutBR {BR} at (0,240) size 0x16
+layer at (375,960) size 179x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 482
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 160x480
+      LayoutText {#text} at (0,0) size 160x464
+        text run at (0,0) width 8: " "
+        text run at (8,0) width 0: " "
+        text run at (0,16) width 152: "This is a text area"
+        text run at (152,16) width 8: " "
+        text run at (0,32) width 128: "with wrap=\"soft\""
+        text run at (128,32) width 0: " "
+        text run at (0,48) width 152: "This is a text area"
+        text run at (152,48) width 8: " "
+        text run at (0,64) width 128: "with wrap=\"soft\""
+        text run at (128,64) width 0: " "
+        text run at (0,80) width 152: "This is a text area"
+        text run at (152,80) width 8: " "
+        text run at (0,96) width 128: "with wrap=\"soft\""
+        text run at (128,96) width 0: " "
+        text run at (0,112) width 152: "This is a text area"
+        text run at (152,112) width 8: " "
+        text run at (0,128) width 128: "with wrap=\"soft\""
+        text run at (128,128) width 0: " "
+        text run at (0,144) width 152: "This is a text area"
+        text run at (152,144) width 8: " "
+        text run at (0,160) width 128: "with wrap=\"soft\""
+        text run at (128,160) width 0: " "
+        text run at (0,176) width 152: "This is a text area"
+        text run at (152,176) width 8: " "
+        text run at (0,192) width 128: "with wrap=\"soft\""
+        text run at (128,192) width 0: " "
+        text run at (0,208) width 152: "This is a text area"
+        text run at (152,208) width 8: " "
+        text run at (0,224) width 128: "with wrap=\"soft\""
+        text run at (128,224) width 0: " "
+        text run at (0,240) width 152: "This is a text area"
+        text run at (152,240) width 8: " "
+        text run at (0,256) width 128: "with wrap=\"soft\""
+        text run at (128,256) width 0: " "
+        text run at (0,272) width 152: "This is a text area"
+        text run at (152,272) width 8: " "
+        text run at (0,288) width 128: "with wrap=\"soft\""
+        text run at (128,288) width 0: " "
+        text run at (0,304) width 152: "This is a text area"
+        text run at (152,304) width 8: " "
+        text run at (0,320) width 128: "with wrap=\"soft\""
+        text run at (128,320) width 0: " "
+        text run at (0,336) width 152: "This is a text area"
+        text run at (152,336) width 8: " "
+        text run at (0,352) width 128: "with wrap=\"soft\""
+        text run at (128,352) width 0: " "
+        text run at (0,368) width 152: "This is a text area"
+        text run at (152,368) width 8: " "
+        text run at (0,384) width 128: "with wrap=\"soft\""
+        text run at (128,384) width 0: " "
+        text run at (0,400) width 152: "This is a text area"
+        text run at (152,400) width 8: " "
+        text run at (0,416) width 128: "with wrap=\"soft\""
+        text run at (128,416) width 0: " "
+        text run at (0,432) width 152: "This is a text area"
+        text run at (152,432) width 8: " "
+        text run at (0,448) width 128: "with wrap=\"soft\""
+        text run at (128,448) width 0: " "
+      LayoutBR {BR} at (0,464) size 0x16
+layer at (375,1014) size 179x36 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 482
+  LayoutTextControl {TEXTAREA} at (14.23,1) size 179x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {DIV} at (3,3) size 160x480
+      LayoutText {#text} at (0,0) size 160x464
+        text run at (0,0) width 8: " "
+        text run at (8,0) width 0: " "
+        text run at (0,16) width 152: "This is a text area"
+        text run at (152,16) width 8: " "
+        text run at (0,32) width 128: "with wrap=\"soft\""
+        text run at (128,32) width 0: " "
+        text run at (0,48) width 152: "This is a text area"
+        text run at (152,48) width 8: " "
+        text run at (0,64) width 128: "with wrap=\"soft\""
+        text run at (128,64) width 0: " "
+        text run at (0,80) width 152: "This is a text area"
+        text run at (152,80) width 8: " "
+        text run at (0,96) width 128: "with wrap=\"soft\""
+        text run at (128,96) width 0: " "
+        text run at (0,112) width 152: "This is a text area"
+        text run at (152,112) width 8: " "
+        text run at (0,128) width 128: "with wrap=\"soft\""
+        text run at (128,128) width 0: " "
+        text run at (0,144) width 152: "This is a text area"
+        text run at (152,144) width 8: " "
+        text run at (0,160) width 128: "with wrap=\"soft\""
+        text run at (128,160) width 0: " "
+        text run at (0,176) width 152: "This is a text area"
+        text run at (152,176) width 8: " "
+        text run at (0,192) width 128: "with wrap=\"soft\""
+        text run at (128,192) width 0: " "
+        text run at (0,208) width 152: "This is a text area"
+        text run at (152,208) width 8: " "
+        text run at (0,224) width 128: "with wrap=\"soft\""
+        text run at (128,224) width 0: " "
+        text run at (0,240) width 152: "This is a text area"
+        text run at (152,240) width 8: " "
+        text run at (0,256) width 128: "with wrap=\"soft\""
+        text run at (128,256) width 0: " "
+        text run at (0,272) width 152: "This is a text area"
+        text run at (152,272) width 8: " "
+        text run at (0,288) width 128: "with wrap=\"soft\""
+        text run at (128,288) width 0: " "
+        text run at (0,304) width 152: "This is a text area"
+        text run at (152,304) width 8: " "
+        text run at (0,320) width 128: "with wrap=\"soft\""
+        text run at (128,320) width 0: " "
+        text run at (0,336) width 152: "This is a text area"
+        text run at (152,336) width 8: " "
+        text run at (0,352) width 128: "with wrap=\"soft\""
+        text run at (128,352) width 0: " "
+        text run at (0,368) width 152: "This is a text area"
+        text run at (152,368) width 8: " "
+        text run at (0,384) width 128: "with wrap=\"soft\""
+        text run at (128,384) width 0: " "
+        text run at (0,400) width 152: "This is a text area"
+        text run at (152,400) width 8: " "
+        text run at (0,416) width 128: "with wrap=\"soft\""
+        text run at (128,416) width 0: " "
+        text run at (0,432) width 152: "This is a text area"
+        text run at (152,432) width 8: " "
+        text run at (0,448) width 128: "with wrap=\"soft\""
+        text run at (128,448) width 0: " "
+      LayoutBR {BR} at (0,464) size 0x16
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/time/time-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/time/time-appearance-basic-expected.png
new file mode 100644
index 0000000..cc924f950
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/time/time-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/time/time-appearance-basic-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/time/time-appearance-basic-expected.txt
new file mode 100644
index 0000000..9683fcf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/time/time-appearance-basic-expected.txt
@@ -0,0 +1,18 @@
+step=none  
+step=1  
+step=0.0001  
+step=60  
+step=3600  
+step=86400  
+step mismatched 
+RTL 
+Disabled, step=3600  
+Readonly, step=3600  
+text-align: 
+text-transform: 
+background, color: 
+font-size, font-weight: 
+font-size with fixed input width: 
+Fixed input height: 
+-webkit-appearance:none: 
+padding: 
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/time/time-appearance-pseudo-elements-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/time/time-appearance-pseudo-elements-expected.png
new file mode 100644
index 0000000..b28159f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/time/time-appearance-pseudo-elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/validation-bubble-appearance-rtl-ui-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/validation-bubble-appearance-rtl-ui-expected.png
new file mode 100644
index 0000000..e52e63c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/validation-bubble-appearance-rtl-ui-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/week/week-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/week/week-appearance-basic-expected.png
new file mode 100644
index 0000000..69f5d5d9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/week/week-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/week/week-appearance-pseudo-elements-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/week/week-appearance-pseudo-elements-expected.png
new file mode 100644
index 0000000..ec646d5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/week/week-appearance-pseudo-elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/layers/opacity-transforms-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/layers/opacity-transforms-expected.png
new file mode 100644
index 0000000..2391e2ba
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/layers/opacity-transforms-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/layers/opacity-transforms-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/layers/opacity-transforms-expected.txt
new file mode 100644
index 0000000..cc64e9b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/layers/opacity-transforms-expected.txt
@@ -0,0 +1,20 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x88
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x88
+    LayoutNGBlockFlow {BODY} at (8,16) size 784x56
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutInline {A} at (0,0) size 305x19 [color=#0000EE]
+          LayoutText {#text} at (0,0) size 305x19
+            text run at (0,0) width 305: "https://bugs.webkit.org/show_bug.cgi?id=22026"
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (0,0) size 650x19
+          text run at (0,0) width 650: "Test that elements with transform and opacity on a parent are not clipped. You should see no red below."
+layer at (150,200) size 100x100
+  LayoutNGBlockFlow (positioned) {DIV} at (150,200) size 100x100 [bgcolor=#FF0000]
+layer at (100,150) size 100x100 transparent
+  LayoutNGBlockFlow (positioned) {DIV} at (100,150) size 100x100
+layer at (100,150) size 10x10
+  LayoutNGBlockFlow {DIV} at (0,0) size 10x10
+layer at (150,200) size 100x100
+  LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 100x100 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/lists/ol-display-types-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/lists/ol-display-types-expected.txt
new file mode 100644
index 0000000..4fee44e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/lists/ol-display-types-expected.txt
@@ -0,0 +1,102 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x420
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x420
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x396
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 743x39
+          text run at (0,0) width 743: "Test of various CSS display types for list elements. All visible elements that have a display-type of list-item are given a"
+          text run at (0,20) width 310: "number. This is generally going to be LI element."
+      LayoutNGBlockFlow {OL} at (0,56) size 784x340
+        LayoutNGListItem {LI} at (40,0) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-16,0) size 16x20
+            LayoutText (anonymous) at (0,0) size 16x19
+              text run at (0,0) width 16: "3. "
+          LayoutText {#text} at (0,0) size 76x19
+            text run at (0,0) width 76: "Should be 3"
+        LayoutNGListItem {LI} at (40,20) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-16,0) size 16x20
+            LayoutText (anonymous) at (0,0) size 16x19
+              text run at (0,0) width 16: "4. "
+          LayoutText {#text} at (0,0) size 76x19
+            text run at (0,0) width 76: "Should be 4"
+        LayoutNGBlockFlow {LI} at (40,40) size 744x20
+          LayoutText {#text} at (0,0) size 166x19
+            text run at (0,0) width 166: "Should not have a number"
+        LayoutNGListItem {LI} at (40,60) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-16,0) size 16x20
+            LayoutText (anonymous) at (0,0) size 16x19
+              text run at (0,0) width 16: "5. "
+          LayoutText {#text} at (0,0) size 76x19
+            text run at (0,0) width 76: "Should be 5"
+        LayoutNGBlockFlow (anonymous) at (40,80) size 744x20
+          LayoutInline {LI} at (0,0) size 166x19
+            LayoutText {#text} at (0,0) size 166x19
+              text run at (0,0) width 166: "Should not have a number"
+          LayoutText {#text} at (0,0) size 0x0
+        LayoutNGListItem {LI} at (40,100) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-16,0) size 16x20
+            LayoutText (anonymous) at (0,0) size 16x19
+              text run at (0,0) width 16: "6. "
+          LayoutText {#text} at (0,0) size 76x19
+            text run at (0,0) width 76: "Should be 6"
+        LayoutNGBlockFlow {DIV} at (40,120) size 744x20
+          LayoutText {#text} at (0,0) size 166x19
+            text run at (0,0) width 166: "Should not have a number"
+        LayoutNGListItem {DIV} at (40,140) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-16,0) size 16x20
+            LayoutText (anonymous) at (0,0) size 16x19
+              text run at (0,0) width 16: "7. "
+          LayoutText {#text} at (0,0) size 76x19
+            text run at (0,0) width 76: "Should be 7"
+        LayoutNGListItem {LI} at (40,160) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-16,0) size 16x20
+            LayoutText (anonymous) at (0,0) size 16x19
+              text run at (0,0) width 16: "8. "
+          LayoutText {#text} at (0,0) size 76x19
+            text run at (0,0) width 76: "Should be 8"
+        LayoutNGListItem {LI} at (40,180) size 744x20
+          LayoutText {#text} at (0,0) size 166x19
+            text run at (0,0) width 166: "Should not have a number"
+        LayoutNGListItem {LI} at (40,200) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-24,0) size 24x20
+            LayoutText (anonymous) at (0,0) size 24x19
+              text run at (0,0) width 24: "10. "
+          LayoutText {#text} at (0,0) size 84x19
+            text run at (0,0) width 84: "Should be 10"
+        LayoutNGListItem {LI} at (40,220) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-18,0) size 10x20
+            LayoutText (anonymous) at (0,0) size 10x19
+              text run at (0,0) width 10: "\x{2022} "
+          LayoutText {#text} at (0,0) size 119x19
+            text run at (0,0) width 119: "Should have a disc"
+        LayoutNGListItem {LI} at (40,240) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-24,0) size 24x20
+            LayoutText (anonymous) at (0,0) size 24x19
+              text run at (0,0) width 24: "12. "
+          LayoutText {#text} at (0,0) size 84x19
+            text run at (0,0) width 84: "Should be 12"
+        LayoutNGListItem {LI} at (40,260) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-18,0) size 14x20
+            LayoutText (anonymous) at (0,0) size 14x19
+              text run at (0,0) width 14: "\x{25A0} "
+          LayoutText {#text} at (0,0) size 135x19
+            text run at (0,0) width 135: "Should have a square"
+        LayoutNGListItem {LI} at (40,280) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-24,0) size 24x20
+            LayoutText (anonymous) at (0,0) size 24x19
+              text run at (0,0) width 24: "14. "
+          LayoutText {#text} at (0,0) size 84x19
+            text run at (0,0) width 84: "Should be 14"
+        LayoutNGListItem {LI} at (40,300) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-18,0) size 10x20
+            LayoutText (anonymous) at (0,0) size 10x19
+              text run at (0,0) width 10: "\x{25E6} "
+          LayoutText {#text} at (0,0) size 128x19
+            text run at (0,0) width 128: "Should have a circle"
+        LayoutNGListItem {LI} at (40,320) size 744x20
+          LayoutNGBlockFlow (anonymous) at (-24,0) size 24x20
+            LayoutText (anonymous) at (0,0) size 24x19
+              text run at (0,0) width 24: "16. "
+          LayoutText {#text} at (0,0) size 84x19
+            text run at (0,0) width 84: "Should be 16"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/lists/scrolled-marker-paint-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/lists/scrolled-marker-paint-expected.txt
new file mode 100644
index 0000000..1c77ae6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/lists/scrolled-marker-paint-expected.txt
@@ -0,0 +1,24 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x76
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x76
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x60
+      LayoutNGBlockFlow (anonymous) at (0,0) size 784x40
+        LayoutBR {BR} at (0,0) size 0x0
+        LayoutBR {BR} at (0,20) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,40) size 784x20
+        LayoutText {#text} at (0,0) size 131x19
+          text run at (0,0) width 131: "This is a testcase for "
+        LayoutInline {A} at (0,0) size 477x19 [color=#0000EE]
+          LayoutText {#text} at (131,0) size 477x19
+            text run at (131,0) width 477: "REGRESSION: (r13028) Scrolling causes incomplete drawing of ul bullets"
+        LayoutText {#text} at (608,0) size 4x19
+          text run at (608,0) width 4: "."
+layer at (8,-4) size 398x20 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutNGBlockFlow (positioned) {UL} at (8,-4) size 397.81x20
+    LayoutNGListItem {LI} at (40,0) size 357.81x20
+      LayoutNGBlockFlow (anonymous) at (-18,0) size 10x20
+        LayoutText (anonymous) at (0,0) size 10x19
+          text run at (0,0) width 10: "\x{2022} "
+      LayoutText {#text} at (0,0) size 358x19
+        text run at (0,0) width 358: "This is a list item. You should see a list marker to the left."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/basic/002-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/basic/002-expected.txt
new file mode 100644
index 0000000..183952b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/basic/002-expected.txt
@@ -0,0 +1,25 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x360
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x360
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x336
+      LayoutNGBlockFlow {P} at (0,0) size 100x160
+        LayoutText {#text} at (0,0) size 100x159
+          text run at (0,0) width 100: "This paragraph"
+          text run at (0,20) width 52: "contains"
+          text run at (0,40) width 100: "justified text."
+          text run at (0,60) width 100: "Within the"
+          text run at (0,80) width 72: "constrained"
+          text run at (0,100) width 100: "width, this text"
+          text run at (0,120) width 100: "should be"
+          text run at (0,140) width 54: "justified."
+      LayoutNGBlockFlow {P} at (0,176) size 100x160
+        LayoutText {#text} at (0,0) size 100x159
+          text run at (0,0) width 100: "This paragraph"
+          text run at (0,20) width 100: "also contains"
+          text run at (0,40) width 100: "justified text."
+          text run at (0,60) width 100: "Within the"
+          text run at (0,80) width 72: "constrained"
+          text run at (0,100) width 100: "width, this text"
+          text run at (0,120) width 100: "should be"
+          text run at (0,140) width 54: "justified."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/basic/009-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/basic/009-expected.txt
new file mode 100644
index 0000000..c51c07f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/basic/009-expected.txt
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x44
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x44
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x28
+      LayoutInline {SPAN} at (0,0) size 331x27
+        LayoutText {#text} at (0,0) size 177x27
+          text run at (0,0) width 177: "This is some text. "
+        LayoutInline {TT} at (0,0) size 154x27
+          LayoutText {#text} at (177,1) size 154x27
+            text run at (177,1) width 154: "As is this."
+      LayoutText {#text} at (331,0) size 343x27
+        text run at (331,0) width 343: " All of this text should be 24px tall."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/bidi-img-alt-text-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/bidi-img-alt-text-expected.txt
new file mode 100644
index 0000000..b5e5990e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/bidi-img-alt-text-expected.txt
@@ -0,0 +1,121 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x488
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x488
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x464
+      LayoutNGBlockFlow (anonymous) at (0,0) size 784x428
+        LayoutText {#text} at (302,87) size 4x19
+          text run at (302,87) width 4: " "
+        LayoutText {#text} at (0,0) size 0x0
+        LayoutText {#text} at (302,194) size 4x19
+          text run at (302,194) width 4: " "
+        LayoutText {#text} at (0,0) size 0x0
+        LayoutText {#text} at (302,301) size 4x19
+          text run at (302,301) width 4: " "
+        LayoutText {#text} at (0,0) size 0x0
+        LayoutText {#text} at (302,408) size 4x19
+          text run at (302,408) width 4: " "
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {P} at (0,444) size 784x20
+        LayoutText {#text} at (0,0) size 354x19
+          text run at (0,0) width 354: "Tests that image alt text takes directionality into account."
+layer at (8,8) size 302x102 clip at (9,9) size 300x100 scrollHeight 130
+  LayoutNGBlockFlow (relative positioned) {SECTION} at (0,0) size 302x102 [border: (1px solid #FF0000)]
+    LayoutNGBlockFlow {H2} at (1,20.91) size 300x27
+      LayoutText {#text} at (0,0) size 165x26
+        text run at (0,0) width 165: "ltr image, rtl alt"
+layer at (9,59) size 280x80 backgroundClip at (9,9) size 300x100 clip at (9,9) size 300x100
+  LayoutNGBlockFlow (positioned) {IMG} at (1,51) size 280x80
+    LayoutInline {SPAN} at (0,0) size 8x19
+      LayoutImage (floating) {IMG} at (0,0) size 16x16
+      LayoutInline {SPAN} at (0,0) size 8x19
+        LayoutText {#text} at (16,0) size 8x19
+          text run at (16,0) width 8: "\x{6CC}\x{627}"
+layer at (314,8) size 302x102 clip at (315,9) size 300x100 scrollHeight 130
+  LayoutNGBlockFlow (relative positioned) {SECTION} at (306,0) size 302x102 [border: (1px solid #FF0000)]
+    LayoutNGBlockFlow {H2} at (1,20.91) size 300x27
+      LayoutText {#text} at (0,0) size 165x26
+        text run at (0,0) width 165: "rtl image, rtl alt"
+layer at (315,59) size 280x80 backgroundClip at (315,9) size 300x100 clip at (315,9) size 300x100
+  LayoutNGBlockFlow (positioned) {IMG} at (1,51) size 280x80
+    LayoutInline {SPAN} at (0,0) size 8x19
+      LayoutImage (floating) {IMG} at (264,0) size 16x16
+      LayoutInline {SPAN} at (0,0) size 8x19
+        LayoutText {#text} at (256,0) size 8x19
+          text run at (256,0) width 8: "\x{6CC}\x{627}"
+layer at (8,115) size 302x102 clip at (9,116) size 300x100 scrollHeight 130
+  LayoutNGBlockFlow (relative positioned) {SECTION} at (0,107) size 302x102 [border: (1px solid #FF0000)]
+    LayoutNGBlockFlow {H2} at (1,20.91) size 300x27
+      LayoutText {#text} at (0,0) size 165x26
+        text run at (0,0) width 165: "ltr image, ltr alt"
+layer at (9,166) size 280x80 backgroundClip at (9,116) size 300x100 clip at (9,116) size 300x100
+  LayoutNGBlockFlow (positioned) {IMG} at (1,51) size 280x80
+    LayoutInline {SPAN} at (0,0) size 15x19
+      LayoutImage (floating) {IMG} at (0,0) size 16x16
+      LayoutInline {SPAN} at (0,0) size 15x19
+        LayoutText {#text} at (16,0) size 15x19
+          text run at (16,0) width 15: "alt"
+layer at (314,115) size 302x102 clip at (315,116) size 300x100 scrollHeight 130
+  LayoutNGBlockFlow (relative positioned) {SECTION} at (306,107) size 302x102 [border: (1px solid #FF0000)]
+    LayoutNGBlockFlow {H2} at (1,20.91) size 300x27
+      LayoutText {#text} at (0,0) size 165x26
+        text run at (0,0) width 165: "rtl image, ltr alt"
+layer at (315,166) size 280x80 backgroundClip at (315,116) size 300x100 clip at (315,116) size 300x100
+  LayoutNGBlockFlow (positioned) {IMG} at (1,51) size 280x80
+    LayoutInline {SPAN} at (0,0) size 15x19
+      LayoutImage (floating) {IMG} at (264,0) size 16x16
+      LayoutInline {SPAN} at (0,0) size 15x19
+        LayoutText {#text} at (249,0) size 15x19
+          text run at (249,0) width 15: "alt"
+layer at (8,222) size 302x102 clip at (9,223) size 300x100 scrollHeight 130
+  LayoutNGBlockFlow (relative positioned) {SECTION} at (0,214) size 302x102 [border: (1px solid #FF0000)]
+    LayoutNGBlockFlow {H2} at (1,20.91) size 300x27
+      LayoutText {#text} at (0,0) size 192x26
+        text run at (0,0) width 192: "ltr image, weak alt"
+layer at (9,273) size 280x80 backgroundClip at (9,223) size 300x100 clip at (9,223) size 300x100
+  LayoutNGBlockFlow (positioned) {IMG} at (1,51) size 280x80
+    LayoutInline {SPAN} at (0,0) size 8x19
+      LayoutImage (floating) {IMG} at (0,0) size 16x16
+      LayoutInline {SPAN} at (0,0) size 8x19
+        LayoutText {#text} at (16,0) size 8x19
+          text run at (16,0) width 8: ".,"
+layer at (314,222) size 302x102 clip at (315,223) size 300x100 scrollHeight 130
+  LayoutNGBlockFlow (relative positioned) {SECTION} at (306,214) size 302x102 [border: (1px solid #FF0000)]
+    LayoutNGBlockFlow {H2} at (1,20.91) size 300x27
+      LayoutText {#text} at (0,0) size 192x26
+        text run at (0,0) width 192: "rtl image, weak alt"
+layer at (315,273) size 280x80 backgroundClip at (315,223) size 300x100 clip at (315,223) size 300x100
+  LayoutNGBlockFlow (positioned) {IMG} at (1,51) size 280x80
+    LayoutInline {SPAN} at (0,0) size 8x19
+      LayoutImage (floating) {IMG} at (264,0) size 16x16
+      LayoutInline {SPAN} at (0,0) size 8x19
+        LayoutText {#text} at (256,0) size 8x19
+          text run at (256,0) width 8: ".,"
+layer at (8,329) size 302x102 clip at (9,330) size 300x100 scrollHeight 130
+  LayoutNGBlockFlow (relative positioned) {SECTION} at (0,321) size 302x102 [border: (1px solid #FF0000)]
+    LayoutNGBlockFlow {H2} at (1,20.91) size 300x27
+      LayoutText {#text} at (0,0) size 202x26
+        text run at (0,0) width 202: "ltr image, mixed alt"
+layer at (9,380) size 280x80 backgroundClip at (9,330) size 300x100 clip at (9,330) size 300x100
+  LayoutNGBlockFlow (positioned) {IMG} at (1,51) size 280x80
+    LayoutInline {SPAN} at (0,0) size 69x19
+      LayoutImage (floating) {IMG} at (0,0) size 16x16
+      LayoutInline {SPAN} at (0,0) size 69x19
+        LayoutText {#text} at (16,0) size 69x19
+          text run at (16,0) width 8: "\x{6CC}\x{627}"
+          text run at (24,0) width 53: "example"
+          text run at (77,0) width 8: "\x{6CC}\x{627}"
+layer at (314,329) size 302x102 clip at (315,330) size 300x100 scrollHeight 130
+  LayoutNGBlockFlow (relative positioned) {SECTION} at (306,321) size 302x102 [border: (1px solid #FF0000)]
+    LayoutNGBlockFlow {H2} at (1,20.91) size 300x27
+      LayoutText {#text} at (0,0) size 202x26
+        text run at (0,0) width 202: "rtl image, mixed alt"
+layer at (315,380) size 280x80 backgroundClip at (315,330) size 300x100 clip at (315,330) size 300x100
+  LayoutNGBlockFlow (positioned) {IMG} at (1,51) size 280x80
+    LayoutInline {SPAN} at (0,0) size 69x19
+      LayoutImage (floating) {IMG} at (264,0) size 16x16
+      LayoutInline {SPAN} at (0,0) size 69x19
+        LayoutText {#text} at (195,0) size 69x19
+          text run at (195,0) width 8: "\x{6CC}\x{627}"
+          text run at (203,0) width 53: "example"
+          text run at (256,0) width 8: "\x{6CC}\x{627}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/cg-fallback-bolding-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/cg-fallback-bolding-expected.txt
new file mode 100644
index 0000000..8c08042
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/cg-fallback-bolding-expected.txt
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x494
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x494
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x358
+      LayoutNGBlockFlow {P} at (0,0) size 784x80
+        LayoutText {#text} at (0,0) size 783x79
+          text run at (0,0) width 783: "The single Hebrew glyph below should be in the Lucida Grande font. It should not be a synthetic bold, because the first font"
+          text run at (0,20) width 781: "in the list (Ahem) does not have the glyph. Therefore we fall back to the second font in the list (Lucida Grande), which does"
+          text run at (0,40) width 727: "support bold. This test is making sure we don't make incorrect assumptions based off the fact that we would have to"
+          text run at (0,60) width 264: "synthesize bold for the first font in the list."
+      LayoutNGBlockFlow {P} at (0,208) size 784x150
+        LayoutText {#text} at (0,17) size 67x128
+          text run at (0,17) width 67: "\x{5D0}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/color-emoji-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/color-emoji-expected.txt
new file mode 100644
index 0000000..d7704e07
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/color-emoji-expected.txt
@@ -0,0 +1,53 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x433
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x433
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x401
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 564x19
+          text run at (0,0) width 564: "Three different sizes. The large size in particular should appear detailed and not pixelated."
+      LayoutNGBlockFlow {P} at (0,36) size 784x86
+        LayoutText {#text} at (0,52) size 74x19
+          text run at (0,52) width 74: "\x{D83D}\x{DE49}\x{D83D}\x{DE3B}\x{D83D}\x{DC11}\x{D83C}\x{DF7C}\x{D83C}\x{DF72}\x{D83D}\x{DE0D}"
+        LayoutInline {SPAN} at (0,0) size 22x5
+          LayoutText {#text} at (74,63) size 22x5
+            text run at (74,63) width 22: "\x{D83D}\x{DE49}\x{D83D}\x{DE3B}\x{D83D}\x{DC11}\x{D83C}\x{DF7C}\x{D83C}\x{DF72}\x{D83D}\x{DE0D}"
+        LayoutText {#text} at (96,52) size 4x19
+          text run at (96,52) width 4: " "
+        LayoutInline {SPAN} at (0,0) size 322x81
+          LayoutText {#text} at (100,3) size 322x81
+            text run at (100,3) width 322: "\x{D83D}\x{DE49}\x{D83D}\x{DE3B}\x{D83D}\x{DC11}\x{D83C}\x{DF7C}\x{D83C}\x{DF72}\x{D83D}\x{DE0D}"
+      LayoutNGBlockFlow {P} at (0,138) size 784x40
+        LayoutText {#text} at (0,0) size 341x19
+          text run at (0,0) width 341: "For the following, the emoji colors should not change."
+        LayoutBR {BR} at (341,0) size 0x0
+        LayoutText {#text} at (0,20) size 568x19
+          text run at (0,20) width 568: "The monkey should be colored, the sheep should be black outlined with a white body, etc."
+      LayoutNGBlockFlow {P} at (0,202) size 400x29 [bgcolor=#0000FF]
+        LayoutText {#text} at (0,1) size 281x27
+          text run at (0,1) width 281: "blue background: \x{D83D}\x{DE49}\x{D83D}\x{DE3B}\x{D83D}\x{DC11}\x{D83C}\x{DF7C}\x{D83C}\x{DF72}\x{D83D}\x{DE0D}"
+      LayoutNGBlockFlow {P} at (0,255) size 784x29 [color=#FF0000]
+        LayoutText {#text} at (0,1) size 193x27
+          text run at (0,1) width 193: "red text: \x{D83D}\x{DE49}\x{D83D}\x{DE3B}\x{D83D}\x{DC11}\x{D83C}\x{DF7C}\x{D83C}\x{DF72}\x{D83D}\x{DE0D}"
+      LayoutNGBlockFlow {P} at (0,308) size 784x40
+        LayoutText {#text} at (0,0) size 425x19
+          text run at (0,0) width 425: "For the following, each emoji should appear in two different colors."
+        LayoutBR {BR} at (424,0) size 0x0
+        LayoutText {#text} at (0,20) size 235x19
+          text run at (0,20) width 235: "Color swatches should not be visible."
+      LayoutNGBlockFlow {P} at (0,372) size 784x29
+        LayoutText {#text} at (0,1) size 372x27
+          text run at (0,1) width 372: "zero-width-joiners: \x{270C}\x{200D}\x{D83C}\x{DFFF}\x{270C}\x{200D}\x{D83C}\x{DFFC}\x{D83D}\x{DC6F}\x{200D}\x{D83C}\x{DFFB}\x{D83D}\x{DC6F}\x{200D}\x{D83C}\x{DFFF}\x{D83D}\x{DC72}\x{200D}\x{D83C}\x{DFFD}\x{D83D}\x{DC72}\x{200D}\x{D83C}\x{DFFB}"
+layer at (500,200) size 200x200
+  LayoutNGBlockFlow (positioned) {DIV} at (500,200) size 200x200
+    LayoutNGBlockFlow {P} at (0,24) size 200x87
+      LayoutText {#text} at (0,1) size 182x27
+        text run at (0,1) width 182: "rotated emoji: \x{D83D}\x{DE49}\x{D83D}\x{DE0D}"
+      LayoutBR {BR} at (182,1) size 0x0
+      LayoutInline {SPAN} at (0,0) size 149x27 [color=#008000]
+        LayoutText {#text} at (0,30) size 149x27
+          text run at (0,30) width 149: "green text: \x{D83D}\x{DE3B}\x{D83C}\x{DF7C}"
+      LayoutBR {BR} at (149,30) size 0x0
+      LayoutInline {SPAN} at (0,0) size 133x27 [bgcolor=#800080]
+        LayoutText {#text} at (0,59) size 133x27
+          text run at (0,59) width 133: "purple bg: \x{D83D}\x{DC11}\x{D83C}\x{DF72}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/fake-italic-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/fake-italic-expected.txt
new file mode 100644
index 0000000..70e63edc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/fake-italic-expected.txt
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x116
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x92
+      LayoutNGBlockFlow {P} at (0,0) size 784x60
+        LayoutText {#text} at (0,0) size 762x59
+          text run at (0,0) width 740: "This layout test is designed to test that our fake italic mode is working correctly. The Ahem font, used below, does not"
+          text run at (0,20) width 762: "include an italic variant. Thus, when we ask for italic Ahem, we should skew the glyphs ourselves, resulting in a series of"
+          text run at (0,40) width 155: "italic black boxes below."
+      LayoutNGBlockFlow {P} at (0,76) size 784x16
+        LayoutText {#text} at (0,0) size 112x16
+          text run at (0,0) width 112: "A A A A"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/fallback-for-custom-font-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/fallback-for-custom-font-expected.txt
new file mode 100644
index 0000000..42cc594
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/fallback-for-custom-font-expected.txt
@@ -0,0 +1,23 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x98
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x98
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x74
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 716x19
+          LayoutInline {A} at (0,0) size 158x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 158x19
+              text run at (51,0) width 158: "http://crbug.com/373389"
+          LayoutText {#text} at (208,0) size 559x19
+            text run at (208,0) width 559: " When a webfont is missing a glyph, synthesization from the fallback font isn't happening"
+        LayoutText {#text} at (766,0) size 5x19
+          text run at (766,0) width 5: "."
+      LayoutNGBlockFlow {P} at (0,36) size 784x38
+        LayoutText {#text} at (0,14) size 187x19
+          text run at (0,14) width 187: "A synthesized oblique bullet: "
+        LayoutInline {SPAN} at (0,0) size 20x32
+          LayoutText {#text} at (186,3) size 20x32
+            text run at (186,3) width 20: "\x{25CF}"
+        LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/font-initial-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/font-initial-expected.txt
new file mode 100644
index 0000000..9805764f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/font-initial-expected.txt
@@ -0,0 +1,21 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x72
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x72
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x56
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 618x19
+          LayoutInline {A} at (0,0) size 302x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 302x19
+              text run at (51,0) width 302: "http://bugs.webkit.org/show_bug.cgi?id=12039"
+          LayoutText {#text} at (352,0) size 317x19
+            text run at (352,0) width 317: " Assertion failure in WebCore::Font::primaryFont"
+        LayoutText {#text} at (668,0) size 5x19
+          text run at (668,0) width 5: "."
+      LayoutNGBlockFlow (anonymous) at (0,36) size 784x20
+        LayoutInline {SPAN} at (0,0) size 38x19
+          LayoutText {#text} at (0,0) size 38x19
+            text run at (0,0) width 38: "PASS"
+        LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/font-stretch-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/font-stretch-expected.txt
new file mode 100644
index 0000000..440586b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/font-stretch-expected.txt
@@ -0,0 +1,127 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x416
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x416
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x400
+      LayoutNGBlockFlow {H1} at (0,0) size 784x24
+        LayoutText {#text} at (0,0) size 253x23
+          text run at (0,0) width 253: "Tests support for font-stretch"
+      LayoutNGBlockFlow {P} at (0,26) size 784x17
+        LayoutText {#text} at (0,0) size 228x16
+          text run at (0,0) width 228: "Tests that CSS font-stretch is supported."
+      LayoutNGBlockFlow {SECTION} at (0,51) size 784x175
+        LayoutNGBlockFlow {H2} at (0,0) size 784x20
+          LayoutText {#text} at (0,0) size 61x19
+            text run at (0,0) width 61: "Segoe UI"
+        LayoutNGBlockFlow {P} at (0,22) size 784x17
+          LayoutNGBlockFlow {SPAN} at (0,0) size 210x17
+            LayoutText {#text} at (0,0) size 162x16
+              text run at (0,0) width 162: "font-stretch: ultra-condensed"
+          LayoutText {#text} at (210,0) size 349x16
+            text run at (210,0) width 349: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,39) size 784x17
+          LayoutNGBlockFlow {SPAN} at (0,0) size 210x17
+            LayoutText {#text} at (0,0) size 164x16
+              text run at (0,0) width 164: "font-stretch: extra-condensed"
+          LayoutText {#text} at (210,0) size 349x16
+            text run at (210,0) width 349: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,56) size 784x17
+          LayoutNGBlockFlow {SPAN} at (0,0) size 210x17
+            LayoutText {#text} at (0,0) size 131x16
+              text run at (0,0) width 131: "font-stretch: condensed"
+          LayoutText {#text} at (210,0) size 349x16
+            text run at (210,0) width 349: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,73) size 784x17
+          LayoutNGBlockFlow {SPAN} at (0,0) size 210x17
+            LayoutText {#text} at (0,0) size 162x16
+              text run at (0,0) width 162: "font-stretch: semi-condensed"
+          LayoutText {#text} at (210,0) size 349x16
+            text run at (210,0) width 349: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,90) size 784x17
+          LayoutNGBlockFlow {SPAN} at (0,0) size 210x17
+            LayoutText {#text} at (0,0) size 113x16
+              text run at (0,0) width 113: "font-stretch: normal"
+          LayoutText {#text} at (210,0) size 349x16
+            text run at (210,0) width 349: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,107) size 784x17
+          LayoutNGBlockFlow {SPAN} at (0,0) size 210x17
+            LayoutText {#text} at (0,0) size 157x16
+              text run at (0,0) width 157: "font-stretch: semi-expanded"
+          LayoutText {#text} at (210,0) size 349x16
+            text run at (210,0) width 349: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,124) size 784x17
+          LayoutNGBlockFlow {SPAN} at (0,0) size 210x17
+            LayoutText {#text} at (0,0) size 126x16
+              text run at (0,0) width 126: "font-stretch: expanded"
+          LayoutText {#text} at (210,0) size 349x16
+            text run at (210,0) width 349: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,141) size 784x17
+          LayoutNGBlockFlow {SPAN} at (0,0) size 210x17
+            LayoutText {#text} at (0,0) size 159x16
+              text run at (0,0) width 159: "font-stretch: extra-expanded"
+          LayoutText {#text} at (210,0) size 349x16
+            text run at (210,0) width 349: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,158) size 784x17
+          LayoutNGBlockFlow {SPAN} at (0,0) size 210x17
+            LayoutText {#text} at (0,0) size 157x16
+              text run at (0,0) width 157: "font-stretch: ultra-expanded"
+          LayoutText {#text} at (210,0) size 349x16
+            text run at (210,0) width 349: " - Just poets wax boldly as kings and queens march over fuzz."
+      LayoutNGBlockFlow {SECTION} at (0,234) size 784x166
+        LayoutNGBlockFlow {H2} at (0,0) size 784x20
+          LayoutText {#text} at (0,0) size 35x19
+            text run at (0,0) width 35: "Arial"
+        LayoutNGBlockFlow {P} at (0,22) size 784x16
+          LayoutNGBlockFlow {SPAN} at (0,0) size 240x16
+            LayoutText {#text} at (0,0) size 183x16
+              text run at (0,0) width 183: "font-stretch: ultra-condensed"
+          LayoutText {#text} at (240,0) size 393x16
+            text run at (240,0) width 393: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,38) size 784x16
+          LayoutNGBlockFlow {SPAN} at (0,0) size 240x16
+            LayoutText {#text} at (0,0) size 187x16
+              text run at (0,0) width 187: "font-stretch: extra-condensed"
+          LayoutText {#text} at (240,0) size 393x16
+            text run at (240,0) width 393: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,54) size 784x16
+          LayoutNGBlockFlow {SPAN} at (0,0) size 240x16
+            LayoutText {#text} at (0,0) size 150x16
+              text run at (0,0) width 150: "font-stretch: condensed"
+          LayoutText {#text} at (240,0) size 393x16
+            text run at (240,0) width 393: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,70) size 784x16
+          LayoutNGBlockFlow {SPAN} at (0,0) size 240x16
+            LayoutText {#text} at (0,0) size 185x16
+              text run at (0,0) width 185: "font-stretch: semi-condensed"
+          LayoutText {#text} at (240,0) size 393x16
+            text run at (240,0) width 393: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,86) size 784x16
+          LayoutNGBlockFlow {SPAN} at (0,0) size 240x16
+            LayoutText {#text} at (0,0) size 124x16
+              text run at (0,0) width 124: "font-stretch: normal"
+          LayoutText {#text} at (240,0) size 393x16
+            text run at (240,0) width 393: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,102) size 784x16
+          LayoutNGBlockFlow {SPAN} at (0,0) size 240x16
+            LayoutText {#text} at (0,0) size 178x16
+              text run at (0,0) width 178: "font-stretch: semi-expanded"
+          LayoutText {#text} at (240,0) size 393x16
+            text run at (240,0) width 393: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,118) size 784x16
+          LayoutNGBlockFlow {SPAN} at (0,0) size 240x16
+            LayoutText {#text} at (0,0) size 143x16
+              text run at (0,0) width 143: "font-stretch: expanded"
+          LayoutText {#text} at (240,0) size 393x16
+            text run at (240,0) width 393: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,134) size 784x16
+          LayoutNGBlockFlow {SPAN} at (0,0) size 240x16
+            LayoutText {#text} at (0,0) size 180x16
+              text run at (0,0) width 180: "font-stretch: extra-expanded"
+          LayoutText {#text} at (240,0) size 393x16
+            text run at (240,0) width 393: " - Just poets wax boldly as kings and queens march over fuzz."
+        LayoutNGBlockFlow {P} at (0,150) size 784x16
+          LayoutNGBlockFlow {SPAN} at (0,0) size 240x16
+            LayoutText {#text} at (0,0) size 176x16
+              text run at (0,0) width 176: "font-stretch: ultra-expanded"
+          LayoutText {#text} at (240,0) size 393x16
+            text run at (240,0) width 393: " - Just poets wax boldly as kings and queens march over fuzz."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/font-stretch-variant-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/font-stretch-variant-expected.txt
new file mode 100644
index 0000000..f1da8c2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/font-stretch-variant-expected.txt
@@ -0,0 +1,83 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 654
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x654 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 785x654.44
+    LayoutNGBlockFlow {BODY} at (8,19.91) size 769x626.53
+      LayoutNGBlockFlow {SECTION} at (0,0) size 769x141.91
+        LayoutNGBlockFlow {H2} at (0,0) size 769x27
+          LayoutText {#text} at (0,0) size 411x26
+            text run at (0,0) width 411: "font-stretch: condensed vs Arial Narrow"
+        LayoutNGBlockFlow {DIV} at (0,46.91) size 769x19
+          LayoutText {#text} at (0,0) size 445x18
+            text run at (0,0) width 445: "Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,65.91) size 769x20
+          LayoutText {#text} at (0,0) size 396x19
+            text run at (0,0) width 396: "Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,85.91) size 769x20
+          LayoutText {#text} at (0,0) size 396x19
+            text run at (0,0) width 396: "Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {P} at (0,121.91) size 769x20
+          LayoutText {#text} at (0,0) size 325x19
+            text run at (0,0) width 325: "The three lines above should have the same weight."
+      LayoutNGBlockFlow {SECTION} at (0,161.81) size 769x217.91
+        LayoutNGBlockFlow {H2} at (0,0) size 769x27
+          LayoutText {#text} at (0,0) size 210x26
+            text run at (0,0) width 210: "Specific width, Arial"
+        LayoutNGBlockFlow {DIV} at (0,46.91) size 769x19
+          LayoutText {#text} at (0,0) size 659x18
+            text run at (0,0) width 659: "font-stretch: ultra-condensed - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,65.91) size 769x19
+          LayoutText {#text} at (0,0) size 663x18
+            text run at (0,0) width 663: "font-stretch: extra-condensed - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,84.91) size 769x19
+          LayoutText {#text} at (0,0) size 623x18
+            text run at (0,0) width 623: "font-stretch: condensed - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,103.91) size 769x19
+          LayoutText {#text} at (0,0) size 662x18
+            text run at (0,0) width 662: "font-stretch: semi-condensed - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,122.91) size 769x19
+          LayoutText {#text} at (0,0) size 593x18
+            text run at (0,0) width 593: "font-stretch: normal - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,141.91) size 769x19
+          LayoutText {#text} at (0,0) size 654x18
+            text run at (0,0) width 654: "font-stretch: semi-expanded - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,160.91) size 769x19
+          LayoutText {#text} at (0,0) size 615x18
+            text run at (0,0) width 615: "font-stretch: expanded - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,179.91) size 769x19
+          LayoutText {#text} at (0,0) size 655x18
+            text run at (0,0) width 655: "font-stretch: extra-expanded - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,198.91) size 769x19
+          LayoutText {#text} at (0,0) size 651x18
+            text run at (0,0) width 651: "font-stretch: ultra-expanded - Back in June we delivered oxygen equipment of the same size."
+      LayoutNGBlockFlow {SECTION} at (0,399.63) size 769x226.91
+        LayoutNGBlockFlow {H2} at (0,0) size 769x27
+          LayoutText {#text} at (0,0) size 296x26
+            text run at (0,0) width 296: "Specific width, Arial Narrow"
+        LayoutNGBlockFlow {DIV} at (0,46.91) size 769x20
+          LayoutText {#text} at (0,0) size 588x19
+            text run at (0,0) width 588: "font-stretch: ultra-condensed - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,66.91) size 769x20
+          LayoutText {#text} at (0,0) size 591x19
+            text run at (0,0) width 591: "font-stretch: extra-condensed - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,86.91) size 769x20
+          LayoutText {#text} at (0,0) size 555x19
+            text run at (0,0) width 555: "font-stretch: condensed - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,106.91) size 769x20
+          LayoutText {#text} at (0,0) size 589x19
+            text run at (0,0) width 589: "font-stretch: semi-condensed - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,126.91) size 769x20
+          LayoutText {#text} at (0,0) size 532x19
+            text run at (0,0) width 532: "font-stretch: normal - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,146.91) size 769x20
+          LayoutText {#text} at (0,0) size 583x19
+            text run at (0,0) width 583: "font-stretch: semi-expanded - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,166.91) size 769x20
+          LayoutText {#text} at (0,0) size 549x19
+            text run at (0,0) width 549: "font-stretch: expanded - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,186.91) size 769x20
+          LayoutText {#text} at (0,0) size 585x19
+            text run at (0,0) width 585: "font-stretch: extra-expanded - Back in June we delivered oxygen equipment of the same size."
+        LayoutNGBlockFlow {DIV} at (0,206.91) size 769x20
+          LayoutText {#text} at (0,0) size 582x19
+            text run at (0,0) width 582: "font-stretch: ultra-expanded - Back in June we delivered oxygen equipment of the same size."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-CS-after-AN-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-CS-after-AN-expected.txt
new file mode 100644
index 0000000..7d43e582
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-CS-after-AN-expected.txt
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x88
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x88
+    LayoutNGBlockFlow {BODY} at (8,16) size 784x56
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 470x19
+          text run at (0,0) width 470: "The following should look like: Arabic characters 123.4 Arabic characters."
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (0,0) size 76x19
+          text run at (0,0) width 21: " \x{644}\x{645}\x{646}"
+          text run at (21,0) width 36: "123.4"
+          text run at (57,0) width 19: "\x{627}\x{628}\x{62C} "
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-linebreak-001-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-linebreak-001-expected.txt
new file mode 100644
index 0000000..0d65a1f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-linebreak-001-expected.txt
@@ -0,0 +1,20 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x164
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x164
+    LayoutNGBlockFlow {BODY} at (8,16) size 784x132
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 761x39
+          text run at (0,0) width 761: "This HTML tests if the 'while-space' property controls the behavors of line-break characters (U+000A and U+000D) in a"
+          text run at (0,20) width 85: "complex text."
+      LayoutNGBlockFlow {P} at (0,56) size 784x20
+        LayoutText {#text} at (0,0) size 499x19
+          text run at (0,0) width 292: "If this test succeeds, you can see three words \""
+          text run at (292,0) width 30: "\x{5E9}\x{5D5}\x{5BC}\x{5E8}\x{5D4}"
+          text run at (322,0) width 177: "\", separated with line-break."
+      LayoutNGBlockFlow {P} at (0,92) size 784x40
+        LayoutText {#text} at (0,0) size 60x39
+          text run at (0,0) width 30: "\x{5E9}\x{5D5}\x{5BC}\x{5E8}\x{5D4}"
+          text run at (30,0) width 0: " "
+          text run at (0,20) width 30: "\x{5E9}\x{5D5}\x{5BC}\x{5E8}\x{5D4}"
+          text run at (30,20) width 30: "\x{5E9}\x{5D5}\x{5BC}\x{5E8}\x{5D4}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-listbox-atsui-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-listbox-atsui-expected.txt
new file mode 100644
index 0000000..76f6303
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-listbox-atsui-expected.txt
@@ -0,0 +1,60 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x360
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x360
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x344
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 578x19
+          text run at (0,0) width 578: "This tests that bidirectional text is correctly rendered when using ATSUI in list box controls."
+        LayoutBR {BR} at (577,0) size 0x0
+        LayoutText {#text} at (0,20) size 566x19
+          text run at (0,20) width 566: "The order of the text below each list box should match the order of the select's option text."
+      LayoutNGBlockFlow (anonymous) at (0,56) size 784x56
+        LayoutText {#text} at (0,0) size 97x19
+          text run at (0,0) width 97: "1) direction: rtl;"
+        LayoutBR {BR} at (97,0) size 0x0
+        LayoutBR {BR} at (84,37) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,112) size 100x20
+        LayoutText {#text} at (31,0) size 69x19
+          text run at (31,0) width 47: "\x{5D0}\x{5E4}\x{5E8}\x{5E1}\x{5DE}\x{5D5}\x{5DF}"
+          text run at (78,0) width 22: "a\x{300}bc"
+      LayoutNGBlockFlow (anonymous) at (0,132) size 784x76
+        LayoutBR {BR} at (0,0) size 0x0
+        LayoutText {#text} at (0,20) size 97x19
+          text run at (0,20) width 97: "2) direction: ltr;"
+        LayoutBR {BR} at (97,20) size 0x0
+        LayoutBR {BR} at (84,57) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,208) size 100x20
+        LayoutText {#text} at (0,0) size 69x19
+          text run at (0,0) width 22: "a\x{300}bc"
+          text run at (22,0) width 47: "\x{5D0}\x{5E4}\x{5E8}\x{5E1}\x{5DE}\x{5D5}\x{5DF}"
+      LayoutNGBlockFlow (anonymous) at (0,228) size 784x76
+        LayoutBR {BR} at (0,0) size 0x0
+        LayoutText {#text} at (0,20) size 70x19
+          text run at (0,20) width 70: "3) No style"
+        LayoutBR {BR} at (70,20) size 0x0
+        LayoutBR {BR} at (84,57) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,304) size 100x20
+        LayoutText {#text} at (0,0) size 69x19
+          text run at (0,0) width 22: "a\x{300}bc"
+          text run at (22,0) width 47: "\x{5D0}\x{5E4}\x{5E8}\x{5E1}\x{5DE}\x{5D5}\x{5DF}"
+      LayoutNGBlockFlow (anonymous) at (0,324) size 784x20
+        LayoutBR {BR} at (0,0) size 0x0
+layer at (8,84) size 84x36 clip at (24,85) size 67x34
+  LayoutListBox {SELECT} at (0,20) size 84x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {OPTION} at (16,1) size 67x17
+      LayoutText {#text} at (2,0) size 63x16
+        text run at (2,0) width 42 RTL: "\x{5D0}\x{5E4}\x{5E8}\x{5E1}\x{5DE}\x{5D5}\x{5DF}"
+        text run at (44,0) width 21: "a\x{300}bc"
+layer at (8,180) size 84x36 clip at (9,181) size 67x34
+  LayoutListBox {SELECT} at (0,40) size 84x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {OPTION} at (1,1) size 67x17
+      LayoutText {#text} at (2,0) size 63x16
+        text run at (2,0) width 21: "a\x{300}bc"
+        text run at (23,0) width 42 RTL: "\x{5D0}\x{5E4}\x{5E8}\x{5E1}\x{5DE}\x{5D5}\x{5DF}"
+layer at (8,276) size 84x36 clip at (9,277) size 67x34
+  LayoutListBox {SELECT} at (0,40) size 84x36 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+    LayoutBlockFlow {OPTION} at (1,1) size 67x17
+      LayoutText {#text} at (2,0) size 63x16
+        text run at (2,0) width 21: "a\x{300}bc"
+        text run at (23,0) width 42 RTL: "\x{5D0}\x{5E4}\x{5E8}\x{5E1}\x{5DE}\x{5D5}\x{5DF}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-mirror-he-ar-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-mirror-he-ar-expected.txt
new file mode 100644
index 0000000..56cee62
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-mirror-he-ar-expected.txt
@@ -0,0 +1,20 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x148
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x148
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x132
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (464,0) size 320x19
+          text run at (464,0) width 320: "This test tests bidi mirroring in Hebrew and Arabic"
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (327,0) size 457x19
+          text run at (327,0) width 457: "The parenthesis should be displayed as \"(...)...\" visually from left to right"
+      LayoutNGBlockFlow {DIV} at (0,72) size 784x20
+        LayoutText {#text} at (754,0) size 30x19
+          text run at (754,0) width 30: "\x{5E9}(\x{5E9})"
+      LayoutNGBlockFlow {DIV} at (0,92) size 784x20
+        LayoutText {#text} at (760,0) size 24x19
+          text run at (760,0) width 24: "\x{5C6}(\x{5C6})"
+      LayoutNGBlockFlow {DIV} at (0,112) size 784x20
+        LayoutText {#text} at (758,0) size 26x19
+          text run at (758,0) width 26: "\x{644}(\x{644})"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-neutral-directionality-paragraph-start-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-neutral-directionality-paragraph-start-expected.txt
new file mode 100644
index 0000000..120c5cc7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-neutral-directionality-paragraph-start-expected.txt
@@ -0,0 +1,35 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x304
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x304
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x280
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 569x19
+          text run at (0,0) width 569: "Mitz Pettel contributed this fix to KDE, and now we're rolling it in. Here's his explanation:"
+      LayoutNGBlockFlow {P} at (0,36) size 784x80
+        LayoutText {#text} at (0,0) size 776x79
+          text run at (0,0) width 766: "The directionality of a neutral character at the beginning of a paragraph (or after a hard line break) is decided incorrectly if"
+          text run at (0,20) width 776: "the first non-neutral character in the paragraph has directionality opposite to the paragraph directionality. For example, if the"
+          text run at (0,40) width 766: "paragraph direction is LTR, the first character on the paragraph is a question mark and the next one is a Hebrew character,"
+          text run at (0,60) width 643: "then the question mark will is considered right-to-left and appears to the right of the Hebrew character."
+      LayoutNGBlockFlow {P} at (0,132) size 784x40
+        LayoutText {#text} at (0,0) size 508x19
+          text run at (0,0) width 508: "The rule to follow is 3.3.4.N2 in the Unicode Standard's Bidirectional Algorithm"
+        LayoutInline {A} at (0,0) size 395x19 [color=#0000EE]
+          LayoutText {#text} at (0,20) size 395x19
+            text run at (0,20) width 395: "http://www.unicode.org/reports/tr9/#Resolving_Neutral_Types"
+        LayoutText {#text} at (394,20) size 5x19
+          text run at (394,20) width 5: "."
+      LayoutNGBlockFlow {P} at (0,188) size 784x20
+        LayoutText {#text} at (0,0) size 676x19
+          text run at (0,0) width 676: "If the test is successful, the question marks should be on the far left and far right of the next two paragraphs."
+      LayoutNGBlockFlow {P} at (0,224) size 784x20
+        LayoutText {#text} at (0,0) size 66x19
+          text run at (0,0) width 11: "? "
+          text run at (11,0) width 24: "\x{FEB2} \x{FEED}"
+          text run at (35,0) width 31: "hello"
+      LayoutNGBlockFlow {P} at (0,260) size 784x20
+        LayoutText {#text} at (714,0) size 70x19
+          text run at (714,0) width 28: " \x{FEB2} \x{FEED}"
+          text run at (742,0) width 31: "hello"
+          text run at (773,0) width 11: "? "
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/complex-character-based-fallback-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/complex-character-based-fallback-expected.txt
new file mode 100644
index 0000000..4777345
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/complex-character-based-fallback-expected.txt
@@ -0,0 +1,36 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x458
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x458
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x434
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 778x39
+          text run at (0,0) width 778: "This tests that complex text that requires font fallback wraps correctly. The text is Tamil, which is not covered by the default"
+          text run at (0,20) width 421: "font, so fallback occurs. Note that the exclamation point in the end "
+        LayoutInline {I} at (0,0) size 10x19
+          LayoutText {#text} at (421,20) size 10x19
+            text run at (421,20) width 10: "is"
+        LayoutText {#text} at (431,20) size 327x19
+          text run at (431,20) width 327: " covered by the default font and is rendered using it."
+      LayoutNGBlockFlow {P} at (0,56) size 306x153 [border: (3px solid #000000)]
+        LayoutText {#text} at (3,3) size 300x145
+          text run at (3,3) width 176: "\x{B87}\x{BA4}\x{BC1} \x{B89}\x{B99}\x{BCD}\x{B95}\x{BB3}\x{BC8}\x{BAA}\x{BCD} \x{BAA}\x{BCB}\x{BA9}\x{BCD}\x{BB1}"
+          text run at (3,24) width 290: "\x{B86}\x{BB0}\x{BCD}\x{BB5}\x{BAE}\x{BC1}\x{B9F}\x{BC8}\x{BAF}\x{BB5}\x{BB0}\x{BCD}\x{B95}\x{BB3}\x{BBE}\x{BB2}\x{BCD} \x{BA4}\x{BCA}\x{B95}\x{BC1}\x{B95}\x{BCD}\x{B95}\x{BAA}\x{BCD}\x{BAA}\x{B9F}\x{BCD}\x{B9F}\x{BC1}"
+          text run at (3,45) width 300: "\x{B95}\x{B9F}\x{BCD}\x{B9F}\x{BC1}\x{BAA}\x{BCD}\x{BAA}\x{BBE}\x{B9F}\x{BC1}\x{B95}\x{BB3}\x{BCD} \x{B8F}\x{BA4}\x{BC1}\x{BAE}\x{BCD} \x{B87}\x{BA9}\x{BCD}\x{BB1}\x{BBF} \x{B87}\x{BB2}\x{BB5}\x{B9A}\x{BAE}\x{BBE}\x{B95}\x{BAA}\x{BCD}"
+          text run at (3,66) width 264: "\x{BAA}\x{BAF}\x{BA9}\x{BCD}\x{BAA}\x{B9F}\x{BC1}\x{BA4}\x{BCD}\x{BA4}\x{B95}\x{BCD}\x{B95}\x{BC2}\x{B9F}\x{BBF}\x{BAF} \x{B92}\x{BB0}\x{BC1} \x{BAA}\x{BA9}\x{BCD}\x{BAE}\x{BCA}\x{BB4}\x{BBF}\x{B95}\x{BCD}"
+          text run at (3,87) width 273: "\x{B95}\x{BB2}\x{BC8}\x{B95}\x{BCD} \x{B95}\x{BB3}\x{B9E}\x{BCD}\x{B9A}\x{BBF}\x{BAF}\x{BA4}\x{BCD} \x{BA4}\x{BBF}\x{B9F}\x{BCD}\x{B9F}\x{BAE}\x{BBE}\x{B95}\x{BC1}\x{BAE}\x{BCD}. \x{B87}\x{B99}\x{BCD}\x{B95}\x{BC1}"
+          text run at (3,108) width 254: "\x{BA8}\x{BC0}\x{B99}\x{BCD}\x{B95}\x{BB3}\x{BC1}\x{BAE}\x{BCD} \x{B89}\x{B99}\x{BCD}\x{B95}\x{BB3}\x{BC1}\x{B95}\x{BCD}\x{B95}\x{BC1} \x{BB5}\x{BBF}\x{BB0}\x{BC1}\x{BAA}\x{BCD}\x{BAA}\x{BAE}\x{BBE}\x{BA9}"
+          text run at (3,129) width 263: "\x{BA4}\x{BB2}\x{BC8}\x{BAA}\x{BCD}\x{BAA}\x{BC1}\x{B95}\x{BB3}\x{BBF}\x{BB2}\x{BCD} \x{BAA}\x{BC1}\x{BA4}\x{BBF}\x{BA4}\x{BBE}\x{B95}\x{B95}\x{BCD} \x{B95}\x{B9F}\x{BCD}\x{B9F}\x{BC1}\x{BB0}\x{BC8}\x{B95}\x{BB3}\x{BCD}!"
+      LayoutNGBlockFlow {P} at (0,225) size 784x40
+        LayoutText {#text} at (0,0) size 777x39
+          text run at (0,0) width 777: "This is the same text but specifying a font that covers Tamil. Note that the exclamation point is rendered using the same font"
+          text run at (0,20) width 67: "as the text."
+      LayoutNGBlockFlow {P} at (0,281) size 306x153 [border: (3px solid #000000)]
+        LayoutText {#text} at (3,3) size 300x145
+          text run at (3,3) width 176: "\x{B87}\x{BA4}\x{BC1} \x{B89}\x{B99}\x{BCD}\x{B95}\x{BB3}\x{BC8}\x{BAA}\x{BCD} \x{BAA}\x{BCB}\x{BA9}\x{BCD}\x{BB1}"
+          text run at (3,24) width 290: "\x{B86}\x{BB0}\x{BCD}\x{BB5}\x{BAE}\x{BC1}\x{B9F}\x{BC8}\x{BAF}\x{BB5}\x{BB0}\x{BCD}\x{B95}\x{BB3}\x{BBE}\x{BB2}\x{BCD} \x{BA4}\x{BCA}\x{B95}\x{BC1}\x{B95}\x{BCD}\x{B95}\x{BAA}\x{BCD}\x{BAA}\x{B9F}\x{BCD}\x{B9F}\x{BC1}"
+          text run at (3,45) width 300: "\x{B95}\x{B9F}\x{BCD}\x{B9F}\x{BC1}\x{BAA}\x{BCD}\x{BAA}\x{BBE}\x{B9F}\x{BC1}\x{B95}\x{BB3}\x{BCD} \x{B8F}\x{BA4}\x{BC1}\x{BAE}\x{BCD} \x{B87}\x{BA9}\x{BCD}\x{BB1}\x{BBF} \x{B87}\x{BB2}\x{BB5}\x{B9A}\x{BAE}\x{BBE}\x{B95}\x{BAA}\x{BCD}"
+          text run at (3,66) width 264: "\x{BAA}\x{BAF}\x{BA9}\x{BCD}\x{BAA}\x{B9F}\x{BC1}\x{BA4}\x{BCD}\x{BA4}\x{B95}\x{BCD}\x{B95}\x{BC2}\x{B9F}\x{BBF}\x{BAF} \x{B92}\x{BB0}\x{BC1} \x{BAA}\x{BA9}\x{BCD}\x{BAE}\x{BCA}\x{BB4}\x{BBF}\x{B95}\x{BCD}"
+          text run at (3,87) width 273: "\x{B95}\x{BB2}\x{BC8}\x{B95}\x{BCD} \x{B95}\x{BB3}\x{B9E}\x{BCD}\x{B9A}\x{BBF}\x{BAF}\x{BA4}\x{BCD} \x{BA4}\x{BBF}\x{B9F}\x{BCD}\x{B9F}\x{BAE}\x{BBE}\x{B95}\x{BC1}\x{BAE}\x{BCD}. \x{B87}\x{B99}\x{BCD}\x{B95}\x{BC1}"
+          text run at (3,108) width 254: "\x{BA8}\x{BC0}\x{B99}\x{BCD}\x{B95}\x{BB3}\x{BC1}\x{BAE}\x{BCD} \x{B89}\x{B99}\x{BCD}\x{B95}\x{BB3}\x{BC1}\x{B95}\x{BCD}\x{B95}\x{BC1} \x{BB5}\x{BBF}\x{BB0}\x{BC1}\x{BAA}\x{BCD}\x{BAA}\x{BAE}\x{BBE}\x{BA9}"
+          text run at (3,129) width 263: "\x{BA4}\x{BB2}\x{BC8}\x{BAA}\x{BCD}\x{BAA}\x{BC1}\x{B95}\x{BB3}\x{BBF}\x{BB2}\x{BCD} \x{BAA}\x{BC1}\x{BA4}\x{BBF}\x{BA4}\x{BBE}\x{B95}\x{B95}\x{BCD} \x{B95}\x{B9F}\x{BCD}\x{B9F}\x{BC1}\x{BB0}\x{BC8}\x{B95}\x{BB3}\x{BCD}!"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/danda-space-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/danda-space-expected.txt
new file mode 100644
index 0000000..1a8d0ef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/danda-space-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x93
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x93
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x69
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {A} at (0,0) size 69x19 [color=#0000EE]
+          LayoutText {#text} at (51,0) size 69x19
+            text run at (51,0) width 69: "bug 25464"
+        LayoutText {#text} at (119,0) size 385x19
+          text run at (119,0) width 385: ": Test for rendering of Danda (U+0964) followed by a space."
+      LayoutNGBlockFlow {P} at (0,36) size 784x33
+        LayoutText {#text} at (0,6) size 299x19
+          text run at (0,6) width 299: "\x{A39}\x{A41}\x{A70}\x{A26}\x{A40} \x{A39}\x{A48}\x{964} \x{A07}\x{A38} \x{A32}\x{A3F}\x{A2A}\x{A40} \x{A26}\x{A47} \x{A35}\x{A3F}\x{A1A} \x{A69}\x{A6B} (35) \x{A05}\x{A71}\x{A16}\x{A30} \x{A39}\x{A41}\x{A70}\x{A26}\x{A47} \x{A39}\x{A28}\x{964}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/plane2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/plane2-expected.txt
new file mode 100644
index 0000000..f592467
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/plane2-expected.txt
@@ -0,0 +1,22 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x168
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x168
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x152
+      LayoutNGBlockFlow {P} at (0,0) size 784x60
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {A} at (0,0) size 69x19 [color=#0000EE]
+          LayoutText {#text} at (51,0) size 69x19
+            text run at (51,0) width 69: "bug 35605"
+        LayoutText {#text} at (119,0) size 758x59
+          text run at (119,0) width 632: ": Two lines below have one character from CJK Ideograph, one from CJK Ext A (both in BMP) and"
+          text run at (0,20) width 758: "three characters from CJK Ext B (plane 2). The last group of characters are covered by Japanese fonts on Mac as well as"
+          text run at (0,40) width 331: "two Chinese fonts for Ext B shipped with Windows."
+      LayoutNGBlockFlow {DIV} at (0,76) size 784x76
+        LayoutNGBlockFlow {DIV} at (0,0) size 784x39
+          LayoutText {#text} at (0,2) size 163x36
+            text run at (0,2) width 163: "\x{4E00} \x{3400} \x{D867}\x{DE8A}\x{D867}\x{DE49}\x{D867}\x{DEDB}"
+        LayoutNGBlockFlow {DIV} at (0,39) size 784x37
+          LayoutText {#text} at (0,0) size 169x36
+            text run at (0,0) width 169: "\x{4E00} \x{3400} \x{D867}\x{DE8A}\x{D867}\x{DE49}\x{D867}\x{DEDB}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/thai-baht-space-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/thai-baht-space-expected.txt
new file mode 100644
index 0000000..261d785
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/thai-baht-space-expected.txt
@@ -0,0 +1,20 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x140
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x140
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x116
+      LayoutNGBlockFlow (anonymous) at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {A} at (0,0) size 69x19 [color=#0000EE]
+          LayoutText {#text} at (51,0) size 69x19
+            text run at (51,0) width 69: "bug 25464"
+        LayoutText {#text} at (119,0) size 770x39
+          text run at (119,0) width 651: ". Characters belonging to 'Common' script followed / preceded by a space should be rendered correctly."
+          text run at (0,20) width 575: "Two lines below have 4 Thai currency signs (U+0E3F) and all of them should be rendered."
+      LayoutNGBlockFlow {P} at (0,56) size 784x60
+        LayoutText {#text} at (0,6) size 290x19
+          text run at (0,6) width 290: "abc \x{E25}\x{E07}\x{E17}\x{E38}\x{E19}4000\x{E3F} \x{E23}\x{E31}\x{E1A}\x{E1B}\x{E23}\x{E30}\x{E01}\x{E31}\x{E19}\x{E23}\x{E32}\x{E22}\x{E44}\x{E14}\x{E49} 50000\x{E3F}/M"
+        LayoutBR {BR} at (290,6) size 0x0
+        LayoutText {#text} at (0,36) size 290x19
+          text run at (0,36) width 290: "abc \x{E25}\x{E07}\x{E17}\x{E38}\x{E19}4000 \x{E3F}\x{E23}\x{E31}\x{E1A}\x{E1B}\x{E23}\x{E30}\x{E01}\x{E31}\x{E19}\x{E23}\x{E32}\x{E22}\x{E44}\x{E14}\x{E49} 50000\x{E3F}/M"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/unicode-bidi-plaintext-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/unicode-bidi-plaintext-expected.txt
new file mode 100644
index 0000000..d4e2d702
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/unicode-bidi-plaintext-expected.txt
@@ -0,0 +1,40 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x214
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x214
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x193
+      LayoutNGBlockFlow {DIV} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 508x19
+          text run at (0,0) width 508: "This tests proper handling of unicode-bidi: plaintext. You should not see any red."
+      LayoutNGBlockFlow {DIV} at (0,20) size 784x80
+        LayoutText {#text} at (0,0) size 40x19
+          text run at (0,0) width 40: "!hello."
+        LayoutBR {BR} at (40,0) size 0x0
+        LayoutText {#text} at (746,20) size 38x19
+          text run at (746,20) width 38: "!\x{5E9}\x{5DC}\x{5D5}\x{5DD}."
+        LayoutBR {BR} at (746,20) size 0x0
+        LayoutText {#text} at (0,40) size 59x19
+          text run at (0,40) width 39: "hello, "
+          text run at (39,40) width 15: "\x{5DC}\x{5D5}\x{5D9}"
+          text run at (54,40) width 5: "!"
+        LayoutBR {BR} at (59,40) size 0x0
+        LayoutText {#text} at (693,60) size 91x19
+          text run at (693,60) width 6: "!"
+          text run at (698,60) width 49: "WebKit"
+          text run at (747,60) width 37: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}, "
+      LayoutNGBlockFlow {PRE} at (0,113) size 784x80
+        LayoutText {#text} at (0,0) size 784x80
+          text run at (0,0) width 8: "a"
+          text run at (8,0) width 0: " "
+          text run at (0,16) width 8: "("
+          text run at (8,16) width 0: " "
+          text run at (680,32) width 0: " "
+          text run at (680,32) width 8: "!"
+          text run at (688,32) width 48: "WebKit"
+          text run at (736,32) width 48: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}, "
+          text run at (0,48) width 56: "hello, "
+          text run at (56,48) width 24: "\x{5DC}\x{5D5}\x{5D9}"
+          text run at (80,48) width 8: "!"
+          text run at (88,48) width 0: " "
+          text run at (0,64) width 8: ")"
+          text run at (8,64) width 0: " "
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/vertical-text-glyph-test-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/vertical-text-glyph-test-expected.txt
new file mode 100644
index 0000000..8daf494
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/vertical-text-glyph-test-expected.txt
@@ -0,0 +1,23 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 605
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x605 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 785x605.25
+    LayoutNGBlockFlow {BODY} at (8,21.33) size 769x575.92
+      LayoutNGBlockFlow {P} at (0,0) size 769x24
+        LayoutText {#text} at (0,0) size 139x23
+          text run at (0,0) width 139: "Simple text path"
+      LayoutNGBlockFlow (anonymous) at (0,45.33) size 769x225.64
+        LayoutNGBlockFlow {SPAN} at (0,0) size 24x219.64
+          LayoutText {#text} at (1,0) size 23x220
+            text run at (1,0) width 220: "string\x{300C}\x{3042}\x{3001}\x{5909}\x{3063}\x{FF01}\x{300D}\x{3002}"
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {P} at (0,304.95) size 769x24
+        LayoutText {#text} at (0,0) size 157x23
+          text run at (0,0) width 157: "Complex text path"
+      LayoutNGBlockFlow (anonymous) at (0,350.28) size 769x225.64
+        LayoutNGBlockFlow {SPAN} at (0,0) size 24x219.64
+          LayoutText {#text} at (1,0) size 23x220
+            text run at (1,0) width 220: "string\x{300C}\x{3042}\x{3001}\x{5909}\x{3063}\x{FF01}\x{300D}\x{3002}"
+        LayoutText {#text} at (0,0) size 0x0
+layer at (8,303) size 769x2 clip at (0,0) size 0x0
+  LayoutNGBlockFlow {HR} at (0,281.63) size 769x2 [border: (1px inset #EEEEEE)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-ideograph-complex-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-ideograph-complex-expected.txt
new file mode 100644
index 0000000..4ca90146
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-ideograph-complex-expected.txt
@@ -0,0 +1,39 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x432
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x432
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x412
+      LayoutNGBlockFlow {P} at (0,0) size 550x64
+        LayoutText {#text} at (0,0) size 550x63
+          text run at (0,0) width 550: "\x{3010}2009 \x{5E74} 11 \x{6708} 4 \x{65E5}\x{7F8E}\x{570B}\x{52A0}\x{5DDE} Cupertino \x{8A0A}\x{3011}\x{860B}\x{679C}\x{4ECA}\x{5929}\x{5BA3}\x{4F48}\x{FF0C}\x{5168}\x{4E16}\x{754C}\x{6700}\x{5927}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{5546}\x{5E97} App Store\x{FF0C}\x{76EE}\x{524D}"
+          text run at (0,16) width 550: "\x{5DF2}\x{64C1}\x{6709} 100,000 \x{591A}\x{7A2E}\x{4F86}\x{81EA}\x{5168}\x{7403}\x{958B}\x{767C}\x{4EBA}\x{54E1}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{3002}\x{5168}\x{4E16}\x{754C} 77 \x{500B}\x{570B}\x{5BB6}\x{7684} iPhone\x{AE} \x{8207} iPod touch\x{AE} \x{7528}\x{6236}\x{64C1}\x{6709}"
+          text run at (0,32) width 550: "20 \x{500B}\x{985E}\x{5225}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{53EF}\x{4F9B}\x{9078}\x{64C7}\x{FF0C}\x{5305}\x{62EC}\x{FF1A}\x{904A}\x{6232}\x{3001}\x{5546}\x{7528}\x{3001}\x{65B0}\x{805E}\x{3001}\x{904B}\x{52D5}\x{3001}\x{91AB}\x{7642}\x{3001}\x{53C3}\x{8003}\x{66F8}\x{7C4D}\x{3001}\x{65C5}\x{904A}\x{7B49}\x{7B49}\x{3002}\x{622A}\x{81F3}\x{76EE}"
+          text run at (0,48) width 478: "\x{524D}\x{70BA}\x{6B62}\x{FF0C}App Store \x{4F7F}\x{7528}\x{8005}\x{4E0B}\x{8F09}\x{6B21}\x{6578}\x{5DF2}\x{8D85}\x{904E} 20 \x{5104}\x{6B21}\x{FF0C}\x{662F}\x{76EE}\x{524D}\x{5168}\x{7403}\x{6700}\x{53D7}\x{6B61}\x{8FCE}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{5546}\x{5E97}\x{3002}"
+      LayoutNGBlockFlow {P} at (0,76) size 550x48
+        LayoutText {#text} at (0,0) size 550x47
+          text run at (0,0) width 550: "\x{860B}\x{679C}\x{5168}\x{7403}\x{7522}\x{54C1}\x{884C}\x{92B7}\x{8CC7}\x{6DF1}\x{526F}\x{7E3D}\x{88C1} Philip Schiller \x{8868}\x{793A}\x{FF1A}\x{300C}\x{63D0}\x{4F9B} 100,000 \x{591A}\x{7A2E}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{53EF}\x{4F9B}\x{9078}\x{64C7}\x{7684} App Store\x{FF0C}\x{662F}"
+          text run at (0,16) width 550: "\x{5168}\x{4E16}\x{754C}\x{6578}\x{5343}\x{842C} iPhone \x{548C} iPod touch \x{4F7F}\x{7528}\x{8005}\x{4EE4}\x{4EBA}\x{7A31}\x{7FA8}\x{7684}\x{4E3B}\x{8981}\x{539F}\x{56E0}\x{3002}iPhone SDK \x{5275}\x{9020}\x{4E86}\x{7B2C}\x{4E00}\x{500B}\x{512A}\x{7570}\x{7684}\x{884C}\x{52D5}\x{61C9}"
+          text run at (0,32) width 319: "\x{7528}\x{7A0B}\x{5F0F}\x{5E73}\x{53F0}\x{FF0C}\x{5BA2}\x{6236}\x{4E5F}\x{975E}\x{5E38}\x{559C}\x{611B}\x{958B}\x{767C}\x{4EBA}\x{54E1}\x{6240}\x{5275}\x{4F5C}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{3002}\x{300D}"
+      LayoutNGBlockFlow {P} at (0,136) size 550x48
+        LayoutText {#text} at (0,0) size 550x47
+          text run at (0,0) width 550: "EA Mobile \x{7684} Worldwide Studios \x{526F}\x{7E3D}\x{88C1} Travis Boatman \x{6307}\x{51FA}\x{FF1A}\x{300C}App Store \x{4E0D}\x{50C5}\x{5FB9}\x{5E95}\x{6539}\x{8B8A}\x{4E86}\x{884C}\x{52D5}\x{904A}\x{6232}\x{7522}\x{696D}\x{7684}"
+          text run at (0,16) width 550: "\x{751F}\x{614B}\x{FF0C}\x{800C}\x{4E14}\x{9084}\x{5728}\x{6301}\x{7E8C}\x{6F14}\x{9032}\x{3002}\x{6709}\x{4E86}\x{5168}\x{7403} 5 \x{5343}\x{591A}\x{842C}\x{7684} iPhone \x{548C} iPod touch \x{5BA2}\x{6236}\x{70BA}\x{57FA}\x{790E}\x{FF0C}App Store \x{8B93}\x{6211}\x{5011}\x{80FD}\x{5920}\x{958B}"
+          text run at (0,32) width 233: "\x{767C}\x{53D7}\x{5230}\x{5EE3}\x{5927}\x{7684}\x{5BA2}\x{6236}\x{559C}\x{611B}\x{7684}\x{9AD8}\x{54C1}\x{8CEA} EA \x{904A}\x{6232}\x{3002}\x{300D}"
+      LayoutNGBlockFlow {P} at (0,196) size 550x48
+        LayoutText {#text} at (0,0) size 550x47
+          text run at (0,0) width 550: "Smule \x{7684}\x{57F7}\x{884C}\x{9577} Jeff Smith \x{8868}\x{793A}\x{FF1A}\x{300C}\x{6211}\x{5011}\x{7684} I Am T-Pain \x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{53D7}\x{5230}\x{5168}\x{7403}\x{5BA2}\x{6236}\x{7684}\x{71B1}\x{70C8}\x{8FF4}\x{97FF}\x{FF0C}\x{6BCF}\x{65E5}\x{8D85}\x{904E}"
+          text run at (0,16) width 550: "10,000 \x{6B21}\x{7684}\x{4E0B}\x{8F09}\x{9060}\x{9060}\x{8D85}\x{8D8A}\x{6211}\x{5011}\x{7684}\x{9810}\x{671F}\x{3002}App Store \x{7D66}\x{4E86}\x{6211}\x{5011}\x{4E00}\x{500B}\x{7368}\x{7279}\x{7684}\x{5546}\x{6A5F}\x{FF0C}\x{8B93}\x{6211}\x{5011}\x{958B}\x{5275}\x{4E00}\x{500B}\x{975E}\x{5E38}\x{6210}\x{529F}\x{7684}"
+          text run at (0,32) width 180: "\x{4E8B}\x{696D}\x{FF0C}\x{76F8}\x{4FE1}\x{672A}\x{4F86}\x{5C07}\x{66F4}\x{4EE4}\x{4EBA}\x{671F}\x{5F85}\x{3002}\x{300D}"
+      LayoutNGBlockFlow {P} at (0,256) size 550x48
+        LayoutText {#text} at (0,0) size 550x47
+          text run at (0,0) width 550: "\x{860B}\x{679C}\x{4E5F}\x{6301}\x{7E8C}\x{958B}\x{767C}\x{65B0}\x{7684}\x{529F}\x{80FD}\x{4F86}\x{63D0}\x{5347}\x{641C}\x{5C0B}\x{8207}\x{63A2}\x{7D22}\x{7684}\x{4FBF}\x{5229}\x{6027}\x{FF0C}\x{5305}\x{62EC}\x{FF1A}Genius for Apps\x{3001}App Store Essentials\x{3001}\x{5B50}"
+          text run at (0,16) width 550: "\x{5206}\x{985E}\x{6E05}\x{55AE}\x{FF0C}\x{4EE5}\x{53CA}\x{66F4}\x{8C50}\x{5BCC}\x{800C}\x{5BF6}\x{8CB4}\x{7684}\x{5BA2}\x{6236}\x{8A55}\x{8AD6}\x{3002}\x{96A8}\x{8457}\x{65B0}\x{7248}\x{7684} iTunes\x{AE} 9 \x{63A8}\x{51FA}\x{FF0C}\x{73FE}\x{5728}\x{60A8}\x{53EF}\x{4EE5}\x{8F15}\x{8F15}\x{9B06}\x{9B06}\x{76F4}\x{63A5}\x{5728}"
+          text run at (0,32) width 524: "iTunes \x{7576}\x{4E2D}\x{6574}\x{7406}\x{60A8}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{FF0C}\x{4E00}\x{65E6}\x{540C}\x{6B65}\x{4E4B}\x{5F8C}\x{FF0C}iPhone \x{6216} iPod touch \x{5C31}\x{6703}\x{81EA}\x{52D5}\x{51FA}\x{73FE}\x{60A8}\x{6240}\x{5B89}\x{6392}\x{7684}\x{914D}\x{7F6E}\x{3002}"
+      LayoutNGBlockFlow {P} at (0,316) size 550x96
+        LayoutText {#text} at (0,0) size 550x95
+          text run at (0,0) width 550: "\x{4ECA}\x{5E74}\x{590F}\x{5929}\x{63A8}\x{51FA}\x{7684} iPhone OS 3.0 \x{70BA} iPhone \x{548C} iPod touch \x{4F7F}\x{7528}\x{8005}\x{63D0}\x{4F9B}\x{4E86} 100 \x{591A}\x{7A2E}\x{5168}\x{65B0}\x{7684}\x{529F}\x{80FD}\x{FF0C}\x{5305}\x{62EC}\x{FF1A}\x{526A}\x{8CBC}\x{8207}"
+          text run at (0,16) width 550: "\x{62F7}\x{8C9D}\x{FF1B}MMS\x{FF1B}\x{65B0}\x{589E}\x{6A6B}\x{5411}\x{6AA2}\x{8996}\x{7684} Mail\x{3001}Text \x{548C} Notes\x{FF1B}\x{7ACB}\x{9AD4}\x{8072} Bluetooth\x{FF1B}\x{6416}\x{4E00}\x{6416}\x{5C31}\x{96A8}\x{6A5F}\x{64AD}\x{653E}\x{FF1B}\x{96FB}\x{8996}\x{7BC0}\x{76EE}\x{5206}"
+          text run at (0,32) width 550: "\x{7D1A}\x{4FDD}\x{8B77}\x{63A7}\x{5236}\x{FF1B}\x{81EA}\x{52D5}\x{767B}\x{5165} Wi-Fi \x{71B1}\x{9EDE}\x{FF1B}\x{4EE5}\x{53CA} Push Notification \x{670D}\x{52D9}\x{901A}\x{77E5}\x{7B49}\x{7B49}\x{3002}\x{9019}\x{4E9B}\x{65B0}\x{589E}\x{529F}\x{80FD}\x{53D7}\x{5230}\x{5BA2}\x{6236}\x{7684}\x{5EE3}\x{5927}\x{6B61}"
+          text run at (0,48) width 550: "\x{8FCE}\x{FF0C}\x{622A}\x{81F3}\x{76EE}\x{524D}\x{70BA}\x{6B62}\x{FF0C}\x{5DF2}\x{7D93}\x{6709}\x{8D85}\x{904E} 20 \x{5104}\x{6B21}\x{7684} Push Notification \x{670D}\x{52D9}\x{901A}\x{77E5}\x{767C}\x{9001}\x{81F3} App Store \x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{3002}\x{6B64}\x{5916}\x{FF0C}"
+          text run at (0,64) width 550: "\x{6700}\x{8FD1}\x{63A8}\x{51FA}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{5167}\x{8CFC}\x{8CB7}\x{6A5F}\x{5236} (In-App Purchase)\x{FF0C}\x{70BA}\x{9818}\x{5148}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{958B}\x{767C}\x{5EE0}\x{5546}\x{63D0}\x{4F9B}\x{4E86}\x{4E00}\x{7A2E}\x{65B9}\x{5F0F}\x{8B93}\x{5BA2}\x{6236}\x{76F4}\x{63A5}"
+          text run at (0,80) width 254: "\x{5F9E}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{7576}\x{4E2D}\x{8CFC}\x{8CB7}\x{5167}\x{5BB9}\x{3001}\x{8A02}\x{95B1}\x{9805}\x{76EE}\x{53CA}\x{6578}\x{4F4D}\x{670D}\x{52D9}\x{3002}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-ideograph-simple-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-ideograph-simple-expected.txt
new file mode 100644
index 0000000..4ca90146
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-ideograph-simple-expected.txt
@@ -0,0 +1,39 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x432
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x432
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x412
+      LayoutNGBlockFlow {P} at (0,0) size 550x64
+        LayoutText {#text} at (0,0) size 550x63
+          text run at (0,0) width 550: "\x{3010}2009 \x{5E74} 11 \x{6708} 4 \x{65E5}\x{7F8E}\x{570B}\x{52A0}\x{5DDE} Cupertino \x{8A0A}\x{3011}\x{860B}\x{679C}\x{4ECA}\x{5929}\x{5BA3}\x{4F48}\x{FF0C}\x{5168}\x{4E16}\x{754C}\x{6700}\x{5927}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{5546}\x{5E97} App Store\x{FF0C}\x{76EE}\x{524D}"
+          text run at (0,16) width 550: "\x{5DF2}\x{64C1}\x{6709} 100,000 \x{591A}\x{7A2E}\x{4F86}\x{81EA}\x{5168}\x{7403}\x{958B}\x{767C}\x{4EBA}\x{54E1}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{3002}\x{5168}\x{4E16}\x{754C} 77 \x{500B}\x{570B}\x{5BB6}\x{7684} iPhone\x{AE} \x{8207} iPod touch\x{AE} \x{7528}\x{6236}\x{64C1}\x{6709}"
+          text run at (0,32) width 550: "20 \x{500B}\x{985E}\x{5225}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{53EF}\x{4F9B}\x{9078}\x{64C7}\x{FF0C}\x{5305}\x{62EC}\x{FF1A}\x{904A}\x{6232}\x{3001}\x{5546}\x{7528}\x{3001}\x{65B0}\x{805E}\x{3001}\x{904B}\x{52D5}\x{3001}\x{91AB}\x{7642}\x{3001}\x{53C3}\x{8003}\x{66F8}\x{7C4D}\x{3001}\x{65C5}\x{904A}\x{7B49}\x{7B49}\x{3002}\x{622A}\x{81F3}\x{76EE}"
+          text run at (0,48) width 478: "\x{524D}\x{70BA}\x{6B62}\x{FF0C}App Store \x{4F7F}\x{7528}\x{8005}\x{4E0B}\x{8F09}\x{6B21}\x{6578}\x{5DF2}\x{8D85}\x{904E} 20 \x{5104}\x{6B21}\x{FF0C}\x{662F}\x{76EE}\x{524D}\x{5168}\x{7403}\x{6700}\x{53D7}\x{6B61}\x{8FCE}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{5546}\x{5E97}\x{3002}"
+      LayoutNGBlockFlow {P} at (0,76) size 550x48
+        LayoutText {#text} at (0,0) size 550x47
+          text run at (0,0) width 550: "\x{860B}\x{679C}\x{5168}\x{7403}\x{7522}\x{54C1}\x{884C}\x{92B7}\x{8CC7}\x{6DF1}\x{526F}\x{7E3D}\x{88C1} Philip Schiller \x{8868}\x{793A}\x{FF1A}\x{300C}\x{63D0}\x{4F9B} 100,000 \x{591A}\x{7A2E}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{53EF}\x{4F9B}\x{9078}\x{64C7}\x{7684} App Store\x{FF0C}\x{662F}"
+          text run at (0,16) width 550: "\x{5168}\x{4E16}\x{754C}\x{6578}\x{5343}\x{842C} iPhone \x{548C} iPod touch \x{4F7F}\x{7528}\x{8005}\x{4EE4}\x{4EBA}\x{7A31}\x{7FA8}\x{7684}\x{4E3B}\x{8981}\x{539F}\x{56E0}\x{3002}iPhone SDK \x{5275}\x{9020}\x{4E86}\x{7B2C}\x{4E00}\x{500B}\x{512A}\x{7570}\x{7684}\x{884C}\x{52D5}\x{61C9}"
+          text run at (0,32) width 319: "\x{7528}\x{7A0B}\x{5F0F}\x{5E73}\x{53F0}\x{FF0C}\x{5BA2}\x{6236}\x{4E5F}\x{975E}\x{5E38}\x{559C}\x{611B}\x{958B}\x{767C}\x{4EBA}\x{54E1}\x{6240}\x{5275}\x{4F5C}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{3002}\x{300D}"
+      LayoutNGBlockFlow {P} at (0,136) size 550x48
+        LayoutText {#text} at (0,0) size 550x47
+          text run at (0,0) width 550: "EA Mobile \x{7684} Worldwide Studios \x{526F}\x{7E3D}\x{88C1} Travis Boatman \x{6307}\x{51FA}\x{FF1A}\x{300C}App Store \x{4E0D}\x{50C5}\x{5FB9}\x{5E95}\x{6539}\x{8B8A}\x{4E86}\x{884C}\x{52D5}\x{904A}\x{6232}\x{7522}\x{696D}\x{7684}"
+          text run at (0,16) width 550: "\x{751F}\x{614B}\x{FF0C}\x{800C}\x{4E14}\x{9084}\x{5728}\x{6301}\x{7E8C}\x{6F14}\x{9032}\x{3002}\x{6709}\x{4E86}\x{5168}\x{7403} 5 \x{5343}\x{591A}\x{842C}\x{7684} iPhone \x{548C} iPod touch \x{5BA2}\x{6236}\x{70BA}\x{57FA}\x{790E}\x{FF0C}App Store \x{8B93}\x{6211}\x{5011}\x{80FD}\x{5920}\x{958B}"
+          text run at (0,32) width 233: "\x{767C}\x{53D7}\x{5230}\x{5EE3}\x{5927}\x{7684}\x{5BA2}\x{6236}\x{559C}\x{611B}\x{7684}\x{9AD8}\x{54C1}\x{8CEA} EA \x{904A}\x{6232}\x{3002}\x{300D}"
+      LayoutNGBlockFlow {P} at (0,196) size 550x48
+        LayoutText {#text} at (0,0) size 550x47
+          text run at (0,0) width 550: "Smule \x{7684}\x{57F7}\x{884C}\x{9577} Jeff Smith \x{8868}\x{793A}\x{FF1A}\x{300C}\x{6211}\x{5011}\x{7684} I Am T-Pain \x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{53D7}\x{5230}\x{5168}\x{7403}\x{5BA2}\x{6236}\x{7684}\x{71B1}\x{70C8}\x{8FF4}\x{97FF}\x{FF0C}\x{6BCF}\x{65E5}\x{8D85}\x{904E}"
+          text run at (0,16) width 550: "10,000 \x{6B21}\x{7684}\x{4E0B}\x{8F09}\x{9060}\x{9060}\x{8D85}\x{8D8A}\x{6211}\x{5011}\x{7684}\x{9810}\x{671F}\x{3002}App Store \x{7D66}\x{4E86}\x{6211}\x{5011}\x{4E00}\x{500B}\x{7368}\x{7279}\x{7684}\x{5546}\x{6A5F}\x{FF0C}\x{8B93}\x{6211}\x{5011}\x{958B}\x{5275}\x{4E00}\x{500B}\x{975E}\x{5E38}\x{6210}\x{529F}\x{7684}"
+          text run at (0,32) width 180: "\x{4E8B}\x{696D}\x{FF0C}\x{76F8}\x{4FE1}\x{672A}\x{4F86}\x{5C07}\x{66F4}\x{4EE4}\x{4EBA}\x{671F}\x{5F85}\x{3002}\x{300D}"
+      LayoutNGBlockFlow {P} at (0,256) size 550x48
+        LayoutText {#text} at (0,0) size 550x47
+          text run at (0,0) width 550: "\x{860B}\x{679C}\x{4E5F}\x{6301}\x{7E8C}\x{958B}\x{767C}\x{65B0}\x{7684}\x{529F}\x{80FD}\x{4F86}\x{63D0}\x{5347}\x{641C}\x{5C0B}\x{8207}\x{63A2}\x{7D22}\x{7684}\x{4FBF}\x{5229}\x{6027}\x{FF0C}\x{5305}\x{62EC}\x{FF1A}Genius for Apps\x{3001}App Store Essentials\x{3001}\x{5B50}"
+          text run at (0,16) width 550: "\x{5206}\x{985E}\x{6E05}\x{55AE}\x{FF0C}\x{4EE5}\x{53CA}\x{66F4}\x{8C50}\x{5BCC}\x{800C}\x{5BF6}\x{8CB4}\x{7684}\x{5BA2}\x{6236}\x{8A55}\x{8AD6}\x{3002}\x{96A8}\x{8457}\x{65B0}\x{7248}\x{7684} iTunes\x{AE} 9 \x{63A8}\x{51FA}\x{FF0C}\x{73FE}\x{5728}\x{60A8}\x{53EF}\x{4EE5}\x{8F15}\x{8F15}\x{9B06}\x{9B06}\x{76F4}\x{63A5}\x{5728}"
+          text run at (0,32) width 524: "iTunes \x{7576}\x{4E2D}\x{6574}\x{7406}\x{60A8}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{FF0C}\x{4E00}\x{65E6}\x{540C}\x{6B65}\x{4E4B}\x{5F8C}\x{FF0C}iPhone \x{6216} iPod touch \x{5C31}\x{6703}\x{81EA}\x{52D5}\x{51FA}\x{73FE}\x{60A8}\x{6240}\x{5B89}\x{6392}\x{7684}\x{914D}\x{7F6E}\x{3002}"
+      LayoutNGBlockFlow {P} at (0,316) size 550x96
+        LayoutText {#text} at (0,0) size 550x95
+          text run at (0,0) width 550: "\x{4ECA}\x{5E74}\x{590F}\x{5929}\x{63A8}\x{51FA}\x{7684} iPhone OS 3.0 \x{70BA} iPhone \x{548C} iPod touch \x{4F7F}\x{7528}\x{8005}\x{63D0}\x{4F9B}\x{4E86} 100 \x{591A}\x{7A2E}\x{5168}\x{65B0}\x{7684}\x{529F}\x{80FD}\x{FF0C}\x{5305}\x{62EC}\x{FF1A}\x{526A}\x{8CBC}\x{8207}"
+          text run at (0,16) width 550: "\x{62F7}\x{8C9D}\x{FF1B}MMS\x{FF1B}\x{65B0}\x{589E}\x{6A6B}\x{5411}\x{6AA2}\x{8996}\x{7684} Mail\x{3001}Text \x{548C} Notes\x{FF1B}\x{7ACB}\x{9AD4}\x{8072} Bluetooth\x{FF1B}\x{6416}\x{4E00}\x{6416}\x{5C31}\x{96A8}\x{6A5F}\x{64AD}\x{653E}\x{FF1B}\x{96FB}\x{8996}\x{7BC0}\x{76EE}\x{5206}"
+          text run at (0,32) width 550: "\x{7D1A}\x{4FDD}\x{8B77}\x{63A7}\x{5236}\x{FF1B}\x{81EA}\x{52D5}\x{767B}\x{5165} Wi-Fi \x{71B1}\x{9EDE}\x{FF1B}\x{4EE5}\x{53CA} Push Notification \x{670D}\x{52D9}\x{901A}\x{77E5}\x{7B49}\x{7B49}\x{3002}\x{9019}\x{4E9B}\x{65B0}\x{589E}\x{529F}\x{80FD}\x{53D7}\x{5230}\x{5BA2}\x{6236}\x{7684}\x{5EE3}\x{5927}\x{6B61}"
+          text run at (0,48) width 550: "\x{8FCE}\x{FF0C}\x{622A}\x{81F3}\x{76EE}\x{524D}\x{70BA}\x{6B62}\x{FF0C}\x{5DF2}\x{7D93}\x{6709}\x{8D85}\x{904E} 20 \x{5104}\x{6B21}\x{7684} Push Notification \x{670D}\x{52D9}\x{901A}\x{77E5}\x{767C}\x{9001}\x{81F3} App Store \x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{3002}\x{6B64}\x{5916}\x{FF0C}"
+          text run at (0,64) width 550: "\x{6700}\x{8FD1}\x{63A8}\x{51FA}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{5167}\x{8CFC}\x{8CB7}\x{6A5F}\x{5236} (In-App Purchase)\x{FF0C}\x{70BA}\x{9818}\x{5148}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{958B}\x{767C}\x{5EE0}\x{5546}\x{63D0}\x{4F9B}\x{4E86}\x{4E00}\x{7A2E}\x{65B9}\x{5F0F}\x{8B93}\x{5BA2}\x{6236}\x{76F4}\x{63A5}"
+          text run at (0,80) width 254: "\x{5F9E}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{7576}\x{4E2D}\x{8CFC}\x{8CB7}\x{5167}\x{5BB9}\x{3001}\x{8A02}\x{95B1}\x{9805}\x{76EE}\x{53CA}\x{6578}\x{4F4D}\x{670D}\x{52D9}\x{3002}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-nbsp-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-nbsp-expected.png
new file mode 100644
index 0000000..1504cbe
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-nbsp-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-nbsp-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-nbsp-expected.txt
new file mode 100644
index 0000000..17b15b6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-nbsp-expected.txt
@@ -0,0 +1,19 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x222
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x222
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x206
+      LayoutNGBlockFlow {DIV} at (0,0) size 656x206 [border: (3px solid #0000FF)]
+        LayoutInline {SPAN} at (0,0) size 515x25
+          LayoutText {#text} at (3,15) size 358x25
+            text run at (3,15) width 358: "a b c d "
+        LayoutText {#text} at (360,15) size 651x75
+          text run at (360,15) width 294: "e f g h"
+          text run at (3,65) width 275: "xxxxxxxxxxx"
+        LayoutBR {BR} at (278,65) size 0x0
+        LayoutInline {SPAN} at (0,0) size 515x25
+          LayoutText {#text} at (3,115) size 358x25
+            text run at (3,115) width 358: "a b c d "
+        LayoutText {#text} at (360,115) size 651x75
+          text run at (360,115) width 294: "e f g h"
+          text run at (3,165) width 275: "xxxxxxxxxxx"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/atsui-kerning-and-ligatures-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/atsui-kerning-and-ligatures-expected.txt
new file mode 100644
index 0000000..fc443c1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/atsui-kerning-and-ligatures-expected.txt
@@ -0,0 +1,26 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x130
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x130
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x114
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 729x19
+          LayoutText {#text} at (51,0) size 729x19
+            text run at (51,0) width 729: "http://bugzilla.opendarwin.org/show_bug.cgi?id=6137 Disable kerning and some ligatures in the ATSUI code path"
+        LayoutText {#text} at (779,0) size 5x19
+          text run at (779,0) width 5: "."
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (0,0) size 708x19
+          text run at (0,0) width 708: "The word \x{201C}dolor\x{201D} below should be highlighted in its entirety. The highlight should not extend beyond that word."
+      LayoutNGBlockFlow {DIV} at (0,72) size 784x42
+        LayoutNGBlockFlow (anonymous) at (0,14) size 784x28
+          LayoutInline {SPAN} at (0,0) size 524x27
+            LayoutText {#text} at (0,0) size 524x27
+              text run at (0,0) width 524: "AVAVAVAVAVfififififififi Lorem ipsum dolor sit ame\x{300}t"
+          LayoutText {#text} at (0,0) size 0x0
+layer at (8,80) size 784x2 clip at (0,0) size 0x0
+  LayoutNGBlockFlow {HR} at (0,0) size 784x2 [border: (1px inset #EEEEEE)]
+selection start: position 37 of child 0 {#text} of child 3 {SPAN} of child 5 {DIV} of body
+selection end:   position 42 of child 0 {#text} of child 3 {SPAN} of child 5 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/justified-selection-at-edge-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/justified-selection-at-edge-expected.txt
new file mode 100644
index 0000000..e6d4afb2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/justified-selection-at-edge-expected.txt
@@ -0,0 +1,27 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x224
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x224
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x200
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 385x19
+          text run at (0,0) width 385: "Test for bug 13234, layout of selected justified text is broken."
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (0,0) size 251x19
+          text run at (0,0) width 251: "The two blue boxes should be identical."
+      LayoutNGBlockFlow {DIV} at (0,72) size 256x46 [border: (3px solid #0000FF)]
+        LayoutText {#text} at (3,3) size 190x19
+          text run at (3,3) width 190: "Lorem ipsum dolor si"
+        LayoutInline {SPAN} at (0,0) size 61x19 [color=#008000] [bgcolor=#FFFF00]
+          LayoutText {#text} at (192,3) size 61x19
+            text run at (192,3) width 61: "t amet,"
+        LayoutText {#text} at (3,23) size 173x19
+          text run at (3,23) width 173: "consectetuer adipiscing elit."
+      LayoutNGBlockFlow (anonymous) at (0,118) size 784x20
+        LayoutBR {BR} at (0,0) size 0x0
+      LayoutNGBlockFlow {P} at (0,154) size 256x46 [border: (3px solid #0000FF)]
+        LayoutText {#text} at (3,3) size 250x39
+          text run at (3,3) width 250: "Lorem ipsum dolor sit amet,"
+          text run at (3,23) width 173: "consectetuer adipiscing elit."
+selection start: position 20 of child 0 {#text} of child 8 {P} of body
+selection end:   position 27 of child 0 {#text} of child 8 {P} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/should-use-atsui-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/should-use-atsui-expected.txt
new file mode 100644
index 0000000..91cb82f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/should-use-atsui-expected.txt
@@ -0,0 +1,26 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x138
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x138
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x122
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 733x39
+          LayoutText {#text} at (51,0) size 733x39
+            text run at (51,0) width 682: "http://bugzilla.opendarwin.org/show_bug.cgi?id=6132 Incorrect selection highlighting for ATSUI text when"
+            text run at (0,20) width 176: "selected range is \"CG-safe\""
+        LayoutText {#text} at (176,20) size 4x19
+          text run at (176,20) width 4: "."
+      LayoutNGBlockFlow {P} at (0,56) size 784x20
+        LayoutText {#text} at (0,0) size 708x19
+          text run at (0,0) width 708: "The word \x{201C}dolor\x{201D} below should be highlighted in its entirety. The highlight should not extend beyond that word."
+      LayoutNGBlockFlow (anonymous) at (0,102) size 784x20
+        LayoutInline {SPAN} at (0,0) size 173x19
+          LayoutText {#text} at (0,0) size 173x19
+            text run at (0,0) width 173: "Lo\x{308}re\x{300}m ipsum dolor sit amet"
+        LayoutText {#text} at (0,0) size 0x0
+layer at (8,100) size 784x2 clip at (0,0) size 0x0
+  LayoutNGBlockFlow {HR} at (0,92) size 784x2 [border: (1px inset #EEEEEE)]
+selection start: position 14 of child 0 {#text} of child 7 {SPAN} of body
+selection end:   position 19 of child 0 {#text} of child 7 {SPAN} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/wbr-styled-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/wbr-styled-expected.txt
new file mode 100644
index 0000000..b048cf94
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/wbr-styled-expected.txt
@@ -0,0 +1,37 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x116
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x92
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 90x19
+          text run at (0,0) width 90: "This tests that "
+        LayoutInline {TT} at (0,0) size 24x16
+          LayoutText {#text} at (90,3) size 24x16
+            text run at (90,3) width 24: "WBR"
+        LayoutText {#text} at (114,0) size 300x19
+          text run at (114,0) width 300: " elements cannot be styled and that setting their "
+        LayoutInline {TT} at (0,0) size 64x16
+          LayoutText {#text} at (414,3) size 64x16
+            text run at (414,3) width 64: "position"
+        LayoutText {#text} at (478,0) size 20x19
+          text run at (478,0) width 20: " to "
+        LayoutInline {TT} at (0,0) size 64x16
+          LayoutText {#text} at (498,3) size 64x16
+            text run at (498,3) width 64: "absolute"
+        LayoutText {#text} at (562,0) size 151x19
+          text run at (562,0) width 151: " does not crash WebKit."
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (0,0) size 126x19
+          text run at (0,0) width 126: "There should be no "
+        LayoutWordBreak {WBR} at (126,0) size 0x0
+          text run at (126,0) width 0: "\x{200B}"
+        LayoutText {#text} at (126,0) size 97x19
+          text run at (126,0) width 97: "red on this line."
+      LayoutNGBlockFlow {P} at (0,72) size 784x20
+        LayoutText {#text} at (0,0) size 124x19
+          text run at (0,0) width 124: "No crashing, please"
+        LayoutWordBreak {WBR} at (124,0) size 0x0
+          text run at (124,0) width 0: "\x{200B}"
+        LayoutText {#text} at (124,0) size 4x19
+          text run at (124,0) width 4: "."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/word-break-soft-hyphen-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/word-break-soft-hyphen-expected.txt
new file mode 100644
index 0000000..87fff79
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/word-break-soft-hyphen-expected.txt
@@ -0,0 +1,24 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x100
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x100
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x76
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 779x39
+          LayoutInline {A} at (0,0) size 302x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 302x19
+              text run at (51,0) width 302: "http://bugs.webkit.org/show_bug.cgi?id=15367"
+          LayoutText {#text} at (352,0) size 779x39
+            text run at (352,0) width 427: " Assertion failure inspecting a document including soft hyphen code"
+            text run at (0,20) width 41: "(0xad)"
+        LayoutText {#text} at (41,20) size 4x19
+          text run at (41,20) width 4: "."
+      LayoutNGBlockFlow {P} at (0,56) size 784x20
+        LayoutText {#text} at (0,0) size 489x19
+          text run at (0,0) width 489: "The following text should not wrap and the border should fit tightly around it."
+layer at (8,100) size 115x26
+  LayoutNGBlockFlow (positioned) {DIV} at (8,100) size 114.89x26 [border: (3px solid #000000)]
+    LayoutText {#text} at (3,3) size 109x19
+      text run at (3,3) width 109: "Two soft\x{AD}hyp\x{AD}hens"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/fast/frames/frame-set-scaling-rotate-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/fast/frames/frame-set-scaling-rotate-expected.png
index 4ac4af6a..b1147ca 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/fast/frames/frame-set-scaling-rotate-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/fast/frames/frame-set-scaling-rotate-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/fast/frames/frame-set-scaling-skew-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/fast/frames/frame-set-scaling-skew-expected.png
index fdbac98d..95fa508 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/fast/frames/frame-set-scaling-skew-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/fast/frames/frame-set-scaling-skew-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/fast/sub-pixel/should-not-repaint-subpixel-composited-layer-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/fast/sub-pixel/should-not-repaint-subpixel-composited-layer-expected.txt
index d2e1e11..761cbdf 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/fast/sub-pixel/should-not-repaint-subpixel-composited-layer-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/fast/sub-pixel/should-not-repaint-subpixel-composited-layer-expected.txt
@@ -4,6 +4,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -38,6 +48,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -72,6 +92,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -106,6 +136,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -140,6 +180,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -174,6 +224,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -208,6 +268,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -242,6 +312,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -276,6 +356,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -310,6 +400,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -344,6 +444,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -378,6 +488,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -412,6 +532,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -446,6 +576,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -480,6 +620,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -514,6 +664,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -548,6 +708,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -582,6 +752,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -616,6 +796,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -650,6 +840,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
@@ -684,6 +884,16 @@
     {
       "name": "LayoutView #document",
       "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/threaded/printing/fixed-positioned-headers-and-footers-clipped-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/threaded/printing/fixed-positioned-headers-and-footers-clipped-expected.png
index 38d3235..f1c9fa2 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/threaded/printing/fixed-positioned-headers-and-footers-clipped-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/threaded/printing/fixed-positioned-headers-and-footers-clipped-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/acquire.html b/third_party/WebKit/LayoutTests/http/tests/locks/acquire.html
index 80b6580..3dd655f7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/locks/acquire.html
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/acquire.html
@@ -4,51 +4,66 @@
 <link rel=help href="https://github.com/inexorabletash/web-locks">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="resources/helpers.js"></script>
 <script>
 'use strict';
 
 promise_test(async t => {
+  const res = uniqueName(t);
   await promise_rejects(t, new TypeError(), navigator.locks.acquire());
-  await promise_rejects(t, new TypeError(), navigator.locks.acquire('name'));
+  await promise_rejects(t, new TypeError(), navigator.locks.acquire(res));
 }, 'navigator.locks.acquire requires a name and a callback');
 
 promise_test(async t => {
+  const res = uniqueName(t);
   await promise_rejects(
     t, new TypeError(),
-    navigator.locks.acquire('name', {mode: 'foo'}, lock => {}));
+    navigator.locks.acquire(res, {mode: 'foo'}, lock => {}));
   await promise_rejects(
     t, new TypeError(),
-    navigator.locks.acquire('name', {mode: null }, lock => {}));
+    navigator.locks.acquire(res, {mode: null }, lock => {}));
   assert_equals(await navigator.locks.acquire(
-    'name', {mode: 'exclusive'}, lock => lock.mode), 'exclusive',
+    res, {mode: 'exclusive'}, lock => lock.mode), 'exclusive',
                 'mode is exclusive');
   assert_equals(await navigator.locks.acquire(
-    'name', {mode: 'shared'}, lock => lock.mode), 'shared',
+    res, {mode: 'shared'}, lock => lock.mode), 'shared',
                 'mode is shared');
 }, 'mode must be "shared" or "exclusive"');
 
 promise_test(async t => {
+  const res = uniqueName(t);
   await promise_rejects(
-    t, new TypeError(), navigator.locks.acquire('name', undefined));
+    t, 'NotSupportedError',
+    navigator.locks.acquire(
+      res, {steal: true, ifAvailable: true}, lock => {}),
+    "A NotSupportedError should be thrown if both " +
+    "'steal' and 'ifAvailable' are specified.");
+}, "The 'steal' and 'ifAvailable' options are mutually exclusive");
+
+promise_test(async t => {
+  const res = uniqueName(t);
   await promise_rejects(
-    t, new TypeError(), navigator.locks.acquire('name', null));
+    t, new TypeError(), navigator.locks.acquire(res, undefined));
   await promise_rejects(
-    t, new TypeError(), navigator.locks.acquire('name', 123));
+    t, new TypeError(), navigator.locks.acquire(res, null));
   await promise_rejects(
-    t, new TypeError(), navigator.locks.acquire('name', 'abc'));
+    t, new TypeError(), navigator.locks.acquire(res, 123));
   await promise_rejects(
-    t, new TypeError(), navigator.locks.acquire('name', []));
+    t, new TypeError(), navigator.locks.acquire(res, 'abc'));
   await promise_rejects(
-    t, new TypeError(), navigator.locks.acquire('name', {}));
+    t, new TypeError(), navigator.locks.acquire(res, []));
   await promise_rejects(
-    t, new TypeError(), navigator.locks.acquire('name', new Promise(r => {})));
+    t, new TypeError(), navigator.locks.acquire(res, {}));
+  await promise_rejects(
+    t, new TypeError(), navigator.locks.acquire(res, new Promise(r => {})));
 }, 'callback must be a function');
 
 promise_test(async t => {
+  const res = uniqueName(t);
   let release;
   const promise = new Promise(r => { release = r; });
 
-  let returned = navigator.locks.acquire('name', lock => { return promise; });
+  let returned = navigator.locks.acquire(res, lock => { return promise; });
 
   const order = [];
 
@@ -65,8 +80,9 @@
    ' lock is released');
 
 promise_test(async t => {
+  const res = uniqueName(t);
   const test_error = {name: 'test'};
-  const p = navigator.locks.acquire('resource', lock => {
+  const p = navigator.locks.acquire(res, lock => {
     throw test_error;
   });
   assert_equals(Promise.resolve(p), p, 'acquire() result is a Promise');
@@ -74,8 +90,9 @@
 }, 'Returned Promise rejects if callback throws synchronously');
 
 promise_test(async t => {
+  const res = uniqueName(t);
   const test_error = {name: 'test'};
-  const p = navigator.locks.acquire('resource', async lock => {
+  const p = navigator.locks.acquire(res, async lock => {
     throw test_error;
   });
   assert_equals(Promise.resolve(p), p, 'acquire() result is a Promise');
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/held.html b/third_party/WebKit/LayoutTests/http/tests/locks/held.html
index 3c12668..9a1d888 100644
--- a/third_party/WebKit/LayoutTests/http/tests/locks/held.html
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/held.html
@@ -4,6 +4,7 @@
 <link rel=help href="https://github.com/inexorabletash/web-locks">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="resources/helpers.js"></script>
 <script>
 'use strict';
 
@@ -13,12 +14,14 @@
 function snooze(t, ms) { return new Promise(r => t.step_timeout(r, ms)); }
 
 promise_test(async t => {
-  const p = navigator.locks.acquire('resource', lock => 123);
+  const res = uniqueName(t);
+  const p = navigator.locks.acquire(res, lock => 123);
   assert_equals(Promise.resolve(p), p, 'acquire() result is a Promise');
   assert_equals(await p, 123, 'promise resolves to the returned value');
 }, 'callback\'s result is promisified if not async');
 
 promise_test(async t => {
+  const res = uniqueName(t);
   // Resolved when the lock is granted.
   let granted;
   const lock_granted_promise = new Promise(r => { granted = r; });
@@ -29,7 +32,7 @@
 
   const order = [];
 
-  navigator.locks.acquire('resource', lock => {
+  navigator.locks.acquire(res, lock => {
     granted(lock);
     return lock_release_promise;
   });
@@ -40,7 +43,7 @@
       order.push('1st lock released');
       resolve();
     }),
-    navigator.locks.acquire('resource', () => {
+    navigator.locks.acquire(res, () => {
       order.push('2nd lock granted');
     })
   ]);
@@ -49,6 +52,7 @@
 }, 'lock is held until callback\'s returned promise resolves');
 
 promise_test(async t => {
+  const res = uniqueName(t);
   // Resolved when the lock is granted.
   let granted;
   const lock_granted_promise = new Promise(r => { granted = r; });
@@ -59,7 +63,7 @@
 
   const order = [];
 
-  navigator.locks.acquire('resource', lock => {
+  navigator.locks.acquire(res, lock => {
     granted(lock);
     return lock_release_promise;
   });
@@ -70,7 +74,7 @@
       order.push('reject');
       reject(new Error('this uncaught rejection is expected'));
     }),
-    navigator.locks.acquire('resource', () => {
+    navigator.locks.acquire(res, () => {
       order.push('2nd lock granted');
     })
   ]);
@@ -78,4 +82,16 @@
   assert_array_equals(order, ['reject', '2nd lock granted']);
 }, 'lock is held until callback\'s returned promise rejects');
 
+promise_test(async t => {
+  const res = uniqueName(t);
+  let callback_called = false;
+  await navigator.locks.acquire(res, async lock => {
+    await navigator.locks.acquire(res, {ifAvailable: true}, lock => {
+      callback_called = true;
+      assert_equals(lock, null, 'lock request should fail if held');
+    });
+  });
+  assert_true(callback_called, 'callback should have executed');
+}, 'held lock prevents the same client from acquiring it');
+
 </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/steal.html b/third_party/WebKit/LayoutTests/http/tests/locks/steal.html
new file mode 100644
index 0000000..f884c69
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/steal.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: steal option</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/helpers.js"></script>
+<script>
+'use strict';
+
+const never_settled = new Promise(resolve => { /* never */ });
+
+promise_test(async t => {
+  const res = uniqueName(t);
+  let callback_called = false;
+  await navigator.locks.acquire(res, {steal: true}, lock => {
+    callback_called = true;
+    assert_not_equals(lock, null, 'Lock should be granted');
+  });
+  assert_true(callback_called, 'Callback should be called');
+}, 'Lock available');
+
+promise_test(async t => {
+  const res = uniqueName(t);
+  let callback_called = false;
+
+  // Grab and hold the lock.
+  navigator.locks.acquire(res, lock => never_settled).catch(_ => {});
+
+  // Steal it.
+  await navigator.locks.acquire(res, {steal: true}, lock => {
+    callback_called = true;
+    assert_not_equals(lock, null, 'Lock should be granted');
+  });
+
+  assert_true(callback_called, 'Callback should be called');
+}, 'Lock not available');
+
+promise_test(async t => {
+  const res = uniqueName(t);
+
+  // Grab and hold the lock.
+  const promise = navigator.locks.acquire(res, lock => never_settled);
+  const assertion = promise_rejects(
+    t, 'AbortError', promise, `Initial request's promise should reject`);
+
+  // Steal it.
+  await navigator.locks.acquire(res, {steal: true}, lock => {});
+
+  await assertion;
+
+}, `Broken lock's release promise rejects`);
+
+promise_test(async t => {
+  const res = uniqueName(t);
+
+  // Grab and hold the lock.
+  navigator.locks.acquire(res, lock => never_settled).catch(_ => {});
+
+  // Make a request for it.
+  let request_granted = false;
+  const promise = navigator.locks.acquire(res, lock => {
+    request_granted = true;
+  });
+
+  // Steal it.
+  await navigator.locks.acquire(res, {steal: true}, lock => {
+    assert_false(request_granted, 'Steal should override request');
+  });
+
+  await promise;
+  assert_true(request_granted, 'Request should eventually be granted');
+
+}, `Requested lock's release promise is deferred`);
+
+promise_test(async t => {
+  const res = uniqueName(t);
+
+  // Grab and hold the lock.
+  navigator.locks.acquire(res, lock => never_settled).catch(_ => {});
+
+  // Steal it.
+  let saw_abort = false;
+  const first_steal = navigator.locks.acquire(
+    res, {steal: true}, lock => never_settled).catch(error => {
+      saw_abort = true;
+    });
+
+  // Steal it again.
+  await navigator.locks.acquire(res, {steal: true}, lock => {});
+
+  await first_steal;
+  assert_true(saw_abort, 'First steal should have aborted');
+
+}, 'Last caller wins');
+
+promise_test(async t => {
+  const res = uniqueName(t);
+  await promise_rejects(
+    t, 'NotSupportedError',
+    navigator.locks.acquire(res, {mode: 'shared', steal: true}, lock => {}),
+    'Request with mode=shared and steal=true should fail');
+
+}, 'Can only steal with exclusive locks');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/autoplay-crossorigin-expected.txt b/third_party/WebKit/LayoutTests/http/tests/webaudio/autoplay-crossorigin-expected.txt
index d45430cb..4a81a55 100644
--- a/third_party/WebKit/LayoutTests/http/tests/webaudio/autoplay-crossorigin-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/webaudio/autoplay-crossorigin-expected.txt
@@ -1,6 +1,5 @@
 CONSOLE WARNING: line 13: An AudioContext in a cross origin iframe must be created or resumed from a user gesture to enable audio output.
 CONSOLE WARNING: line 23: An AudioContext in a cross origin iframe must be created or resumed from a user gesture to enable audio output.
-CONSOLE WARNING: line 30: AudioParam value setter will become equivalent to AudioParam.setValueAtTime() in M65, around March 2018  See https://webaudio.github.io/web-audio-api/#dom-audioparam-value for more details.
 CONSOLE WARNING: line 36: An AudioContext in a cross origin iframe must be created or resumed from a user gesture to enable audio output.
 CONSOLE ERROR: line 2676: Uncaught Error: assert_equals: stateAfterClick expected "running" but got "suspended"
 This is a testharness.js-based test.
diff --git a/third_party/WebKit/LayoutTests/images/resources/crbug807324.png b/third_party/WebKit/LayoutTests/images/resources/crbug807324.png
new file mode 100644
index 0000000..f58aab7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/images/resources/crbug807324.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/css/clip-zooming-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/css/clip-zooming-expected.png
index e2fabf4..93f37025 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/css/clip-zooming-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/css/clip-zooming-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/editing/pasteboard/drop-text-without-selection-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/editing/pasteboard/drop-text-without-selection-expected.png
index 6531a32..df6d458a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/editing/pasteboard/drop-text-without-selection-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/editing/pasteboard/drop-text-without-selection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/hover-subselector-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/hover-subselector-expected.png
index e673934..02a1cbdb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/hover-subselector-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/hover-subselector-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/universal-hover-quirk-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/universal-hover-quirk-expected.png
index ec2fa5d..874b99a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/universal-hover-quirk-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/css/universal-hover-quirk-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/button-text-transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/button-text-transform-expected.png
index cd56603f..5ec552e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/button-text-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/button-text-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/control-clip-overflow-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/control-clip-overflow-expected.png
index ae3bed1..042ac8c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/control-clip-overflow-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/control-clip-overflow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/floating-textfield-relayout-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/floating-textfield-relayout-expected.png
index 5185d1d..3a37b542 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/floating-textfield-relayout-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/floating-textfield-relayout-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-rtl-expected.png
index 1cc9b4c..22e1f30 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-rtl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-rtl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/listbox-scrollbar-incremental-load-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/listbox-scrollbar-incremental-load-expected.png
index cff80a43..21381fd2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/listbox-scrollbar-incremental-load-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/listbox-scrollbar-incremental-load-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/menulist-clip-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/menulist-clip-expected.png
index 54d602df..c205d52 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/menulist-clip-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/menulist-clip-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/menulist-option-wrap-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/menulist-option-wrap-expected.png
index e5f0cde..eefbae8d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/menulist-option-wrap-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/menulist-option-wrap-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-change-listbox-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-change-listbox-size-expected.png
index 5995d990..02e7897 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-change-listbox-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-change-listbox-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-disabled-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-disabled-appearance-expected.png
index fbddc00d..9762544 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-disabled-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-disabled-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-item-background-clip-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-item-background-clip-expected.png
index 247ff48..3d0f902 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-item-background-clip-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-item-background-clip-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-writing-direction-natural-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-writing-direction-natural-expected.png
index c75e784..0b63e155 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-writing-direction-natural-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-writing-direction-natural-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/prepend-in-anonymous-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/prepend-in-anonymous-table-expected.png
index 62948c4..b98ca36 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/prepend-in-anonymous-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/prepend-in-anonymous-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/text-field-baseline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/text-field-baseline-expected.png
index 027b5ed..6082658 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/text-field-baseline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/text-field-baseline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/atsui-small-caps-punctuation-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/atsui-small-caps-punctuation-size-expected.png
index 23d7398..cbd73ab 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/atsui-small-caps-punctuation-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/atsui-small-caps-punctuation-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/atsui-spacing-features-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/atsui-spacing-features-expected.png
index b2977d9..22d1b8f4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/atsui-spacing-features-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/atsui-spacing-features-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/basic/015-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/basic/015-expected.png
index 98247e75..7564f733 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/basic/015-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/basic/015-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/break-word-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/break-word-expected.png
index 4b7216c..306f48c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/break-word-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/break-word-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/capitalize-empty-generated-string-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/capitalize-empty-generated-string-expected.png
index 140687e8..6428ee4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/capitalize-empty-generated-string-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/capitalize-empty-generated-string-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/capitalize-preserve-nbsp-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/capitalize-preserve-nbsp-expected.png
index 00a4e960..79e4b21 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/capitalize-preserve-nbsp-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/capitalize-preserve-nbsp-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/font-initial-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/font-initial-expected.png
index 9713672..ec8ae183 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/font-initial-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/font-initial-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/in-rendered-text-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/in-rendered-text-rtl-expected.png
index cea8b523..819c442 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/in-rendered-text-rtl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/in-rendered-text-rtl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/international/bidi-neutral-directionality-paragraph-start-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/international/bidi-neutral-directionality-paragraph-start-expected.png
index 4803c76..6554a1c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/international/bidi-neutral-directionality-paragraph-start-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/international/bidi-neutral-directionality-paragraph-start-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/international/rtl-white-space-pre-wrap-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/international/rtl-white-space-pre-wrap-expected.png
index 6b2ecf5..cc35d1c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/international/rtl-white-space-pre-wrap-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/international/rtl-white-space-pre-wrap-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/midword-break-after-breakable-char-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/midword-break-after-breakable-char-expected.png
index 8ae1f4c..d08eba4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/midword-break-after-breakable-char-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/midword-break-after-breakable-char-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/midword-break-hang-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/midword-break-hang-expected.png
index 8307b0b..f6df36d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/midword-break-hang-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/midword-break-hang-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/reset-emptyRun-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/reset-emptyRun-expected.png
index 751aee1..1f572b6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/reset-emptyRun-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/reset-emptyRun-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/atsui-partial-selection-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/atsui-partial-selection-expected.png
index d923049..114e09e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/atsui-partial-selection-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/atsui-partial-selection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/delete-hard-break-character-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/delete-hard-break-character-expected.png
index ebb8306..5b7f410e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/delete-hard-break-character-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/delete-hard-break-character-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/pre-wrap-overflow-selection-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/pre-wrap-overflow-selection-expected.png
index 3708416..a649892 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/pre-wrap-overflow-selection-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/pre-wrap-overflow-selection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/rtl-caret-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/rtl-caret-expected.png
index 8ccd632a..6bd755b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/rtl-caret-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/rtl-caret-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/selection-hard-linebreak-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/selection-hard-linebreak-expected.png
index be03961f..c2c9ea7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/selection-hard-linebreak-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/selection-hard-linebreak-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/wbr-in-pre-crash-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/wbr-in-pre-crash-expected.png
index 48371a6..98661b2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/wbr-in-pre-crash-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/wbr-in-pre-crash-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/whitespace/pre-wrap-last-char-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/whitespace/pre-wrap-last-char-expected.png
index a4b0971..ddf5f1d2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/whitespace/pre-wrap-last-char-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/whitespace/pre-wrap-last-char-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/whitespace/pre-wrap-spaces-after-newline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/whitespace/pre-wrap-spaces-after-newline-expected.png
index 5378ea0..35728dd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/whitespace/pre-wrap-spaces-after-newline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/whitespace/pre-wrap-spaces-after-newline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/word-break-run-rounding-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/word-break-run-rounding-expected.png
index e1c7fba..45a8614 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/word-break-run-rounding-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/word-break-run-rounding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/word-break-soft-hyphen-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/word-break-soft-hyphen-expected.png
index ab78ac71..73db959 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/word-break-soft-hyphen-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/word-break-soft-hyphen-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/word-space-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/word-space-expected.png
index c953cee4..9b4329a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/word-space-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/word-space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/editing/pasteboard/drop-text-without-selection-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/editing/pasteboard/drop-text-without-selection-expected.png
index b75667b..e6ee0b3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/editing/pasteboard/drop-text-without-selection-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/editing/pasteboard/drop-text-without-selection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/button-text-transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/button-text-transform-expected.png
index efd144c..f877946 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/button-text-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/button-text-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/button/button-inner-block-reuse-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/button/button-inner-block-reuse-expected.png
index 4e60160..4450ac53 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/button/button-inner-block-reuse-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/button/button-inner-block-reuse-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/control-clip-overflow-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/control-clip-overflow-expected.png
index 7645fa55..7fd968e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/control-clip-overflow-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/control-clip-overflow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/floating-textfield-relayout-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/floating-textfield-relayout-expected.png
index 4375b65..635a100 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/floating-textfield-relayout-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/floating-textfield-relayout-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.png
index e11f5c8..00999a4c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/listbox-scrollbar-incremental-load-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/listbox-scrollbar-incremental-load-expected.png
index 9ca05fb4..6def0eb5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/listbox-scrollbar-incremental-load-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/listbox-scrollbar-incremental-load-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/menulist-clip-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/menulist-clip-expected.png
index dd555e9..703bb7e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/menulist-clip-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/menulist-clip-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/menulist-option-wrap-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/menulist-option-wrap-expected.png
index 563f9769..2db48149 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/menulist-option-wrap-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/menulist-option-wrap-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-change-listbox-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-change-listbox-size-expected.png
index e42a8dff..38e09db 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-change-listbox-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-change-listbox-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-disabled-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-disabled-appearance-expected.png
index 7c2ee30..47246b84 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-disabled-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-disabled-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-item-background-clip-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-item-background-clip-expected.png
index 5abca10..b7e7654 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-item-background-clip-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-item-background-clip-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-writing-direction-natural-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-writing-direction-natural-expected.png
index 70d57c5..b5a3d96b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-writing-direction-natural-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-writing-direction-natural-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/text-field-baseline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/text-field-baseline-expected.png
index cfb0e34..2b129c2b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/text-field-baseline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/text-field-baseline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/button/button-inner-block-reuse-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/button/button-inner-block-reuse-expected.png
deleted file mode 100644
index 4e60160..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/button/button-inner-block-reuse-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-writing-direction-natural-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-writing-direction-natural-expected.png
deleted file mode 100644
index 70d57c5..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-writing-direction-natural-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/text-field-baseline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/text-field-baseline-expected.png
deleted file mode 100644
index cfb0e34..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/text-field-baseline-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/direct-image-compositing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/direct-image-compositing-expected.png
index c54d26ab..3675e49d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/compositing/direct-image-compositing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/direct-image-compositing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/generated-content-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/generated-content-expected.png
index 393d2e59..98f6a87d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/compositing/generated-content-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/generated-content-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/sibling-positioning-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/sibling-positioning-expected.png
index a1add91..8b34d9b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/compositing/sibling-positioning-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/sibling-positioning-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/pasteboard/drop-text-without-selection-expected.png b/third_party/WebKit/LayoutTests/platform/mac/editing/pasteboard/drop-text-without-selection-expected.png
index 1680595..e0afedf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/pasteboard/drop-text-without-selection-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/editing/pasteboard/drop-text-without-selection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/6476-expected.png b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/6476-expected.png
index 1fd920d3..4de1d84 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/6476-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/6476-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/click-start-of-line-expected.png b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/click-start-of-line-expected.png
index c6409dabb..fcb9917 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/click-start-of-line-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/click-start-of-line-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/contains-boundaries-expected.png b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/contains-boundaries-expected.png
index cf95091..183e8c0b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/contains-boundaries-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/contains-boundaries-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/inline-closest-leaf-child-expected.png b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/inline-closest-leaf-child-expected.png
index 5597b64..65dce8b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/inline-closest-leaf-child-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/inline-closest-leaf-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/leave-requested-block-expected.png b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/leave-requested-block-expected.png
index d428da1..d76ecf3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/leave-requested-block-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/leave-requested-block-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-clip-text-expected.png
index e6b6e89..86d16cb5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-clip-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-clip-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/body-generated-image-propagated-to-root-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/body-generated-image-propagated-to-root-expected.png
index e33a2b15..dc41a36 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/body-generated-image-propagated-to-root-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/body-generated-image-propagated-to-root-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/mask-negative-offset-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/mask-negative-offset-repeat-expected.png
index 42f4e61..c4a45972 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/mask-negative-offset-repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/mask-negative-offset-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-expected.png
index b3f2605..a483a39 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png
index 734bda8..7d12fc42 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/basic/adding-near-anonymous-block-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/basic/adding-near-anonymous-block-expected.png
index 6a2d2f8..1067cc7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/basic/adding-near-anonymous-block-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/basic/adding-near-anonymous-block-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/basic/text-indent-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/basic/text-indent-rtl-expected.png
index 17523ff..b435470 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/basic/text-indent-rtl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/basic/text-indent-rtl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/basic/truncation-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/basic/truncation-rtl-expected.png
index a44f45cd..b162340 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/basic/truncation-rtl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/basic/truncation-rtl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/002-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/002-expected.png
index 29fba73..4c592055 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/002-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/002-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/intruding-painted-twice-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/intruding-painted-twice-expected.png
index 83acd25..4c5f7e89 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/intruding-painted-twice-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/intruding-painted-twice-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/nopaint-after-layer-destruction-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/nopaint-after-layer-destruction-expected.png
index 246ebbd4..464e6396c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/nopaint-after-layer-destruction-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/nopaint-after-layer-destruction-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/nopaint-after-layer-destruction2-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/nopaint-after-layer-destruction2-expected.png
index fbb985c..5ae00310 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/nopaint-after-layer-destruction2-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/nopaint-after-layer-destruction2-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/table-relayout-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/table-relayout-expected.png
index f7d34ff..bcfb38a2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/table-relayout-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/table-relayout-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/vertical-move-relayout-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/vertical-move-relayout-expected.png
index 0b8ec285..260811bd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/vertical-move-relayout-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/vertical-move-relayout-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/positioning/height-change-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/positioning/height-change-expected.png
index aebe4742..4a446ed 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/positioning/height-change-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/positioning/height-change-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/positioning/relayout-on-position-change-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/positioning/relayout-on-position-change-expected.png
index 435eadf..b744c1c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/positioning/relayout-on-position-change-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/positioning/relayout-on-position-change-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/positioning/window-height-change-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/positioning/window-height-change-expected.png
index cd81bc98..ccb2596 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/positioning/window-height-change-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/positioning/window-height-change-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-huge-assert-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-huge-assert-expected.png
index da64f30..1d48345a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-huge-assert-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-huge-assert-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css-generated-content/before-with-first-letter-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css-generated-content/before-with-first-letter-expected.png
index 734ed720..d97be526 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css-generated-content/before-with-first-letter-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css-generated-content/before-with-first-letter-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css-generated-content/hover-style-change-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css-generated-content/hover-style-change-expected.png
index 8fe83f0..56c3f96d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css-generated-content/hover-style-change-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css-generated-content/hover-style-change-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/border-radius-outline-offset-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/border-radius-outline-offset-expected.png
index ef38b37..bc5f7cdc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/border-radius-outline-offset-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/border-radius-outline-offset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/clip-zooming-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/clip-zooming-expected.png
index ca337bc..d5379ac 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/clip-zooming-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/clip-zooming-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/ex-after-font-variant-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/ex-after-font-variant-expected.png
index c3c3ae48..854e056 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/ex-after-font-variant-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/ex-after-font-variant-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/find-next-layer-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/find-next-layer-expected.png
index af12ed6..cf495e1f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/find-next-layer-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/find-next-layer-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-capitalized-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-capitalized-expected.png
index d55e71df..b9ab41c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-capitalized-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-capitalized-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-detach-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-detach-expected.png
index 3ae3ce1..4a21969 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-detach-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-detach-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-float-after-float-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-float-after-float-expected.png
index c88b1223..68a46fb4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-float-after-float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-float-after-float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-float-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-float-expected.png
index 2875f6bf..5b22cffe 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-hover-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-hover-expected.png
index c6c30e293..65bba2a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-hover-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-hover-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-visibility-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-visibility-expected.png
index 6b6f5dd6..c505aa1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-visibility-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/first-letter-visibility-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-face-opentype-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-face-opentype-expected.png
index d8dfe4bb..e3e2a22d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-face-opentype-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-face-opentype-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-face-synthetic-bold-italic-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-face-synthetic-bold-italic-expected.png
index e9a2e89..beabc38 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-face-synthetic-bold-italic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-face-synthetic-bold-italic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-face-weight-matching-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-face-weight-matching-expected.png
index 56731ea..07433a68 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-face-weight-matching-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-face-weight-matching-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-shorthand-weight-only-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-shorthand-weight-only-expected.png
index 7801ae0..c511460 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-shorthand-weight-only-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/font-shorthand-weight-only-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/hover-subselector-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/hover-subselector-expected.png
index 59681591..b2c3e45 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/hover-subselector-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/hover-subselector-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/invalid-percentage-property-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/invalid-percentage-property-expected.png
index 8e41acf..b0e15310 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/invalid-percentage-property-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/invalid-percentage-property-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/nth-child-dynamic-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/nth-child-dynamic-expected.png
index 3a7db020..aa7d52a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/nth-child-dynamic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/nth-child-dynamic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/resize-corner-tracking-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/resize-corner-tracking-expected.png
index 12a9355e7..cbf5753 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/resize-corner-tracking-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/resize-corner-tracking-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/resize-corner-tracking-transformed-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/resize-corner-tracking-transformed-expected.png
index b1cc5e7..96bb9e6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/resize-corner-tracking-transformed-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/resize-corner-tracking-transformed-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/resize-corner-tracking-transformed-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/resize-corner-tracking-transformed-iframe-expected.png
index 0468679..2eff463 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/resize-corner-tracking-transformed-iframe-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/resize-corner-tracking-transformed-iframe-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/rtl-ordering-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/rtl-ordering-expected.png
index b6317610..2d101a3d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/rtl-ordering-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/rtl-ordering-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/universal-hover-quirk-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/universal-hover-quirk-expected.png
index 2fbc0caa..5399409 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/universal-hover-quirk-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/universal-hover-quirk-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/dom/Element/class-attribute-whitespace-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/dom/Element/class-attribute-whitespace-expected.png
index 38eefbd7..14524e66e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/dom/Element/class-attribute-whitespace-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/dom/Element/class-attribute-whitespace-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/dom/HTMLLinkElement/pending-stylesheet-count-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/dom/HTMLLinkElement/pending-stylesheet-count-expected.png
index 61d1c72b..688b9f1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/dom/HTMLLinkElement/pending-stylesheet-count-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/dom/HTMLLinkElement/pending-stylesheet-count-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/anonymous-block-orphaned-lines-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/anonymous-block-orphaned-lines-expected.png
index 80c2d95b01..3491ec5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/anonymous-block-orphaned-lines-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/anonymous-block-orphaned-lines-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/containing-block-change-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/containing-block-change-expected.png
index 233a792..b2ab2b66 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/containing-block-change-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/containing-block-change-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/create-renderer-for-whitespace-only-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/create-renderer-for-whitespace-only-text-expected.png
index 711e43f2..b037fee 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/create-renderer-for-whitespace-only-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/create-renderer-for-whitespace-only-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/float-in-trailing-whitespace-after-last-line-break-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/float-in-trailing-whitespace-after-last-line-break-expected.png
index b7c3ac930..e8167fac 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/float-in-trailing-whitespace-after-last-line-break-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/float-in-trailing-whitespace-after-last-line-break-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/float-withdrawal-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/float-withdrawal-expected.png
index af0099a..2000185 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/float-withdrawal-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/float-withdrawal-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.png
index 7e294a0..5660757 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/insert-before-table-part-in-continuation-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/selection-highlight-adjust-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/selection-highlight-adjust-expected.png
index 3c71748b..ccf539b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/selection-highlight-adjust-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/selection-highlight-adjust-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/staticY-marking-parents-regression-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/staticY-marking-parents-regression-expected.png
index 2ec37ed..1972b4a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/staticY-marking-parents-regression-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/staticY-marking-parents-regression-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/view-overflow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/view-overflow-expected.png
index a627899f..e6dc142 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/view-overflow-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/dynamic/view-overflow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/button-text-transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/button-text-transform-expected.png
index 2b7a76a..b880788 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/button-text-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/button-text-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/button/button-inner-block-reuse-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/button/button-inner-block-reuse-expected.png
index da61ace5..41d31b5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/button/button-inner-block-reuse-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/button/button-inner-block-reuse-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-clip-overflow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-clip-overflow-expected.png
index cf1f91c..2c37292 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-clip-overflow-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-clip-overflow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/floating-textfield-relayout-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/floating-textfield-relayout-expected.png
index 5143e49..fa17c3a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/floating-textfield-relayout-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/floating-textfield-relayout-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/slider-thumb-shared-style-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/slider-thumb-shared-style-expected.png
index e4700be..5b95e0b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/slider-thumb-shared-style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/range/slider-thumb-shared-style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.png
index 830368ac..6bd1f27 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-scrollbar-incremental-load-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-scrollbar-incremental-load-expected.png
index ca89d86..36190f4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-scrollbar-incremental-load-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-scrollbar-incremental-load-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/menulist-clip-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/menulist-clip-expected.png
index aa0c05e..7f23bc0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/menulist-clip-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/menulist-clip-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/menulist-option-wrap-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/menulist-option-wrap-expected.png
index ebd0fb94..38e0704 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/menulist-option-wrap-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/menulist-option-wrap-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-change-listbox-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-change-listbox-size-expected.png
index 2003dec..b62e5d2c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-change-listbox-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-change-listbox-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-disabled-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-disabled-appearance-expected.png
index c73e9daa..5a4c96eb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-disabled-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-disabled-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-display-none-style-resolve-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-display-none-style-resolve-expected.png
index 09a802f..64cb01b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-display-none-style-resolve-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-display-none-style-resolve-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-item-background-clip-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-item-background-clip-expected.png
index 565ade0..ed9e9c2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-item-background-clip-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-item-background-clip-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-writing-direction-natural-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-writing-direction-natural-expected.png
index 26b7a14..6acd15f6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-writing-direction-natural-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-writing-direction-natural-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/visual-hebrew-text-field-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/visual-hebrew-text-field-expected.png
index dc3f7347..6e35272 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/visual-hebrew-text-field-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/visual-hebrew-text-field-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/frames/frameset-style-recalc-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/frames/frameset-style-recalc-expected.png
index dc36bf6..235f170 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/frames/frameset-style-recalc-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/frames/frameset-style-recalc-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/inline-block/14498-positionForCoordinates-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/inline-block/14498-positionForCoordinates-expected.png
index e1cec0e3..e3bf052 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/inline-block/14498-positionForCoordinates-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/inline-block/14498-positionForCoordinates-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/inline-block/overflow-clip-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/inline-block/overflow-clip-expected.png
index f490707..80e370c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/inline-block/overflow-clip-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/inline-block/overflow-clip-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/inline/br-text-decoration-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/inline/br-text-decoration-expected.png
index 4d68df45..5989a9cf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/inline/br-text-decoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/inline/br-text-decoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/inline-dirty-z-order-lists-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/inline-dirty-z-order-lists-expected.png
index 522ed5b..1bb9e177 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/inline-dirty-z-order-lists-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/inline-dirty-z-order-lists-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/normal-flow-hit-test-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/normal-flow-hit-test-expected.png
index 7480976d..7c44325 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/normal-flow-hit-test-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/normal-flow-hit-test-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/opacity-outline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/opacity-outline-expected.png
index 8aa80015..4708c1d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/opacity-outline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/opacity-outline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/opacity-transforms-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/opacity-transforms-expected.png
index 02c59b3..717fb7e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/opacity-transforms-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/opacity-transforms-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/scroll-rect-to-visible-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/scroll-rect-to-visible-expected.png
index 2cad4b1..847c3fb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/scroll-rect-to-visible-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/scroll-rect-to-visible-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/lists/marker-before-empty-inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/lists/marker-before-empty-inline-expected.png
index 19c06bc..aa7ad92 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/lists/marker-before-empty-inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/lists/marker-before-empty-inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/lists/marker-image-error-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/lists/marker-image-error-expected.png
index 7bbdb48..750dcf4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/lists/marker-image-error-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/lists/marker-image-error-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/lists/markers-in-selection-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/lists/markers-in-selection-expected.png
index c135670..a4588dd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/lists/markers-in-selection-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/lists/markers-in-selection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/hit-test-overflow-controls-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/hit-test-overflow-controls-expected.png
index 4fcc5ef..b839966d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/hit-test-overflow-controls-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/hit-test-overflow-controls-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/image-selection-highlight-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/image-selection-highlight-expected.png
index b0ec6d53..86cf706bf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/image-selection-highlight-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/image-selection-highlight-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-rtl-inline-scrollbar-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-rtl-inline-scrollbar-expected.png
index bd892a6..ca160e4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-rtl-inline-scrollbar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-rtl-inline-scrollbar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/position-fixed-transform-clipping-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/position-fixed-transform-clipping-expected.png
index 84e170ca..f6ff36b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/position-fixed-transform-clipping-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/position-fixed-transform-clipping-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/scrollbar-position-update-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/scrollbar-position-update-expected.png
index 9407cbb..35bbf3c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/scrollbar-position-update-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/scrollbar-position-update-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/inline-crash-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/inline-crash-expected.png
index 277d452..95440d5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/inline-crash-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/inline-crash-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-overflow-hidden-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-overflow-hidden-expected.png
index 670adc6..b80d8484 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-overflow-hidden-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-overflow-hidden-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/absolute-position-percentage-height-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/absolute-position-percentage-height-expected.png
index dc37e14..73e57b5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/absolute-position-percentage-height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/absolute-position-percentage-height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/image-resize-width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/image-resize-width-expected.png
index 4157da56..b47db12 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/image-resize-width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/image-resize-width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/percent-height-in-anonymous-block-in-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/percent-height-in-anonymous-block-in-table-expected.png
index 7e1bb5d5..0cc3118 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/percent-height-in-anonymous-block-in-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/percent-height-in-anonymous-block-in-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/selection-rect-in-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/selection-rect-in-table-cell-expected.png
index bca5e119..4a1ccfd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/selection-rect-in-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/selection-rect-in-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/selection-rect-transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/selection-rect-transform-expected.png
index ced262b..537ad07 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/selection-rect-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/replaced/selection-rect-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/100-percent-cell-width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/100-percent-cell-width-expected.png
index 6803bb3b..a9a9bb3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/100-percent-cell-width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/100-percent-cell-width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/add-before-anonymous-child-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/add-before-anonymous-child-expected.png
index 0603a7b..07975c29 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/add-before-anonymous-child-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/add-before-anonymous-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/border-collapsing-head-foot-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/border-collapsing-head-foot-expected.png
index 906421a0..d9b09e7b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/border-collapsing-head-foot-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/border-collapsing-head-foot-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/border-collapsing-head-foot-vertical-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/border-collapsing-head-foot-vertical-expected.png
index d22a3a85..43b6f87d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/border-collapsing-head-foot-vertical-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/border-collapsing-head-foot-vertical-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/rtl-border-collapsing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/rtl-border-collapsing-expected.png
index bd923b7d..d23c9b43 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/rtl-border-collapsing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/rtl-border-collapsing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/rtl-border-collapsing-vertical-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/rtl-border-collapsing-vertical-expected.png
index 2862b412..808cf97f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/rtl-border-collapsing-vertical-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/rtl-border-collapsing-vertical-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/cell-absolute-child-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/cell-absolute-child-expected.png
index 73a24ba..4d54a0c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/cell-absolute-child-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/cell-absolute-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/click-near-anonymous-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/click-near-anonymous-table-expected.png
index 5c9cd35..55347e6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/click-near-anonymous-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/click-near-anonymous-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/edge-offsets-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/edge-offsets-expected.png
index cd65d36d..36a97e01 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/edge-offsets-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/edge-offsets-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/generated-caption-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/generated-caption-expected.png
index 5c1a083..7837e75 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/generated-caption-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/generated-caption-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/insert-before-anonymous-ancestors-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/insert-before-anonymous-ancestors-expected.png
index 9cb7c771..9fdc938 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/insert-before-anonymous-ancestors-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/insert-before-anonymous-ancestors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/prepend-in-anonymous-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/prepend-in-anonymous-table-expected.png
index a34edcc..cf6b374a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/prepend-in-anonymous-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/prepend-in-anonymous-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/row-height-recalc-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/row-height-recalc-expected.png
index f00dbe78..22f8cd4b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/row-height-recalc-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/row-height-recalc-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/rtl-cell-display-none-assert-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/rtl-cell-display-none-assert-expected.png
index 4eefeea4..4271a5a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/rtl-cell-display-none-assert-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/rtl-cell-display-none-assert-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/stale-grid-crash-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/stale-grid-crash-expected.png
index be5fb1361..a3f22a9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/stale-grid-crash-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/stale-grid-crash-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/text-field-baseline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/text-field-baseline-expected.png
index 5cbf418b..f78105e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/text-field-baseline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/text-field-baseline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/atsui-small-caps-punctuation-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/atsui-small-caps-punctuation-size-expected.png
index 1ff0718a..9b3e9854 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/atsui-small-caps-punctuation-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/atsui-small-caps-punctuation-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/atsui-spacing-features-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/atsui-spacing-features-expected.png
index 1a2ba725..0393c51 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/atsui-spacing-features-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/atsui-spacing-features-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/basic/015-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/basic/015-expected.png
index d629bb77..913f9b0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/basic/015-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/basic/015-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/break-word-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/break-word-expected.png
index da454b99..86012f6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/break-word-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/break-word-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/capitalize-empty-generated-string-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/capitalize-empty-generated-string-expected.png
index 80dcc12..425ede36 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/capitalize-empty-generated-string-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/capitalize-empty-generated-string-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/capitalize-preserve-nbsp-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/capitalize-preserve-nbsp-expected.png
index 451f218..8fbd8fc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/capitalize-preserve-nbsp-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/capitalize-preserve-nbsp-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/font-initial-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/font-initial-expected.png
index ae157cd..f3af69bf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/font-initial-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/font-initial-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/in-rendered-text-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/in-rendered-text-rtl-expected.png
index 5ab849a..500b710 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/in-rendered-text-rtl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/in-rendered-text-rtl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/international/bidi-neutral-directionality-paragraph-start-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/international/bidi-neutral-directionality-paragraph-start-expected.png
index 67375a1..0c25a61 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/international/bidi-neutral-directionality-paragraph-start-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/international/bidi-neutral-directionality-paragraph-start-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/international/rtl-white-space-pre-wrap-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/international/rtl-white-space-pre-wrap-expected.png
index 2666ce3..3628484 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/international/rtl-white-space-pre-wrap-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/international/rtl-white-space-pre-wrap-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/midword-break-after-breakable-char-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/midword-break-after-breakable-char-expected.png
index 5fbf6a3..80cfba0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/midword-break-after-breakable-char-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/midword-break-after-breakable-char-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/midword-break-hang-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/midword-break-hang-expected.png
index 3c3ccc4..8bce956 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/midword-break-hang-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/midword-break-hang-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/reset-emptyRun-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/reset-emptyRun-expected.png
index 17290039..e598ddf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/reset-emptyRun-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/reset-emptyRun-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/atsui-partial-selection-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/atsui-partial-selection-expected.png
index 1dd7ded..6e90dbd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/atsui-partial-selection-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/atsui-partial-selection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/delete-hard-break-character-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/delete-hard-break-character-expected.png
index b967ab4..16b60f10 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/delete-hard-break-character-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/delete-hard-break-character-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/pre-wrap-overflow-selection-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/pre-wrap-overflow-selection-expected.png
index 464913c6..5b10083 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/pre-wrap-overflow-selection-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/pre-wrap-overflow-selection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/rtl-caret-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/rtl-caret-expected.png
index b7a423f..28d8bfb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/rtl-caret-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/rtl-caret-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/selection-hard-linebreak-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/selection-hard-linebreak-expected.png
index cf8ff51..4e7a7c4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/selection-hard-linebreak-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/selection-hard-linebreak-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/wbr-in-pre-crash-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/wbr-in-pre-crash-expected.png
index be156124..8f6df20f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/wbr-in-pre-crash-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/wbr-in-pre-crash-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/whitespace/pre-wrap-last-char-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/whitespace/pre-wrap-last-char-expected.png
index 482d9ee..76c9efa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/whitespace/pre-wrap-last-char-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/whitespace/pre-wrap-last-char-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/whitespace/pre-wrap-spaces-after-newline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/whitespace/pre-wrap-spaces-after-newline-expected.png
index d44162a28..befb460 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/whitespace/pre-wrap-spaces-after-newline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/whitespace/pre-wrap-spaces-after-newline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/word-break-run-rounding-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/word-break-run-rounding-expected.png
index 102dcf33..ca85743 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/word-break-run-rounding-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/word-break-run-rounding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/word-break-soft-hyphen-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/word-break-soft-hyphen-expected.png
index 96473e5..cd186c19 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/word-break-soft-hyphen-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/word-break-soft-hyphen-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/word-space-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/word-space-expected.png
index 65d424e..66508bc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/word-space-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/word-space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/video-replaces-poster-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/video-replaces-poster-expected.png
index 3890fb8..76e5c5a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/media/video-replaces-poster-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/media/video-replaces-poster-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/list-marker-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/list-marker-expected.png
index f507c66..8c41120 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/list-marker-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/list-marker-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/outline/layer-outline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/outline/layer-outline-expected.png
index bb9dd2af..6f9f4a4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/outline/layer-outline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/outline/layer-outline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/outline/layer-outline-horizontal-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/outline/layer-outline-horizontal-expected.png
index bb9dd2af..6f9f4a4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/outline/layer-outline-horizontal-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/outline/layer-outline-horizontal-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/overflow/flexible-box-overflow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/overflow/flexible-box-overflow-expected.png
index 5199952..f6f264f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/overflow/flexible-box-overflow-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/overflow/flexible-box-overflow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/overflow/flexible-box-overflow-horizontal-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/overflow/flexible-box-overflow-horizontal-expected.png
index 5199952..f6f264f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/overflow/flexible-box-overflow-horizontal-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/overflow/flexible-box-overflow-horizontal-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/position/fixed-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/position/fixed-expected.png
index 539a7720a..c3a5a455 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/position/fixed-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/position/fixed-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/scroll/overflow-scroll-delete-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/scroll/overflow-scroll-delete-expected.png
index 08f8b7ed..50bf9aa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/scroll/overflow-scroll-delete-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/scroll/overflow-scroll-delete-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/selection/selected-replaced-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/selection/selected-replaced-expected.png
index ec25b1a7..60bf033 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/selection/selected-replaced-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/selection/selected-replaced-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/text-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/text-shadow-expected.png
index dfd228e..f1c8dfcd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/text-shadow-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/text-shadow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/text-shadow-horizontal-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/text-shadow-horizontal-expected.png
index dfd228e..f1c8dfcd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/text-shadow-horizontal-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/text-shadow-horizontal-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/transforms/transform-positioned-ancestor-expected.png b/third_party/WebKit/LayoutTests/platform/mac/transforms/transform-positioned-ancestor-expected.png
index 10d01d4a..d1371acc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/transforms/transform-positioned-ancestor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/transforms/transform-positioned-ancestor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-caret-expected.png b/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-caret-expected.png
index adfc50d..f9f2cbc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-caret-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-caret-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/transforms/transforms-with-zoom-expected.png b/third_party/WebKit/LayoutTests/platform/mac/transforms/transforms-with-zoom-expected.png
index 297795d..7f881d8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/transforms/transforms-with-zoom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/transforms/transforms-with-zoom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/fast/block/basic/adding-near-anonymous-block-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/fast/block/basic/adding-near-anonymous-block-expected.png
index 68f9dfc4..604e6d8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/fast/block/basic/adding-near-anonymous-block-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/fast/block/basic/adding-near-anonymous-block-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/fast/block/float/table-relayout-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/fast/block/float/table-relayout-expected.png
index b923e3f15..8435833 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/fast/block/float/table-relayout-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/fast/block/float/table-relayout-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/fast/block/float/vertical-move-relayout-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/fast/block/float/vertical-move-relayout-expected.png
index 5acc5c2..0b7515ae 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/fast/block/float/vertical-move-relayout-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/fast/block/float/vertical-move-relayout-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/css/clip-zooming-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/css/clip-zooming-expected.png
index e273835b..0b0f1cd 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/css/clip-zooming-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/css/clip-zooming-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioListener/audiolistener-set-position.html b/third_party/WebKit/LayoutTests/webaudio/AudioListener/audiolistener-set-position.html
new file mode 100644
index 0000000..179672c5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioListener/audiolistener-set-position.html
@@ -0,0 +1,166 @@
+<!doctype html>
+<html>
+  <head>
+    <title>
+      Test AudioListener.setPosition and AudioListener.setOrientation Errors
+    </title>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script>
+    <script src="../resources/audit-util.js"></script>
+    <script src="../resources/audit.js"></script>
+    <script src="../resources/set-position-vs-curve-test.js"></script>
+  </head>
+  <body>
+    <script id="layout-test-code">
+      // Fairly arbitrary rate
+      let sampleRate = 16000;
+
+      // For the tests we need to render for at least two render quanta.
+      // Otherwise, pretty arbitrary.
+      let renderFrames = 256;
+      let renderDuration = renderFrames / sampleRate;
+
+      // The curve duration for the test.  Anything less than one render quantum
+      // is fine.  Arbitrarily choose something small.
+      let curveDurationFrames = 8;
+      let curveDuration = curveDurationFrames / sampleRate;
+
+      // When to call setPosition, after the setValueCurve has ended.  Any value
+      // after the end of the first render quantum is fine.
+      let suspendFrame = 129;
+
+      let audit = Audit.createTaskRunner();
+
+      // Array of tests to do.  Each element of this array is used to create a
+      // task to test the entry.
+      let tests = [
+        // Test |setPosition| against |positionX|, |positionY|, and |positionZ|
+        // setValueCurves.  Include test where there's overlap and where there
+        // isn't.
+        {
+          name: 'Listener setPosition X error',
+          options: {paramName: 'positionX', curveDuration: renderDuration}
+        },
+        {
+          name: 'Listener setPosition X no error',
+          options: {
+            paramName: 'positionX',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+        {
+          name: 'Listener setPosition Y error',
+          options: {paramName: 'positionY', curveDuration: renderDuration}
+        },
+        {
+          name: 'Listener setPosition Y no error',
+          options: {
+            paramName: 'positionY',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+        {
+          name: 'Listener setPosition Z error',
+          options: {paramName: 'positionZ', curveDuration: renderDuration}
+        },
+        {
+          name: 'Listener setPosition Z no error',
+          options: {
+            paramName: 'positionZ',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+        // Now do the same with |setOrientation|, for forward and up vectors.
+        {
+          name: 'Listener setOrientation forward X error',
+          options: {paramName: 'forwardX', curveDuration: renderDuration}
+        },
+        {
+          name: 'Listener setOrientation forward X no error',
+          options: {
+            paramName: 'forwardX',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+        {
+          name: 'Listener setOrientation forward Y error',
+          options: {paramName: 'forwardY', curveDuration: renderDuration}
+        },
+        {
+          name: 'Listener setOrientation forward Y no error',
+          options: {
+            paramName: 'forwardY',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+        {
+          name: 'Listener setOrientation forward Z error',
+          options: {paramName: 'forwardZ', curveDuration: renderDuration}
+        },
+        {
+          name: 'Listener setOrientation forward Z no error',
+          options: {
+            paramName: 'forwardZ',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+        {
+          name: 'Listener setOrientation up X error',
+          options: {paramName: 'upX', curveDuration: renderDuration}
+        },
+        {
+          name: 'Listener setOrientation up X no error',
+          options: {
+            paramName: 'upX',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+        {
+          name: 'Listener setOrientation up Y error',
+          options: {paramName: 'upY', curveDuration: renderDuration}
+        },
+        {
+          name: 'Listener setOrientation up Y no error',
+          options: {
+            paramName: 'upY',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+        {
+          name: 'Listener setOrientation up Z error',
+          options: {paramName: 'upZ', curveDuration: renderDuration}
+        },
+        {
+          name: 'Listener setOrientation up Z no error',
+          options: {
+            paramName: 'upZ',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+      ];
+
+      // Create an audit test for each entry in |tests|.
+      tests.forEach(test => {
+        audit.define(test.name, (task, should) => {
+          let context = new OfflineAudioContext(1, renderFrames, sampleRate);
+          testPositionSetterVsCurve(
+              should, context,
+              Object.assign(
+                  {testName: test.name, nodeName: 'listener'}, test.options))
+              .then(() => task.done());
+        });
+      });
+
+      audit.run();
+    </script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-initial-event.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-initial-event.html
index abd40b39..5468f424 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-initial-event.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-initial-event.html
@@ -137,9 +137,11 @@
         source.buffer = createConstantBuffer(context, 1, 1);
         source.loop = true;
 
-        // Automation is applied to a gain node
-        let gain = context.createGain();
-        gain.gain.value = v0;
+        // Automation is applied to a gain node.  Set the initial value of the
+        // gain in the constructor; using the value setter does an implicit
+        // setValueAtTime which sets an initial event.  This defeats the purpose
+        // of the test.
+        let gain = new GainNode(context, {gain: v0});
 
         // Delay start of automation, if requested
         if (delay) {
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-nominal-range-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-nominal-range-expected.txt
index 217e3a52..3a2e19d 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-nominal-range-expected.txt
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-nominal-range-expected.txt
@@ -1,21 +1,37 @@
-CONSOLE WARNING: line 371: AudioParam value setter will become equivalent to AudioParam.setValueAtTime() in M65, around March 2018  See https://webaudio.github.io/web-audio-api/#dom-audioparam-value for more details.
 CONSOLE WARNING: line 371: Delay.delayTime.value -1 outside nominal range [0, 1.5]; value will be clamped.
+CONSOLE WARNING: line 371: Delay.delayTime.setValueAtTime value -1 outside nominal range [0, 1.5]; value will be clamped.
 CONSOLE WARNING: line 383: Delay.delayTime.value 4 outside nominal range [0, 1.5]; value will be clamped.
+CONSOLE WARNING: line 383: Delay.delayTime.setValueAtTime value 4 outside nominal range [0, 1.5]; value will be clamped.
 CONSOLE WARNING: line 371: StereoPanner.pan.value -3 outside nominal range [-1, 1]; value will be clamped.
+CONSOLE WARNING: line 371: StereoPanner.pan.setValueAtTime value -3 outside nominal range [-1, 1]; value will be clamped.
 CONSOLE WARNING: line 383: StereoPanner.pan.value 3 outside nominal range [-1, 1]; value will be clamped.
+CONSOLE WARNING: line 383: StereoPanner.pan.setValueAtTime value 3 outside nominal range [-1, 1]; value will be clamped.
 CONSOLE WARNING: line 371: DynamicsCompressor.threshold.value -201 outside nominal range [-100, 0]; value will be clamped.
+CONSOLE WARNING: line 371: DynamicsCompressor.threshold.setValueAtTime value -201 outside nominal range [-100, 0]; value will be clamped.
 CONSOLE WARNING: line 383: DynamicsCompressor.threshold.value 1 outside nominal range [-100, 0]; value will be clamped.
+CONSOLE WARNING: line 383: DynamicsCompressor.threshold.setValueAtTime value 1 outside nominal range [-100, 0]; value will be clamped.
 CONSOLE WARNING: line 371: DynamicsCompressor.knee.value -1 outside nominal range [0, 40]; value will be clamped.
+CONSOLE WARNING: line 371: DynamicsCompressor.knee.setValueAtTime value -1 outside nominal range [0, 40]; value will be clamped.
 CONSOLE WARNING: line 383: DynamicsCompressor.knee.value 81 outside nominal range [0, 40]; value will be clamped.
+CONSOLE WARNING: line 383: DynamicsCompressor.knee.setValueAtTime value 81 outside nominal range [0, 40]; value will be clamped.
 CONSOLE WARNING: line 383: DynamicsCompressor.ratio.value 41 outside nominal range [1, 20]; value will be clamped.
+CONSOLE WARNING: line 383: DynamicsCompressor.ratio.setValueAtTime value 41 outside nominal range [1, 20]; value will be clamped.
 CONSOLE WARNING: line 371: DynamicsCompressor.attack.value -1 outside nominal range [0, 1]; value will be clamped.
+CONSOLE WARNING: line 371: DynamicsCompressor.attack.setValueAtTime value -1 outside nominal range [0, 1]; value will be clamped.
 CONSOLE WARNING: line 383: DynamicsCompressor.attack.value 3 outside nominal range [0, 1]; value will be clamped.
+CONSOLE WARNING: line 383: DynamicsCompressor.attack.setValueAtTime value 3 outside nominal range [0, 1]; value will be clamped.
 CONSOLE WARNING: line 371: DynamicsCompressor.release.value -1 outside nominal range [0, 1]; value will be clamped.
+CONSOLE WARNING: line 371: DynamicsCompressor.release.setValueAtTime value -1 outside nominal range [0, 1]; value will be clamped.
 CONSOLE WARNING: line 383: DynamicsCompressor.release.value 3 outside nominal range [0, 1]; value will be clamped.
+CONSOLE WARNING: line 383: DynamicsCompressor.release.setValueAtTime value 3 outside nominal range [0, 1]; value will be clamped.
 CONSOLE WARNING: line 371: BiquadFilter.frequency.value -1 outside nominal range [0, 24000]; value will be clamped.
+CONSOLE WARNING: line 371: BiquadFilter.frequency.setValueAtTime value -1 outside nominal range [0, 24000]; value will be clamped.
 CONSOLE WARNING: line 383: BiquadFilter.frequency.value 48001 outside nominal range [0, 24000]; value will be clamped.
+CONSOLE WARNING: line 383: BiquadFilter.frequency.setValueAtTime value 48001 outside nominal range [0, 24000]; value will be clamped.
 CONSOLE WARNING: line 371: Oscillator.frequency.value -48001 outside nominal range [-24000, 24000]; value will be clamped.
+CONSOLE WARNING: line 371: Oscillator.frequency.setValueAtTime value -48001 outside nominal range [-24000, 24000]; value will be clamped.
 CONSOLE WARNING: line 383: Oscillator.frequency.value 48001 outside nominal range [-24000, 24000]; value will be clamped.
+CONSOLE WARNING: line 383: Oscillator.frequency.setValueAtTime value 48001 outside nominal range [-24000, 24000]; value will be clamped.
 CONSOLE WARNING: line 302: Delay.delayTime.setValueAtTime value -1 outside nominal range [0, 1]; value will be clamped.
 CONSOLE WARNING: line 303: Delay.delayTime.linearRampToValueAtTime value 2 outside nominal range [0, 1]; value will be clamped.
 CONSOLE WARNING: line 304: Delay.delayTime.exponentialRampToValue value 3 outside nominal range [0, 1]; value will be clamped.
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-value-setter-error.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-value-setter-error.html
new file mode 100644
index 0000000..ef097fbe
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-value-setter-error.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>
+      AudioParam Value Setter Error Tests 
+    </title>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script>
+    <script src="../resources/audit-util.js"></script>
+    <script src="../resources/audit.js"></script>
+    <script src="../resources/audioparam-testing.js"></script>
+  </head>
+  <body>
+    <script id="layout-test-code">
+      let sampleRate = 16384;
+      // Number of frames in a rendering quantum.
+      // Test doesn't need to run for very long.
+      let renderDuration = 0.2;
+      let renderFrames = renderDuration * sampleRate;
+      let automationEndTime = 0.1;
+
+      let audit = Audit.createTaskRunner();
+
+      audit.define(
+          'Test value setter with setValueCurveAtTime', (task, should) => {
+            let context = new OfflineAudioContext(
+                {length: renderFrames, sampleRate: sampleRate});
+
+            let src = new ConstantSourceNode(context);
+            let gain = new GainNode(context);
+
+            src.connect(gain).connect(context.destination);
+
+            let render_quantum_duration =
+                RENDER_QUANTUM_FRAMES / context.sampleRate;
+
+            // Start and duration of the curve automation.  These are fairly
+            // arbitrary, but the start should be at least 2 render quanta from
+            // the beginning to allow time for testing the value setter before
+            // the curve starts.  The duration should be at least 2 render
+            // quanta to allow us to apply the value setter in the middle
+            // (somewhere) of the curve.
+            let curveStartTime = 3 * render_quantum_duration;
+            let curveDuration = 4 * render_quantum_duration;
+
+            should(
+                () => {
+                  gain.gain.setValueCurveAtTime(
+                      [-2, 1], curveStartTime, curveDuration);
+                },
+                `setValueCurveAtTime([...], ${curveStartTime}, ${
+                                                                 curveDuration
+                                                               })`)
+                .notThrow();
+
+            // Applying the value setter outside the curve automation should not
+            // throw.  The gain value is arbitrary.
+            context.suspend(curveStartTime - render_quantum_duration)
+                .then(() => {
+                  should(
+                      () => gain.gain.value = Math.PI,
+                      'Using value setter at time ' + context.currentTime +
+                          ' before curve starts')
+                      .notThrow();
+                })
+                .then(() => context.resume());
+
+            // Applying the value setter inside the curve automation should not
+            // throw.  The gain value is arbitrary.
+            context.suspend(curveStartTime + curveDuration / 2)
+                .then(() => {
+                  should(
+                      () => gain.gain.value = 0,
+                      'Using value setter at time ' + context.currentTime +
+                          ' in the middle of the curve')
+                      .throw('NotSupportedError');
+                })
+                .then(() => context.resume());
+
+            src.start();
+
+            // Don't care about the actual output.
+            context.startRendering().then(() => task.done());
+          });
+
+      audit.run();
+    </script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/value-setter-warnings-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/value-setter-warnings-expected.txt
index 0d7b4c44..172d137 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/value-setter-warnings-expected.txt
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/value-setter-warnings-expected.txt
@@ -1,18 +1,11 @@
 CONSOLE ERROR: line 39: [audit.js] this test requires the explicit comparison with the expected result when it runs with run-webkit-tests.
 CONSOLE MESSAGE: line 129: Test: test-0
 CONSOLE WARNING: line 135: AudioParam value setter will become equivalent to AudioParam.setValueAtTime() in M65, around March 2018  See https://webaudio.github.io/web-audio-api/#dom-audioparam-value for more details.
-CONSOLE WARNING: line 148: ConstantSource.offset.value setter called at time 0.4986666666666666 overlaps event setValueAtTime(1, 0.2) to linearRampToValueAtTime(99, 0.7)
 CONSOLE MESSAGE: line 129: Test: test-1
-CONSOLE WARNING: line 148: ConstantSource.offset.value setter called at time 0.09866666666666667 overlaps event setValueAtTime(0, 0) to linearRampToValueAtTime(1, 0.21)
-CONSOLE WARNING: line 148: ConstantSource.offset.value setter called at time 0.4986666666666666 overlaps event linearRampToValueAtTime(1, 0.21) to linearRampToValueAtTime(99, 0.71)
 CONSOLE MESSAGE: line 129: Test: test-2
-CONSOLE WARNING: line 148: ConstantSource.offset.value setter called at time 0.09866666666666667 overlaps event setValueAtTime(0, 0) to linearRampToValueAtTime(1, 0.22)
 CONSOLE MESSAGE: line 129: Test: test-3
-CONSOLE WARNING: line 148: ConstantSource.offset.value setter called at time 0.09866666666666667 overlaps event setValueAtTime(0, 0) to linearRampToValueAtTime(1, 0.23)
 CONSOLE MESSAGE: line 129: Test: test-4
-CONSOLE WARNING: line 148: ConstantSource.offset.value setter called at time 0.4986666666666666 overlaps event setTargetAtTime(1, 0.24, 0.1)
 CONSOLE MESSAGE: line 129: Test: test-5
-CONSOLE WARNING: line 148: ConstantSource.offset.value setter called at time 0.4986666666666666 overlaps event setValueCurveAtTime(..., 0.25, 0.5) to setValueAtTime(3, 0.75)
 This is a testharness.js-based test.
 PASS # AUDIT TASK RUNNER STARTED.
 PASS > [test-0] 
@@ -31,8 +24,9 @@
 PASS   test-4 : rendered successfully
 PASS < [test-4] All assertions passed. (total 1 assertions)
 PASS > [test-5] 
+PASS   Value setter overlaps setValueCurve threw NotSupportedError: "Failed to set the 'value' property on 'AudioParam': setValueAtTime(99, 0.4986666666666666) overlaps setValueCurveAtTime(..., 0.25, 0.5)".
 PASS   test-5 : rendered successfully
-PASS < [test-5] All assertions passed. (total 1 assertions)
+PASS < [test-5] All assertions passed. (total 2 assertions)
 PASS # AUDIT TASK RUNNER FINISHED: 6 tasks ran successfully.
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/value-setter-warnings.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/value-setter-warnings.html
index 8db6966..a8c6085b 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/value-setter-warnings.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/value-setter-warnings.html
@@ -112,7 +112,7 @@
               // No overlap.
               {time: 0.1, value: -1},
               // Overlaps setValueCurve
-              {time: 0.5, value: 99},
+              {time: 0.5, value: 99, shouldThrow: true},
               // Past end of setValueCurve, so no warning
               {time: .9, value: 50}
             ])
@@ -145,7 +145,13 @@
         for (let item of valueSetterList) {
           context.suspend(item.time)
               .then(() => {
-                src.offset.value = item.value;
+                if (item.shouldThrow === true) {
+                  should(() => src.offset.value = item.value,
+                    'Value setter overlaps setValueCurve')
+                    .throw('NotSupportedError');
+                } else {
+                  src.offset.value = item.value;
+                }
               })
               .then(() => context.resume());
         }
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/worklet-warnings-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/worklet-warnings-expected.txt
index 851a790..43304ef 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/worklet-warnings-expected.txt
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/worklet-warnings-expected.txt
@@ -1,5 +1,5 @@
-CONSOLE WARNING: line 36: AudioParam value setter will become equivalent to AudioParam.setValueAtTime() in M65, around March 2018  See https://webaudio.github.io/web-audio-api/#dom-audioparam-value for more details.
 CONSOLE WARNING: line 39: AudioWorklet("noise-generator").amplitude.value 99 outside nominal range [0, 1]; value will be clamped.
+CONSOLE WARNING: line 39: AudioWorklet("noise-generator").amplitude.setValueAtTime value 99 outside nominal range [0, 1]; value will be clamped.
 CONSOLE WARNING: line 43: AudioWorklet("noise-generator").amplitude.setValueAtTime value -1 outside nominal range [0, 1]; value will be clamped.
 CONSOLE WARNING: line 44: AudioWorklet("noise-generator").amplitude.linearRampToValueAtTime value 5 outside nominal range [0, 1]; value will be clamped.
 This is a testharness.js-based test.
diff --git a/third_party/WebKit/LayoutTests/webaudio/BiquadFilter/no-dezippering.html b/third_party/WebKit/LayoutTests/webaudio/BiquadFilter/no-dezippering.html
index 72e46a2..3168b80 100644
--- a/third_party/WebKit/LayoutTests/webaudio/BiquadFilter/no-dezippering.html
+++ b/third_party/WebKit/LayoutTests/webaudio/BiquadFilter/no-dezippering.html
@@ -68,7 +68,7 @@
               initializer: {type: 'peaking', gain: 1},
               changeList:
                   [{quantum: 2, newValue: 5}, {quantum: 6, newValue: -.3}],
-              threshold: 1.3710e-6
+              threshold: 1.9074e-6
             }).then(() => task.done());
           });
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/Panner/panner-set-position.html b/third_party/WebKit/LayoutTests/webaudio/Panner/panner-set-position.html
new file mode 100644
index 0000000..c3a49db
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/webaudio/Panner/panner-set-position.html
@@ -0,0 +1,130 @@
+<!doctype html>
+<html>
+  <head>
+    <title>
+      Test Panner.setPosition and Panner.setOrientation Errors
+    </title>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script>
+    <script src="../resources/audit-util.js"></script>
+    <script src="../resources/audit.js"></script>
+    <script src="../resources/set-position-vs-curve-test.js"></script>
+  </head>
+  <body>
+    <script id="layout-test-code">
+      // Fairly arbitrary rate
+      let sampleRate = 16000;
+
+      // For the tests we need to render for at least two render quanta.
+      // Otherwise, pretty arbitrary.
+      let renderFrames = 256;
+      let renderDuration = renderFrames / sampleRate;
+
+      // The curve duration for the test.  Anything less than one render quantum
+      // is fine.  Arbitrarily choose something small.
+      let curveDurationFrames = 8;
+      let curveDuration = curveDurationFrames / sampleRate;
+
+      // When to call setPosition, after the setValueCurve has ended.  Any value
+      // after the end of the first render quantum is fine.
+      let suspendFrame = 129;
+
+      let audit = Audit.createTaskRunner();
+
+      // Array of tests to do.  Each element of this array is used to create a
+      // task to test the entry.
+      let tests = [
+        // Test setPosition against positionX, positionY, and positionZ
+        // setValueCurves.  Include test where there's overlap and where there
+        // isn't.
+        {
+          name: 'Panner setPosition X error',
+          options: {paramName: 'positionX', curveDuration: renderDuration}
+        },
+        {
+          name: 'Panner setPosition X no error',
+          options: {
+            paramName: 'positionX',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+        {
+          name: 'Panner setPosition Y error',
+          options: {paramName: 'positionY', curveDuration: renderDuration}
+        },
+        {
+          name: 'Panner setPosition Y no error',
+          options: {
+            paramName: 'positionY',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+        {
+          name: 'Panner setPosition Z error',
+          options: {paramName: 'positionZ', curveDuration: renderDuration}
+        },
+        {
+          name: 'Panner setPosition Z no error',
+          options: {
+            paramName: 'positionZ',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+        // Now do the same with setOrientation.
+        {
+          name: 'Panner setOrientation X error',
+          options: {paramName: 'orientationX', curveDuration: renderDuration}
+        },
+        {
+          name: 'Panner setOrientation X no error',
+          options: {
+            paramName: 'orientationX',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+        {
+          name: 'Panner setOrientation Y error',
+          options: {paramName: 'orientationY', curveDuration: renderDuration}
+        },
+        {
+          name: 'Panner setOrientation Y no error',
+          options: {
+            paramName: 'orientationY',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+        {
+          name: 'Panner setOrientation Z error',
+          options: {paramName: 'orientationZ', curveDuration: renderDuration}
+        },
+        {
+          name: 'Panner setOrientation Z no error',
+          options: {
+            paramName: 'orientationZ',
+            curveDuration: curveDuration,
+            suspendFrame: suspendFrame
+          }
+        },
+      ];
+
+      // Create an audit test for each entry in |tests|.
+      tests.forEach(test => {
+        audit.define(test.name, (task, should) => {
+          let context = new OfflineAudioContext(1, renderFrames, sampleRate);
+          testPositionSetterVsCurve(
+              should, context,
+              Object.assign(
+                  {testName: test.name, nodeName: 'panner'}, test.options))
+              .then(() => task.done());
+        });
+      });
+
+      audit.run();
+    </script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/set-position-vs-curve-test.js b/third_party/WebKit/LayoutTests/webaudio/resources/set-position-vs-curve-test.js
new file mode 100644
index 0000000..403129d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/webaudio/resources/set-position-vs-curve-test.js
@@ -0,0 +1,96 @@
+// This depends on audit.js to define the |should| function used herein.
+//
+// Test that setPosition throws an error if there is already a
+// setValueCurve scheduled during the same time period.
+function testPositionSetterVsCurve(should, context, options) {
+  // Create the graph consisting of a source node and the panner.
+  let src = new ConstantSourceNode(context, {offset: 1});
+  let panner = new PannerNode(context);
+  src.connect(panner).connect(context.destination);
+
+  let curve = Float32Array.from([-10, 10]);
+
+  // Determine if we're testing the panner or the listener and set the node
+  // appropriately.
+  let testNode = options.nodeName === 'panner' ? panner : context.listener;
+
+  let prefix = options.nodeName === 'panner' ? 'panner.' : 'listener.';
+
+  let message = prefix + options.paramName + '.setValueCurve(..., 0, ' +
+      options.curveDuration + ')';
+
+  // If the coordinate name has 'position', we're testing setPosition;
+  // otherwise assume we're testing setOrientation.
+  let methodName =
+      options.paramName.includes('position') ? 'setPosition' : 'setOrientation';
+
+  // Sanity check that we're testing the right node. (The |testName| prefix is
+  // to make each message unique for testharness.)
+  if (options.nodeName === 'panner') {
+    should(
+        testNode instanceof PannerNode,
+        options.testName + ': Node under test is a PannerNode')
+        .beTrue();
+  } else {
+    should(
+        testNode instanceof AudioListener,
+        options.testName + ': Node under test is an AudioLIstener')
+        .beTrue();
+  }
+
+  // Set the curve automation on the specified axis.
+  should(() => {
+    testNode[options.paramName].setValueCurveAtTime(
+        curve, 0, options.curveDuration);
+  }, message).notThrow();
+
+  let resumeContext = context.resume.bind(context);
+
+  // Get correct argument string for the setter for printing the message.
+  let setterArguments;
+  if (options.nodeName === 'panner') {
+    setterArguments = '(1,1,1)';
+  } else {
+    if (methodName === 'setPosition') {
+      setterArguments = '(1,1,1)';
+    } else {
+      setterArguments = '(1,1,1,1,1,1)';
+    }
+  }
+
+  let setterMethod = () => {
+    // It's ok to give extra args.
+    testNode[methodName](1, 1, 1, 1, 1, 1);
+  };
+
+  if (options.suspendFrame) {
+    // We're testing setPosition after the curve has ended to verify that
+    // we don't throw an error.  Thus, suspend the context and call
+    // setPosition.
+    let suspendTime = options.suspendFrame / context.sampleRate;
+    context.suspend(suspendTime)
+        .then(() => {
+          should(
+              setterMethod,
+              prefix + methodName + setterArguments + ' for ' +
+                  options.paramName + ' at time ' + suspendTime)
+              .notThrow();
+        })
+        .then(resumeContext);
+  } else {
+    // Basic test where setPosition is called where setValueCurve is
+    // already active.
+    context.suspend(0)
+        .then(() => {
+          should(
+              setterMethod,
+              prefix + methodName + setterArguments + ' for ' +
+                  options.paramName)
+              .throw('NotSupportedError');
+        })
+        .then(resumeContext);
+  }
+
+  src.start();
+  return context.startRendering();
+}
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_methods.py b/third_party/WebKit/Source/bindings/scripts/v8_methods.py
index 536e031..3a93474 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_methods.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_methods.py
@@ -374,7 +374,7 @@
     return idl_type.v8_set_return_value(cpp_value, extended_attributes, script_wrappable=script_wrappable, for_main_world=for_main_world, is_static=method.is_static)
 
 
-def v8_value_to_local_cpp_variadic_value(method, argument, index, return_promise):
+def v8_value_to_local_cpp_variadic_value(argument, index):
     assert argument.is_variadic
     idl_type = v8_types.native_value_traits_type_name(argument.idl_type, True)
 
@@ -411,7 +411,7 @@
     }
 
 
-def v8_value_to_local_cpp_value(interface_name, method, argument, index, return_promise=False):
+def v8_value_to_local_cpp_value(interface_name, method, argument, index):
     extended_attributes = argument.extended_attributes
     idl_type = argument.idl_type
     name = argument.name
@@ -428,7 +428,7 @@
                                                for_storage=for_storage)
 
     if argument.is_variadic:
-        return v8_value_to_local_cpp_variadic_value(method, argument, index, return_promise)
+        return v8_value_to_local_cpp_variadic_value(argument, index)
     return idl_type.v8_value_to_local_cpp_value(extended_attributes, v8_value,
                                                 name, declare_variable=False,
                                                 use_exception_state=method.returns_promise)
diff --git a/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp b/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp
index 72d7b7b..d1b38bc8 100644
--- a/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp
+++ b/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp
@@ -628,26 +628,6 @@
   return return_value_if_no_parameter;
 }
 
-static bool ImmersiveMediaFeatureEval(const MediaQueryExpValue& value,
-                                      MediaFeaturePrefix op,
-                                      const MediaValues& media_values) {
-  bool return_value_if_no_parameter;
-  int is_immersive_numeric_value;
-
-  bool immersive = media_values.InImmersiveMode();
-
-  return_value_if_no_parameter = immersive;
-  is_immersive_numeric_value = immersive ? 1 : 0;
-
-  if (value.IsValid()) {
-    float number;
-    return NumberValue(value, number) &&
-           CompareValue(is_immersive_numeric_value, static_cast<int>(number),
-                        op);
-  }
-  return return_value_if_no_parameter;
-}
-
 static bool HoverMediaFeatureEval(const MediaQueryExpValue& value,
                                   MediaFeaturePrefix,
                                   const MediaValues& media_values) {
diff --git a/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp b/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp
index f6952a47..3ec9bed 100644
--- a/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp
+++ b/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp
@@ -8,10 +8,7 @@
 #include "core/css/MediaList.h"
 #include "core/css/MediaValuesCached.h"
 #include "core/css/MediaValuesInitialViewport.h"
-#include "core/css/parser/CSSTokenizer.h"
-#include "core/css/parser/MediaQueryParser.h"
 #include "core/frame/LocalFrameView.h"
-#include "core/frame/Settings.h"
 #include "core/media_type_names.h"
 #include "core/testing/DummyPageHolder.h"
 #include "platform/wtf/text/StringBuilder.h"
@@ -155,47 +152,16 @@
     {nullptr, 0}  // Do not remove the terminator line.
 };
 
-MediaQueryEvaluatorTestCase g_non_immersive_test_cases[] = {
-    {"(immersive: 1)", 0},
-    {"(immersive: 0)", 1},
-    {nullptr, 0}  // Do not remove the terminator line.
-};
-
-MediaQueryEvaluatorTestCase g_immersive_test_cases[] = {
-    {"(immersive: 1)", 1},
-    {"(immersive: 0)", 0},
-    {nullptr, 0}  // Do not remove the terminator line.
-};
-
-MediaQueryEvaluatorTestCase g_non_ua_sheet_immersive_test_cases[] = {
-    {"(immersive: 1)", 0},
-    {"(immersive: 0)", 0},
-    {nullptr, 0}  // Do not remove the terminator line.
-};
-
 void TestMQEvaluator(MediaQueryEvaluatorTestCase* test_cases,
-                     const MediaQueryEvaluator& media_query_evaluator,
-                     CSSParserMode mode) {
+                     const MediaQueryEvaluator& media_query_evaluator) {
   scoped_refptr<MediaQuerySet> query_set = nullptr;
   for (unsigned i = 0; test_cases[i].input; ++i) {
-    if (String(test_cases[i].input).IsEmpty()) {
-      query_set = MediaQuerySet::Create();
-    } else {
-      query_set = MediaQueryParser::ParseMediaQuerySetInMode(
-          CSSParserTokenRange(
-              CSSTokenizer(test_cases[i].input).TokenizeToEOF()),
-          mode);
-    }
+    query_set = MediaQuerySet::Create(test_cases[i].input);
     EXPECT_EQ(test_cases[i].output, media_query_evaluator.Eval(*query_set))
         << "Query: " << test_cases[i].input;
   }
 }
 
-void TestMQEvaluator(MediaQueryEvaluatorTestCase* test_cases,
-                     const MediaQueryEvaluator& media_query_evaluator) {
-  TestMQEvaluator(test_cases, media_query_evaluator, kHTMLStandardMode);
-}
-
 TEST(MediaQueryEvaluatorTest, Cached) {
   MediaValuesCached::MediaValuesCachedData data;
   data.viewport_width = 500;
@@ -213,7 +179,6 @@
   data.strict_mode = true;
   data.display_mode = kWebDisplayModeBrowser;
   data.display_shape = kDisplayShapeRect;
-  data.immersive_mode = false;
 
   // Default values.
   {
@@ -221,9 +186,6 @@
     MediaQueryEvaluator media_query_evaluator(*media_values);
     TestMQEvaluator(g_screen_test_cases, media_query_evaluator);
     TestMQEvaluator(g_viewport_test_cases, media_query_evaluator);
-    TestMQEvaluator(g_non_immersive_test_cases, media_query_evaluator,
-                    kUASheetMode);
-    TestMQEvaluator(g_non_ua_sheet_immersive_test_cases, media_query_evaluator);
   }
 
   // Print values.
@@ -245,17 +207,6 @@
     data.color_bits_per_component = 24;
     data.monochrome_bits_per_component = 0;
   }
-
-  // Immersive values.
-  {
-    data.immersive_mode = true;
-    MediaValues* media_values = MediaValuesCached::Create(data);
-    MediaQueryEvaluator media_query_evaluator(*media_values);
-    TestMQEvaluator(g_immersive_test_cases, media_query_evaluator,
-                    kUASheetMode);
-    TestMQEvaluator(g_non_ua_sheet_immersive_test_cases, media_query_evaluator);
-    data.immersive_mode = false;
-  }
 }
 
 TEST(MediaQueryEvaluatorTest, Dynamic) {
@@ -315,18 +266,4 @@
   TestMQEvaluator(g_viewport_test_cases, media_query_evaluator);
 }
 
-TEST(MediaQueryEvaluatorTest, DynamicImmersive) {
-  std::unique_ptr<DummyPageHolder> page_holder =
-      DummyPageHolder::Create(IntSize(500, 500));
-  page_holder->GetFrameView().SetMediaType(MediaTypeNames::screen);
-
-  MediaQueryEvaluator media_query_evaluator(&page_holder->GetFrame());
-  page_holder->GetDocument().GetSettings()->SetImmersiveModeEnabled(false);
-
-  TestMQEvaluator(g_non_immersive_test_cases, media_query_evaluator,
-                  kUASheetMode);
-  page_holder->GetDocument().GetSettings()->SetImmersiveModeEnabled(true);
-  TestMQEvaluator(g_immersive_test_cases, media_query_evaluator, kUASheetMode);
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/MediaQueryExp.cpp b/third_party/WebKit/Source/core/css/MediaQueryExp.cpp
index ffb00dbc..37cdd70 100644
--- a/third_party/WebKit/Source/core/css/MediaQueryExp.cpp
+++ b/third_party/WebKit/Source/core/css/MediaQueryExp.cpp
@@ -122,8 +122,7 @@
          media_feature == minColorIndexMediaFeature ||
          media_feature == monochromeMediaFeature ||
          media_feature == maxMonochromeMediaFeature ||
-         media_feature == minMonochromeMediaFeature ||
-         media_feature == immersiveMediaFeature;
+         media_feature == minMonochromeMediaFeature;
 }
 
 static inline bool FeatureWithPositiveInteger(const String& media_feature,
@@ -185,8 +184,7 @@
          media_feature == displayModeMediaFeature ||
          media_feature == scanMediaFeature ||
          media_feature == shapeMediaFeature ||
-         media_feature == colorGamutMediaFeature ||
-         media_feature == immersiveMediaFeature;
+         media_feature == colorGamutMediaFeature;
 }
 
 bool MediaQueryExp::IsViewportDependent() const {
diff --git a/third_party/WebKit/Source/core/css/MediaValues.cpp b/third_party/WebKit/Source/core/css/MediaValues.cpp
index 64c3b35d..8844114 100644
--- a/third_party/WebKit/Source/core/css/MediaValues.cpp
+++ b/third_party/WebKit/Source/core/css/MediaValues.cpp
@@ -133,12 +133,6 @@
   return three_d_enabled;
 }
 
-bool MediaValues::CalculateInImmersiveMode(LocalFrame* frame) {
-  DCHECK(frame);
-  DCHECK(frame->GetSettings());
-  return frame->GetSettings()->GetImmersiveModeEnabled();
-}
-
 PointerType MediaValues::CalculatePrimaryPointerType(LocalFrame* frame) {
   DCHECK(frame);
   DCHECK(frame->GetSettings());
diff --git a/third_party/WebKit/Source/core/css/MediaValues.h b/third_party/WebKit/Source/core/css/MediaValues.h
index 0e2ac9f8..3ecdace 100644
--- a/third_party/WebKit/Source/core/css/MediaValues.h
+++ b/third_party/WebKit/Source/core/css/MediaValues.h
@@ -66,7 +66,6 @@
   virtual HoverType PrimaryHoverType() const = 0;
   virtual int AvailableHoverTypes() const = 0;
   virtual bool ThreeDEnabled() const = 0;
-  virtual bool InImmersiveMode() const = 0;
   virtual const String MediaType() const = 0;
   virtual WebDisplayMode DisplayMode() const = 0;
   virtual bool StrictMode() const = 0;
@@ -90,7 +89,6 @@
   static const String CalculateMediaType(LocalFrame*);
   static WebDisplayMode CalculateDisplayMode(LocalFrame*);
   static bool CalculateThreeDEnabled(LocalFrame*);
-  static bool CalculateInImmersiveMode(LocalFrame*);
   static PointerType CalculatePrimaryPointerType(LocalFrame*);
   static int CalculateAvailablePointerTypes(LocalFrame*);
   static HoverType CalculatePrimaryHoverType(LocalFrame*);
diff --git a/third_party/WebKit/Source/core/css/MediaValuesCached.cpp b/third_party/WebKit/Source/core/css/MediaValuesCached.cpp
index 773639f..2ffa7da 100644
--- a/third_party/WebKit/Source/core/css/MediaValuesCached.cpp
+++ b/third_party/WebKit/Source/core/css/MediaValuesCached.cpp
@@ -62,7 +62,6 @@
     available_hover_types = MediaValues::CalculateAvailableHoverTypes(frame);
     default_font_size = MediaValues::CalculateDefaultFontSize(frame);
     three_d_enabled = MediaValues::CalculateThreeDEnabled(frame);
-    immersive_mode = MediaValues::CalculateInImmersiveMode(frame);
     strict_mode = MediaValues::CalculateStrictMode(frame);
     display_mode = MediaValues::CalculateDisplayMode(frame);
     media_type = MediaValues::CalculateMediaType(frame);
@@ -153,10 +152,6 @@
   return data_.three_d_enabled;
 }
 
-bool MediaValuesCached::InImmersiveMode() const {
-  return data_.immersive_mode;
-}
-
 bool MediaValuesCached::StrictMode() const {
   return data_.strict_mode;
 }
diff --git a/third_party/WebKit/Source/core/css/MediaValuesCached.h b/third_party/WebKit/Source/core/css/MediaValuesCached.h
index 042443d..7f6080a 100644
--- a/third_party/WebKit/Source/core/css/MediaValuesCached.h
+++ b/third_party/WebKit/Source/core/css/MediaValuesCached.h
@@ -30,7 +30,6 @@
     int available_hover_types;
     int default_font_size;
     bool three_d_enabled;
-    bool immersive_mode;
     bool strict_mode;
     String media_type;
     WebDisplayMode display_mode;
@@ -55,7 +54,6 @@
       data.available_hover_types = available_hover_types;
       data.default_font_size = default_font_size;
       data.three_d_enabled = three_d_enabled;
-      data.immersive_mode = immersive_mode;
       data.strict_mode = strict_mode;
       data.media_type = media_type.IsolatedCopy();
       data.display_mode = display_mode;
@@ -87,7 +85,6 @@
   HoverType PrimaryHoverType() const override;
   int AvailableHoverTypes() const override;
   bool ThreeDEnabled() const override;
-  bool InImmersiveMode() const override;
   bool StrictMode() const override;
   Document* GetDocument() const override;
   bool HasValues() const override;
diff --git a/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp b/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp
index 5abcaa0..0a5d1d0 100644
--- a/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp
+++ b/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp
@@ -117,10 +117,6 @@
   return CalculateThreeDEnabled(frame_);
 }
 
-bool MediaValuesDynamic::InImmersiveMode() const {
-  return CalculateInImmersiveMode(frame_);
-}
-
 const String MediaValuesDynamic::MediaType() const {
   return CalculateMediaType(frame_);
 }
diff --git a/third_party/WebKit/Source/core/css/MediaValuesDynamic.h b/third_party/WebKit/Source/core/css/MediaValuesDynamic.h
index 0f1f8253..7b62e5e7 100644
--- a/third_party/WebKit/Source/core/css/MediaValuesDynamic.h
+++ b/third_party/WebKit/Source/core/css/MediaValuesDynamic.h
@@ -35,7 +35,6 @@
   HoverType PrimaryHoverType() const override;
   int AvailableHoverTypes() const override;
   bool ThreeDEnabled() const override;
-  bool InImmersiveMode() const override;
   bool StrictMode() const override;
   const String MediaType() const override;
   WebDisplayMode DisplayMode() const override;
diff --git a/third_party/WebKit/Source/core/css/media_feature_names.json5 b/third_party/WebKit/Source/core/css/media_feature_names.json5
index c36a0f83..5f06821 100644
--- a/third_party/WebKit/Source/core/css/media_feature_names.json5
+++ b/third_party/WebKit/Source/core/css/media_feature_names.json5
@@ -22,9 +22,6 @@
     "device-height",
     "device-width",
     "display-mode",
-    // This has not been standardized and is only available to UA style sheets.
-    // See crbug.com/809165
-    "immersive",
     "max-color",
     "max-color-index",
     "max-aspect-ratio",
diff --git a/third_party/WebKit/Source/core/css/parser/CSS.proto b/third_party/WebKit/Source/core/css/parser/CSS.proto
index 369265f4..85b27729 100644
--- a/third_party/WebKit/Source/core/css/parser/CSS.proto
+++ b/third_party/WebKit/Source/core/css/parser/CSS.proto
@@ -811,7 +811,6 @@
     SCAN = 43;
     SHAPE = 44;
     INVALID_NAME = 45;
-    IMMERSIVE = 46;
   }
   required ValueId id = 1;
 }
diff --git a/third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp b/third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp
index 0eb43c2e..ea09c93 100644
--- a/third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp
@@ -17,20 +17,12 @@
 
 scoped_refptr<MediaQuerySet> MediaQueryParser::ParseMediaQuerySet(
     CSSParserTokenRange range) {
-  return MediaQueryParser(kMediaQuerySetParser, kHTMLStandardMode)
-      .ParseImpl(range);
-}
-
-scoped_refptr<MediaQuerySet> MediaQueryParser::ParseMediaQuerySetInMode(
-    CSSParserTokenRange range,
-    CSSParserMode mode) {
-  return MediaQueryParser(kMediaQuerySetParser, mode).ParseImpl(range);
+  return MediaQueryParser(kMediaQuerySetParser).ParseImpl(range);
 }
 
 scoped_refptr<MediaQuerySet> MediaQueryParser::ParseMediaCondition(
     CSSParserTokenRange range) {
-  return MediaQueryParser(kMediaConditionParser, kHTMLStandardMode)
-      .ParseImpl(range);
+  return MediaQueryParser(kMediaConditionParser).ParseImpl(range);
 }
 
 const MediaQueryParser::State MediaQueryParser::kReadRestrictor =
@@ -57,10 +49,8 @@
     &MediaQueryParser::SkipUntilBlockEnd;
 const MediaQueryParser::State MediaQueryParser::kDone = &MediaQueryParser::Done;
 
-MediaQueryParser::MediaQueryParser(ParserType parser_type, CSSParserMode mode)
-    : parser_type_(parser_type),
-      query_set_(MediaQuerySet::Create()),
-      mode_(mode) {
+MediaQueryParser::MediaQueryParser(ParserType parser_type)
+    : parser_type_(parser_type), query_set_(MediaQuerySet::Create()) {
   if (parser_type == kMediaQuerySetParser)
     state_ = &MediaQueryParser::ReadRestrictor;
   else  // MediaConditionParser
@@ -160,13 +150,8 @@
                                    const CSSParserToken& token,
                                    CSSParserTokenRange& range) {
   if (type == kIdentToken) {
-    String media_feature = token.Value().ToString();
-    if (IsMediaFeatureAllowedInMode(media_feature)) {
-      media_query_data_.SetMediaFeature(media_feature);
-      state_ = kReadFeatureColon;
-    } else {
-      state_ = kSkipUntilComma;
-    }
+    media_query_data_.SetMediaFeature(token.Value().ToString());
+    state_ = kReadFeatureColon;
   } else {
     state_ = kSkipUntilComma;
   }
@@ -280,12 +265,6 @@
   return query_set_;
 }
 
-bool MediaQueryParser::IsMediaFeatureAllowedInMode(
-    const String& media_feature) const {
-  return mode_ == kUASheetMode ||
-         media_feature != MediaFeatureNames::immersiveMediaFeature;
-}
-
 MediaQueryData::MediaQueryData()
     : restrictor_(MediaQuery::kNone),
       media_type_(MediaTypeNames::all),
diff --git a/third_party/WebKit/Source/core/css/parser/MediaQueryParser.h b/third_party/WebKit/Source/core/css/parser/MediaQueryParser.h
index 1618275c..53fbc54 100644
--- a/third_party/WebKit/Source/core/css/parser/MediaQueryParser.h
+++ b/third_party/WebKit/Source/core/css/parser/MediaQueryParser.h
@@ -10,7 +10,6 @@
 #include "core/css/MediaList.h"
 #include "core/css/MediaQuery.h"
 #include "core/css/MediaQueryExp.h"
-#include "core/css/parser/CSSParserMode.h"
 #include "core/css/parser/CSSParserToken.h"
 #include "core/css/parser/CSSParserTokenRange.h"
 #include "core/css/parser/MediaQueryBlockWatcher.h"
@@ -60,9 +59,6 @@
   static scoped_refptr<MediaQuerySet> ParseMediaQuerySet(const String&);
   static scoped_refptr<MediaQuerySet> ParseMediaQuerySet(CSSParserTokenRange);
   static scoped_refptr<MediaQuerySet> ParseMediaCondition(CSSParserTokenRange);
-  static scoped_refptr<MediaQuerySet> ParseMediaQuerySetInMode(
-      CSSParserTokenRange,
-      CSSParserMode);
 
  private:
   enum ParserType {
@@ -70,7 +66,7 @@
     kMediaConditionParser,
   };
 
-  MediaQueryParser(ParserType, CSSParserMode);
+  MediaQueryParser(ParserType);
   virtual ~MediaQueryParser();
 
   scoped_refptr<MediaQuerySet> ParseImpl(CSSParserTokenRange);
@@ -117,14 +113,11 @@
   void SetStateAndRestrict(State, MediaQuery::RestrictorType);
   void HandleBlocks(const CSSParserToken&);
 
-  bool IsMediaFeatureAllowedInMode(const String& media_feature) const;
-
   State state_;
   ParserType parser_type_;
   MediaQueryData media_query_data_;
   scoped_refptr<MediaQuerySet> query_set_;
   MediaQueryBlockWatcher block_watcher_;
-  CSSParserMode mode_;
 
   const static State kReadRestrictor;
   const static State kReadMediaNot;
diff --git a/third_party/WebKit/Source/core/exported/WebSettingsImpl.cpp b/third_party/WebKit/Source/core/exported/WebSettingsImpl.cpp
index 60682f6..beb5b884 100644
--- a/third_party/WebKit/Source/core/exported/WebSettingsImpl.cpp
+++ b/third_party/WebKit/Source/core/exported/WebSettingsImpl.cpp
@@ -636,8 +636,8 @@
   settings_->SetEmbeddedMediaExperienceEnabled(enabled);
 }
 
-void WebSettingsImpl::SetImmersiveModeEnabled(bool enabled) {
-  settings_->SetImmersiveModeEnabled(enabled);
+void WebSettingsImpl::SetPagePopupsSuppressed(bool suppressed) {
+  settings_->SetPagePopupsSuppressed(suppressed);
 }
 
 void WebSettingsImpl::SetViewportEnabled(bool enabled) {
diff --git a/third_party/WebKit/Source/core/exported/WebSettingsImpl.h b/third_party/WebKit/Source/core/exported/WebSettingsImpl.h
index 7f77ead..6bea2595 100644
--- a/third_party/WebKit/Source/core/exported/WebSettingsImpl.h
+++ b/third_party/WebKit/Source/core/exported/WebSettingsImpl.h
@@ -120,7 +120,7 @@
   void SetMediaPlaybackGestureWhitelistScope(const WebString&) override;
   void SetPresentationRequiresUserGesture(bool) override;
   void SetEmbeddedMediaExperienceEnabled(bool) override;
-  void SetImmersiveModeEnabled(bool) override;
+  void SetPagePopupsSuppressed(bool) override;
   void SetMinimumAccelerated2dCanvasSize(int) override;
   void SetMinimumFontSize(int) override;
   void SetMinimumLogicalFontSize(int) override;
diff --git a/third_party/WebKit/Source/core/frame/Settings.json5 b/third_party/WebKit/Source/core/frame/Settings.json5
index b6905521..26091ba 100644
--- a/third_party/WebKit/Source/core/frame/Settings.json5
+++ b/third_party/WebKit/Source/core/frame/Settings.json5
@@ -230,12 +230,15 @@
       initial: false,
     },
 
-    // This is true when the page is being displayed in a 3D context (eg, a VR
-    // headset).
+    // This is used when page popups should not be presented at all from time
+    // to time in the life of a renderer. This is different than the runtime
+    // enabled feature to enable page popups which remains fixed for the
+    // lifetime of a render and semantically means that an alternative UI
+    // should be shown. An example of when this might be used is in an
+    // embedder than cannot render these popups (in VR mode, say).
     {
-      name: "immersiveModeEnabled",
+      name: "pagePopupsSuppressed",
       initial: false,
-      invalidate: "MediaQuery",
     },
 
     {
diff --git a/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp b/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp
index e14cfff..7a0b40a2 100644
--- a/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp
@@ -314,6 +314,9 @@
   anchor->setAttribute(classAttr, class_value);
   anchor->setAttribute(targetAttr, "_blank");
   anchor->setAttribute(hrefAttr, url);
+  // Disallow JavaScript hrefs. https://crbug.com/808407
+  if (anchor->Url().ProtocolIsJavaScript())
+    anchor->setAttribute(hrefAttr, "about:blank");
   current_->ParserAppendChild(anchor);
   return anchor;
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
index 7e8a1f8..b98b75a 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -1998,6 +1998,7 @@
 }
 
 bool LayoutBlock::RecalcChildOverflowAfterStyleChange() {
+  DCHECK(!IsTable());
   DCHECK(ChildNeedsOverflowRecalcAfterStyleChange());
   ClearChildNeedsOverflowRecalcAfterStyleChange();
 
@@ -2041,6 +2042,11 @@
   if (!self_needs_overflow_recalc && !children_overflow_changed)
     return false;
 
+  return RecalcSelfOverflowAfterStyleChange();
+}
+
+bool LayoutBlock::RecalcSelfOverflowAfterStyleChange() {
+  bool self_needs_overflow_recalc = SelfNeedsOverflowRecalcAfterStyleChange();
   ClearSelfNeedsOverflowRecalcAfterStyleChange();
   // If the current block needs layout, overflow will be recalculated during
   // layout time anyway. We can safely exit here.
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.h b/third_party/WebKit/Source/core/layout/LayoutBlock.h
index b2c5bea6..cced7023 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.h
@@ -318,6 +318,7 @@
  protected:
   bool RecalcNormalFlowChildOverflowIfNeeded(LayoutObject*);
   bool RecalcPositionedDescendantsOverflowAfterStyleChange();
+  bool RecalcSelfOverflowAfterStyleChange();
 
  public:
   bool RecalcChildOverflowAfterStyleChange();
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
index 1837c0c..ab5b342c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -563,6 +563,8 @@
 }
 
 bool LayoutTable::RecalcOverflowAfterStyleChange() {
+  RecalcSelfOverflowAfterStyleChange();
+
   if (!ChildNeedsOverflowRecalcAfterStyleChange())
     return false;
   ClearChildNeedsOverflowRecalcAfterStyleChange();
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp b/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp
index 7437bc9..221f532e 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableTest.cpp
@@ -18,6 +18,30 @@
   }
 };
 
+TEST_F(LayoutTableTest, OverflowViaOutline) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      div { display: table; width: 100px; height: 200px; }
+    </style>
+    <div id=target>
+      <div id=child></div>
+    </div>
+  )HTML");
+  auto* target = GetTableByElementId("target");
+  EXPECT_EQ(LayoutRect(0, 0, 100, 200), target->SelfVisualOverflowRect());
+  ToElement(target->GetNode())
+      ->setAttribute(HTMLNames::styleAttr, "outline: 2px solid black");
+
+  auto* child = GetTableByElementId("child");
+  ToElement(child->GetNode())
+      ->setAttribute(HTMLNames::styleAttr, "outline: 2px solid black");
+
+  target->GetFrameView()->UpdateAllLifecyclePhases();
+  EXPECT_EQ(LayoutRect(-2, -2, 104, 204), target->SelfVisualOverflowRect());
+
+  EXPECT_EQ(LayoutRect(-2, -2, 104, 204), child->SelfVisualOverflowRect());
+}
+
 TEST_F(LayoutTableTest, OverflowWithCollapsedBorders) {
   SetBodyInnerHTML(R"HTML(
     <style>
diff --git a/third_party/WebKit/Source/core/page/ChromeClientImpl.cpp b/third_party/WebKit/Source/core/page/ChromeClientImpl.cpp
index ce8e972d4..e8434291 100644
--- a/third_party/WebKit/Source/core/page/ChromeClientImpl.cpp
+++ b/third_party/WebKit/Source/core/page/ChromeClientImpl.cpp
@@ -550,8 +550,7 @@
   NotifyPopupOpeningObservers();
   ColorChooserUIController* controller = nullptr;
 
-  // TODO(crbug.com/779126): add support for the chooser in immersive mode.
-  if (frame->GetDocument()->GetSettings()->GetImmersiveModeEnabled())
+  if (frame->GetDocument()->GetSettings()->GetPagePopupsSuppressed())
     return nullptr;
 
   if (RuntimeEnabledFeatures::PagePopupEnabled()) {
@@ -567,11 +566,10 @@
 DateTimeChooser* ChromeClientImpl::OpenDateTimeChooser(
     DateTimeChooserClient* picker_client,
     const DateTimeChooserParameters& parameters) {
-  // TODO(crbug.com/779126): add support for the chooser in immersive mode.
   if (picker_client->OwnerElement()
           .GetDocument()
           .GetSettings()
-          ->GetImmersiveModeEnabled())
+          ->GetPagePopupsSuppressed())
     return nullptr;
 
   NotifyPopupOpeningObservers();
@@ -774,8 +772,7 @@
 
 PopupMenu* ChromeClientImpl::OpenPopupMenu(LocalFrame& frame,
                                            HTMLSelectElement& select) {
-  // TODO(crbug.com/779126): add support for the menu in immersive mode.
-  if (frame.GetDocument()->GetSettings()->GetImmersiveModeEnabled())
+  if (frame.GetDocument()->GetSettings()->GetPagePopupsSuppressed())
     return nullptr;
 
   NotifyPopupOpeningObservers();
diff --git a/third_party/WebKit/Source/core/page/ChromeClientImplTest.cpp b/third_party/WebKit/Source/core/page/ChromeClientImplTest.cpp
index f291c12..91dd605 100644
--- a/third_party/WebKit/Source/core/page/ChromeClientImplTest.cpp
+++ b/third_party/WebKit/Source/core/page/ChromeClientImplTest.cpp
@@ -161,9 +161,6 @@
   Member<Element> owner_element_;
 };
 
-// TODO(crbug.com/779126): A number of popups are not supported in immersive
-// mode. The PagePopupSuppressionTests ensure that these unsupported popups
-// do not appear in immersive mode.
 class PagePopupSuppressionTest : public ::testing::Test {
  public:
   PagePopupSuppressionTest() = default;
@@ -221,11 +218,11 @@
   EXPECT_TRUE(CanOpenColorChooser());
 
   Settings* settings = GetSettings();
-  settings->SetImmersiveModeEnabled(true);
+  settings->SetPagePopupsSuppressed(true);
 
   EXPECT_FALSE(CanOpenColorChooser());
 
-  settings->SetImmersiveModeEnabled(false);
+  settings->SetPagePopupsSuppressed(false);
   EXPECT_TRUE(CanOpenColorChooser());
 }
 
@@ -234,11 +231,11 @@
   EXPECT_TRUE(CanOpenDateTimeChooser());
 
   Settings* settings = GetSettings();
-  settings->SetImmersiveModeEnabled(true);
+  settings->SetPagePopupsSuppressed(true);
 
   EXPECT_FALSE(CanOpenDateTimeChooser());
 
-  settings->SetImmersiveModeEnabled(false);
+  settings->SetPagePopupsSuppressed(false);
   EXPECT_TRUE(CanOpenDateTimeChooser());
 }
 
@@ -247,11 +244,11 @@
   EXPECT_TRUE(CanOpenPopupMenu());
 
   Settings* settings = GetSettings();
-  settings->SetImmersiveModeEnabled(true);
+  settings->SetPagePopupsSuppressed(true);
 
   EXPECT_FALSE(CanOpenPopupMenu());
 
-  settings->SetImmersiveModeEnabled(false);
+  settings->SetPagePopupsSuppressed(false);
   EXPECT_TRUE(CanOpenPopupMenu());
 }
 
diff --git a/third_party/WebKit/Source/modules/locks/Lock.cpp b/third_party/WebKit/Source/modules/locks/Lock.cpp
index c3a2e1c..830aa0a 100644
--- a/third_party/WebKit/Source/modules/locks/Lock.cpp
+++ b/third_party/WebKit/Source/modules/locks/Lock.cpp
@@ -6,6 +6,7 @@
 
 #include "bindings/core/v8/ScriptPromise.h"
 #include "bindings/core/v8/ScriptPromiseResolver.h"
+#include "core/dom/DOMException.h"
 #include "core/dom/ExecutionContext.h"
 #include "modules/locks/LockManager.h"
 #include "platform/bindings/ScriptState.h"
@@ -76,6 +77,9 @@
       handle_(std::move(handle)),
       manager_(manager) {
   PauseIfNeeded();
+
+  handle_.set_connection_error_handler(
+      WTF::Bind(&Lock::OnConnectionError, WrapWeakPersistent(this)));
 }
 
 Lock::~Lock() = default;
@@ -138,4 +142,9 @@
   }
 }
 
+void Lock::OnConnectionError() {
+  resolver_->Reject(DOMException::Create(
+      kAbortError, "Lock broken by another request with the 'steal' option."));
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/locks/Lock.h b/third_party/WebKit/Source/modules/locks/Lock.h
index 1cdfac3..416f91c 100644
--- a/third_party/WebKit/Source/modules/locks/Lock.h
+++ b/third_party/WebKit/Source/modules/locks/Lock.h
@@ -60,6 +60,8 @@
 
   void ReleaseIfHeld();
 
+  void OnConnectionError();
+
   Member<ScriptPromiseResolver> resolver_;
 
   const String name_;
diff --git a/third_party/WebKit/Source/modules/locks/LockManager.cpp b/third_party/WebKit/Source/modules/locks/LockManager.cpp
index f7bd1c94..c6125de 100644
--- a/third_party/WebKit/Source/modules/locks/LockManager.cpp
+++ b/third_party/WebKit/Source/modules/locks/LockManager.cpp
@@ -205,9 +205,25 @@
 
   mojom::blink::LockMode mode = Lock::StringToMode(options.mode());
 
+  if (options.steal() && options.ifAvailable()) {
+    exception_state.ThrowDOMException(
+        kNotSupportedError,
+        "The 'steal' and 'ifAvailable' options cannot be used together.");
+    return ScriptPromise();
+  }
+
+  if (options.steal() && mode != mojom::blink::LockMode::EXCLUSIVE) {
+    exception_state.ThrowDOMException(
+        kNotSupportedError,
+        "The 'steal' option may only be used with 'exclusive' locks.");
+    return ScriptPromise();
+  }
+
   mojom::blink::LockManager::WaitMode wait =
-      options.ifAvailable() ? mojom::blink::LockManager::WaitMode::NO_WAIT
-                            : mojom::blink::LockManager::WaitMode::WAIT;
+      options.steal()
+          ? mojom::blink::LockManager::WaitMode::PREEMPT
+          : options.ifAvailable() ? mojom::blink::LockManager::WaitMode::NO_WAIT
+                                  : mojom::blink::LockManager::WaitMode::WAIT;
 
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   ScriptPromise promise = resolver->Promise();
diff --git a/third_party/WebKit/Source/modules/locks/LockOptions.idl b/third_party/WebKit/Source/modules/locks/LockOptions.idl
index 18d4ed2..7659b79 100644
--- a/third_party/WebKit/Source/modules/locks/LockOptions.idl
+++ b/third_party/WebKit/Source/modules/locks/LockOptions.idl
@@ -8,5 +8,6 @@
 dictionary LockOptions {
     LockMode mode = "exclusive";
     boolean ifAvailable = false;
+    boolean steal = false;
     // TODO(jsbell): AbortSignal signal;
 };
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
index d374b41..995ce8f3 100644
--- a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
+++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
@@ -813,9 +813,9 @@
                                            "Cannot show the payment request"));
   }
 
-  // TODO(crbug.com/779126): add support for handling payment requests in
-  // immersive mode.
-  if (GetFrame()->GetDocument()->GetSettings()->GetImmersiveModeEnabled()) {
+  // VR mode uses popup suppression setting to disable html select element,
+  // date pickers, etc.
+  if (GetFrame()->GetDocument()->GetSettings()->GetPagePopupsSuppressed()) {
     return ScriptPromise::RejectWithDOMException(
         script_state,
         DOMException::Create(kInvalidStateError, "Page popups are suppressed"));
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioListener.cpp b/third_party/WebKit/Source/modules/webaudio/AudioListener.cpp
index 5ff2cad..5953e55 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioListener.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/AudioListener.cpp
@@ -271,37 +271,52 @@
     panner->MarkPannerAsDirty(type);
 }
 
-void AudioListener::setPosition(const FloatPoint3D& position) {
+void AudioListener::setPosition(const FloatPoint3D& position,
+                                ExceptionState& exceptionState) {
   DCHECK(IsMainThread());
 
   // This synchronizes with panner's process().
   MutexLocker listener_locker(listener_lock_);
-  position_x_->setValue(position.X());
-  position_y_->setValue(position.Y());
-  position_z_->setValue(position.Z());
+
+  double now = position_x_->Context()->currentTime();
+
+  position_x_->setValueAtTime(position.X(), now, exceptionState);
+  position_y_->setValueAtTime(position.Y(), now, exceptionState);
+  position_z_->setValueAtTime(position.Z(), now, exceptionState);
+
   MarkPannersAsDirty(PannerHandler::kAzimuthElevationDirty |
                      PannerHandler::kDistanceConeGainDirty);
 }
 
-void AudioListener::setOrientation(const FloatPoint3D& orientation) {
+void AudioListener::setOrientation(const FloatPoint3D& orientation,
+                                   ExceptionState& exceptionState) {
   DCHECK(IsMainThread());
 
   // This synchronizes with panner's process().
   MutexLocker listener_locker(listener_lock_);
-  forward_x_->setValue(orientation.X());
-  forward_y_->setValue(orientation.Y());
-  forward_z_->setValue(orientation.Z());
+
+  double now = forward_x_->Context()->currentTime();
+
+  forward_x_->setValueAtTime(orientation.X(), now, exceptionState);
+  forward_y_->setValueAtTime(orientation.Y(), now, exceptionState);
+  forward_z_->setValueAtTime(orientation.Z(), now, exceptionState);
+
   MarkPannersAsDirty(PannerHandler::kAzimuthElevationDirty);
 }
 
-void AudioListener::SetUpVector(const FloatPoint3D& up_vector) {
+void AudioListener::SetUpVector(const FloatPoint3D& up_vector,
+                                ExceptionState& exceptionState) {
   DCHECK(IsMainThread());
 
   // This synchronizes with panner's process().
   MutexLocker listener_locker(listener_lock_);
-  up_x_->setValue(up_vector.X());
-  up_y_->setValue(up_vector.Y());
-  up_z_->setValue(up_vector.Z());
+
+  double now = up_x_->Context()->currentTime();
+
+  up_x_->setValueAtTime(up_vector.X(), now, exceptionState);
+  up_y_->setValueAtTime(up_vector.Y(), now, exceptionState);
+  up_z_->setValueAtTime(up_vector.Z(), now, exceptionState);
+
   MarkPannersAsDirty(PannerHandler::kAzimuthElevationDirty);
 }
 
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioListener.h b/third_party/WebKit/Source/modules/webaudio/AudioListener.h
index 4abc99a..063d554 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioListener.h
+++ b/third_party/WebKit/Source/modules/webaudio/AudioListener.h
@@ -100,8 +100,8 @@
   const float* GetUpZValues(size_t frames_to_process);
 
   // Position
-  void setPosition(float x, float y, float z) {
-    setPosition(FloatPoint3D(x, y, z));
+  void setPosition(float x, float y, float z, ExceptionState& exceptionState) {
+    setPosition(FloatPoint3D(x, y, z), exceptionState);
   }
 
   // Orientation and Up-vector
@@ -110,9 +110,10 @@
                       float z,
                       float up_x,
                       float up_y,
-                      float up_z) {
-    setOrientation(FloatPoint3D(x, y, z));
-    SetUpVector(FloatPoint3D(up_x, up_y, up_z));
+                      float up_z,
+                      ExceptionState& exceptionState) {
+    setOrientation(FloatPoint3D(x, y, z), exceptionState);
+    SetUpVector(FloatPoint3D(up_x, up_y, up_z), exceptionState);
   }
 
   Mutex& ListenerLock() { return listener_lock_; }
@@ -132,9 +133,9 @@
  private:
   AudioListener(BaseAudioContext&);
 
-  void setPosition(const FloatPoint3D&);
-  void setOrientation(const FloatPoint3D&);
-  void SetUpVector(const FloatPoint3D&);
+  void setPosition(const FloatPoint3D&, ExceptionState&);
+  void setOrientation(const FloatPoint3D&, ExceptionState&);
+  void SetUpVector(const FloatPoint3D&, ExceptionState&);
 
   void MarkPannersAsDirty(unsigned);
 
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioListener.idl b/third_party/WebKit/Source/modules/webaudio/AudioListener.idl
index 7cc1cd7..e4af5a6 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioListener.idl
+++ b/third_party/WebKit/Source/modules/webaudio/AudioListener.idl
@@ -28,8 +28,8 @@
 
 // See https://webaudio.github.io/web-audio-api/#AudioListener
 interface AudioListener {
-    [MeasureAs=AudioListenerSetPosition] void setPosition(float x, float y, float z);
-    [MeasureAs=AudioListenerSetOrientation] void setOrientation(float x, float y, float z, float xUp, float yUp, float zUp);
+    [RaisesException, MeasureAs=AudioListenerSetPosition] void setPosition(float x, float y, float z);
+    [RaisesException, MeasureAs=AudioListenerSetOrientation] void setOrientation(float x, float y, float z, float xUp, float yUp, float zUp);
 
     // Location of the listener
     readonly attribute AudioParam positionX;
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParam.cpp b/third_party/WebKit/Source/modules/webaudio/AudioParam.cpp
index 2fbab0f4..4c1990f 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioParam.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/AudioParam.cpp
@@ -303,6 +303,17 @@
   Handler().SetValue(value);
 }
 
+void AudioParam::setValue(float value, ExceptionState& exception_state) {
+  WarnIfOutsideRange("value", value);
+
+  // This is to signal any errors, if necessary, about conflicting
+  // automations.
+  setValueAtTime(value, Context()->currentTime(), exception_state);
+  // This is to change the value so that an immediate query for the
+  // value returns the expected values.
+  Handler().SetValue(value);
+}
+
 // TODO(crbug.com/764396): Remove this when fixed.
 void AudioParam::WarnIfSetterOverlapsEvent() {
   DCHECK(IsMainThread());
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParam.h b/third_party/WebKit/Source/modules/webaudio/AudioParam.h
index fc0fdc4..2dd311ff 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioParam.h
+++ b/third_party/WebKit/Source/modules/webaudio/AudioParam.h
@@ -234,6 +234,7 @@
   String GetParamName() const;
 
   float value() const;
+  void setValue(float, ExceptionState&);
   void setValue(float);
   float defaultValue() const;
 
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParam.idl b/third_party/WebKit/Source/modules/webaudio/AudioParam.idl
index 7be04a61a..c9c6283 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioParam.idl
+++ b/third_party/WebKit/Source/modules/webaudio/AudioParam.idl
@@ -28,7 +28,7 @@
 
 // See https://webaudio.github.io/web-audio-api/#AudioParam
 interface AudioParam {
-    attribute float value;
+    [RaisesException=Setter] attribute float value;
     readonly attribute float defaultValue;
 
     // Nominal range for the value.
diff --git a/third_party/WebKit/Source/modules/webaudio/PannerNode.cpp b/third_party/WebKit/Source/modules/webaudio/PannerNode.cpp
index 521ab5a7..0422a3f9 100644
--- a/third_party/WebKit/Source/modules/webaudio/PannerNode.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/PannerNode.cpp
@@ -430,25 +430,35 @@
   MarkPannerAsDirty(PannerHandler::kDistanceConeGainDirty);
 }
 
-void PannerHandler::SetPosition(float x, float y, float z) {
+void PannerHandler::SetPosition(float x,
+                                float y,
+                                float z,
+                                ExceptionState& exceptionState) {
   // This synchronizes with process().
   MutexLocker process_locker(process_lock_);
 
-  position_x_->SetValue(x);
-  position_y_->SetValue(y);
-  position_z_->SetValue(z);
+  double now = Context()->currentTime();
+
+  position_x_->Timeline().SetValueAtTime(x, now, exceptionState);
+  position_y_->Timeline().SetValueAtTime(y, now, exceptionState);
+  position_z_->Timeline().SetValueAtTime(z, now, exceptionState);
 
   MarkPannerAsDirty(PannerHandler::kAzimuthElevationDirty |
                     PannerHandler::kDistanceConeGainDirty);
 }
 
-void PannerHandler::SetOrientation(float x, float y, float z) {
+void PannerHandler::SetOrientation(float x,
+                                   float y,
+                                   float z,
+                                   ExceptionState& exceptionState) {
   // This synchronizes with process().
   MutexLocker process_locker(process_lock_);
 
-  orientation_x_->SetValue(x);
-  orientation_y_->SetValue(y);
-  orientation_z_->SetValue(z);
+  double now = Context()->currentTime();
+
+  orientation_x_->Timeline().SetValueAtTime(x, now, exceptionState);
+  orientation_y_->Timeline().SetValueAtTime(y, now, exceptionState);
+  orientation_z_->Timeline().SetValueAtTime(z, now, exceptionState);
 
   MarkPannerAsDirty(PannerHandler::kDistanceConeGainDirty);
 }
@@ -729,12 +739,18 @@
   GetPannerHandler().SetPanningModel(model);
 }
 
-void PannerNode::setPosition(float x, float y, float z) {
-  GetPannerHandler().SetPosition(x, y, z);
+void PannerNode::setPosition(float x,
+                             float y,
+                             float z,
+                             ExceptionState& exceptionState) {
+  GetPannerHandler().SetPosition(x, y, z, exceptionState);
 }
 
-void PannerNode::setOrientation(float x, float y, float z) {
-  GetPannerHandler().SetOrientation(x, y, z);
+void PannerNode::setOrientation(float x,
+                                float y,
+                                float z,
+                                ExceptionState& exceptionState) {
+  GetPannerHandler().SetOrientation(x, y, z, exceptionState);
 }
 
 String PannerNode::distanceModel() const {
diff --git a/third_party/WebKit/Source/modules/webaudio/PannerNode.h b/third_party/WebKit/Source/modules/webaudio/PannerNode.h
index 1887b6f..83f8e8c 100644
--- a/third_party/WebKit/Source/modules/webaudio/PannerNode.h
+++ b/third_party/WebKit/Source/modules/webaudio/PannerNode.h
@@ -84,8 +84,8 @@
   void SetPanningModel(const String&);
 
   // Position and orientation
-  void SetPosition(float x, float y, float z);
-  void SetOrientation(float x, float y, float z);
+  void SetPosition(float x, float y, float z, ExceptionState&);
+  void SetOrientation(float x, float y, float z, ExceptionState&);
 
   // Distance parameters
   String DistanceModel() const;
@@ -226,8 +226,8 @@
 
   String panningModel() const;
   void setPanningModel(const String&);
-  void setPosition(float x, float y, float z);
-  void setOrientation(float x, float y, float z);
+  void setPosition(float x, float y, float z, ExceptionState&);
+  void setOrientation(float x, float y, float z, ExceptionState&);
   String distanceModel() const;
   void setDistanceModel(const String&);
   double refDistance() const;
diff --git a/third_party/WebKit/Source/modules/webaudio/PannerNode.idl b/third_party/WebKit/Source/modules/webaudio/PannerNode.idl
index e182b198..a47cc5de 100644
--- a/third_party/WebKit/Source/modules/webaudio/PannerNode.idl
+++ b/third_party/WebKit/Source/modules/webaudio/PannerNode.idl
@@ -44,8 +44,8 @@
     attribute PanningModelType panningModel;
 
     // Uses a 3D cartesian coordinate system
-    [MeasureAs=PannerNodeSetPosition] void setPosition(float x, float y, float z);
-    [MeasureAs=PannerNodeSetOrientation] void setOrientation(float x, float y, float z);
+    [RaisesException, MeasureAs=PannerNodeSetPosition] void setPosition(float x, float y, float z);
+    [RaisesException, MeasureAs=PannerNodeSetOrientation] void setOrientation(float x, float y, float z);
 
     // Uses a 3D cartesian coordinate system
     readonly attribute AudioParam positionX;
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBloberizer.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBloberizer.cpp
index 0fb0f70e..5649a47 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBloberizer.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBloberizer.cpp
@@ -170,7 +170,6 @@
   // We want to skip descenders in general, but it is undesirable renderings for
   // CJK characters.
   return bloberizer.GetType() == ShapeResultBloberizer::Type::kTextIntercepts &&
-         !text.Is8Bit() &&
          !Character::CanTextDecorationSkipInk(
              text.CodepointAt(character_index));
 }
diff --git a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoderTest.cpp b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoderTest.cpp
index ee2966e..26711ec 100644
--- a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoderTest.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoderTest.cpp
@@ -1002,4 +1002,19 @@
   EXPECT_TRUE(decoder->Failed());
 }
 
+TEST(PNGTests, truncated) {
+  auto decoder = CreatePNGDecoderWithPngData(
+      "/LayoutTests/images/resources/crbug807324.png");
+
+  // An update to libpng (without using the libpng-provided workaround) resulted
+  // in truncating this image. It has no transparency, so no pixel should be
+  // transparent.
+  auto* frame = decoder->DecodeFrameBufferAtIndex(0);
+  auto size = decoder->Size();
+  for (int i = 0; i < size.Width();  ++i)
+  for (int j = 0; j < size.Height(); ++j) {
+    ASSERT_NE(SK_ColorTRANSPARENT, *frame->GetAddr(i, j));
+  }
+}
+
 };  // namespace blink
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
index e50a831..75d80cd 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
@@ -1296,8 +1296,6 @@
 }
 
 void ResourceFetcher::ClearPreloads(ClearPreloadsPolicy policy) {
-  LogPreloadStats(policy);
-
   Vector<PreloadKey> keys_to_be_removed;
   for (const auto& pair : preloads_) {
     Resource* resource = pair.value;
@@ -1600,153 +1598,6 @@
   }
 }
 
-void ResourceFetcher::LogPreloadStats(ClearPreloadsPolicy policy) {
-  unsigned scripts = 0;
-  unsigned script_misses = 0;
-  unsigned stylesheets = 0;
-  unsigned stylesheet_misses = 0;
-  unsigned images = 0;
-  unsigned image_misses = 0;
-  unsigned fonts = 0;
-  unsigned font_misses = 0;
-  unsigned medias = 0;
-  unsigned media_misses = 0;
-  unsigned text_tracks = 0;
-  unsigned text_track_misses = 0;
-  unsigned imports = 0;
-  unsigned import_misses = 0;
-  unsigned raws = 0;
-  unsigned raw_misses = 0;
-  for (const auto& pair : preloads_) {
-    Resource* resource = pair.value;
-    // Do not double count link rel preloads. These do not get cleared if the
-    // ClearPreloadsPolicy is only clearing speculative markup preloads.
-    if (resource->IsLinkPreload() &&
-        policy == kClearSpeculativeMarkupPreloads) {
-      continue;
-    }
-    int miss_count = resource->IsUnusedPreload() ? 1 : 0;
-    switch (resource->GetType()) {
-      case Resource::kImage:
-        images++;
-        image_misses += miss_count;
-        break;
-      case Resource::kScript:
-        scripts++;
-        script_misses += miss_count;
-        break;
-      case Resource::kCSSStyleSheet:
-        stylesheets++;
-        stylesheet_misses += miss_count;
-        break;
-      case Resource::kFont:
-        fonts++;
-        font_misses += miss_count;
-        break;
-      case Resource::kAudio:
-      case Resource::kVideo:
-        medias++;
-        media_misses += miss_count;
-        break;
-      case Resource::kTextTrack:
-        text_tracks++;
-        text_track_misses += miss_count;
-        break;
-      case Resource::kImportResource:
-        imports++;
-        import_misses += miss_count;
-        break;
-      case Resource::kRaw:
-        raws++;
-        raw_misses += miss_count;
-        break;
-      case Resource::kMock:
-        // Do not count Resource::Mock because this type is only for testing.
-        break;
-      default:
-        NOTREACHED();
-    }
-  }
-
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, image_preloads,
-                                  ("PreloadScanner.Counts2.Image", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, image_preload_misses,
-      ("PreloadScanner.Counts2.Miss.Image", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, script_preloads,
-      ("PreloadScanner.Counts2.Script", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, script_preload_misses,
-      ("PreloadScanner.Counts2.Miss.Script", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, stylesheet_preloads,
-      ("PreloadScanner.Counts2.CSSStyleSheet", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, stylesheet_preload_misses,
-      ("PreloadScanner.Counts2.Miss.CSSStyleSheet", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, font_preloads,
-                                  ("PreloadScanner.Counts2.Font", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, font_preload_misses,
-      ("PreloadScanner.Counts2.Miss.Font", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, media_preloads,
-                                  ("PreloadScanner.Counts2.Media", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, media_preload_misses,
-      ("PreloadScanner.Counts2.Miss.Media", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, text_track_preloads,
-      ("PreloadScanner.Counts2.TextTrack", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, text_track_preload_misses,
-      ("PreloadScanner.Counts2.Miss.TextTrack", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, import_preloads,
-      ("PreloadScanner.Counts2.Import", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, import_preload_misses,
-      ("PreloadScanner.Counts2.Miss.Import", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, raw_preloads,
-                                  ("PreloadScanner.Counts2.Raw", 0, 100, 25));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, raw_preload_misses,
-      ("PreloadScanner.Counts2.Miss.Raw", 0, 100, 25));
-
-  if (images)
-    image_preloads.Count(images);
-  if (image_misses)
-    image_preload_misses.Count(image_misses);
-  if (scripts)
-    script_preloads.Count(scripts);
-  if (script_misses)
-    script_preload_misses.Count(script_misses);
-  if (stylesheets)
-    stylesheet_preloads.Count(stylesheets);
-  if (stylesheet_misses)
-    stylesheet_preload_misses.Count(stylesheet_misses);
-  if (fonts)
-    font_preloads.Count(fonts);
-  if (font_misses)
-    font_preload_misses.Count(font_misses);
-  if (medias)
-    media_preloads.Count(medias);
-  if (media_misses)
-    media_preload_misses.Count(media_misses);
-  if (text_tracks)
-    text_track_preloads.Count(text_tracks);
-  if (text_track_misses)
-    text_track_preload_misses.Count(text_track_misses);
-  if (imports)
-    import_preloads.Count(imports);
-  if (import_misses)
-    import_preload_misses.Count(import_misses);
-  if (raws)
-    raw_preloads.Count(raws);
-  if (raw_misses)
-    raw_preload_misses.Count(raw_misses);
-}
-
 String ResourceFetcher::GetCacheIdentifier() const {
   if (Context().IsControlledByServiceWorker())
     return String::Number(Context().ServiceWorkerID());
diff --git a/third_party/WebKit/Source/platform/memory_profiler/SamplingNativeHeapProfiler.cpp b/third_party/WebKit/Source/platform/memory_profiler/SamplingNativeHeapProfiler.cpp
index 4343c4b9..dbba847 100644
--- a/third_party/WebKit/Source/platform/memory_profiler/SamplingNativeHeapProfiler.cpp
+++ b/third_party/WebKit/Source/platform/memory_profiler/SamplingNativeHeapProfiler.cpp
@@ -28,7 +28,9 @@
 
 bool g_deterministic;
 Atomic32 g_running;
-AtomicWord g_cumulative_counter = 0;
+Atomic32 g_operations_in_flight;
+Atomic32 g_fast_path_is_closed;
+AtomicWord g_cumulative_counter;
 AtomicWord g_threshold = kDefaultSamplingInterval;
 AtomicWord g_sampling_interval = kDefaultSamplingInterval;
 uint32_t g_last_sample_ordinal = 0;
@@ -216,7 +218,6 @@
   // Lock-free algorithm that adds the allocation size to the cumulative
   // counter. When the counter reaches threshold, it picks a single thread
   // that will record the sample and reset the counter.
-  // The thread that records the sample returns true, others return false.
   AtomicWord threshold = base::subtle::NoBarrier_Load(&g_threshold);
   AtomicWord accumulated = base::subtle::NoBarrier_AtomicIncrement(
       &g_cumulative_counter, static_cast<AtomicWord>(size));
@@ -265,15 +266,32 @@
   size_t count = std::max<size_t>(1, (total_allocated + size / 2) / size);
   Sample sample(size, count, ++g_last_sample_ordinal);
   RecordStackTrace(&sample, skip_frames);
+
+  // Close the fast-path as inserting an element into samples_ may cause
+  // rehashing that invalidates iterators affecting all the concurrent
+  // readers.
+  base::subtle::Release_Store(&g_fast_path_is_closed, 1);
+  while (base::subtle::Acquire_Load(&g_operations_in_flight)) {
+    while (base::subtle::NoBarrier_Load(&g_operations_in_flight)) {
+    }
+  }
+  // TODO(alph): We can do better by keeping the fast-path open when
+  // we know insert won't cause rehashing.
   samples_.insert(std::make_pair(address, std::move(sample)));
+  base::subtle::Release_Store(&g_fast_path_is_closed, 0);
 
   entered_.Set(false);
 }
 
 // static
 void SamplingNativeHeapProfiler::MaybeRecordFree(void* address) {
-  // TODO(alph): Implement a fast path without locking a mutex.
-  g_instance->RecordFree(address);
+  bool maybe_sampled = true;  // Pessimistically assume allocation was sampled.
+  base::subtle::Barrier_AtomicIncrement(&g_operations_in_flight, 1);
+  if (LIKELY(!base::subtle::NoBarrier_Load(&g_fast_path_is_closed)))
+    maybe_sampled = g_instance->samples_.count(address);
+  base::subtle::Barrier_AtomicIncrement(&g_operations_in_flight, -1);
+  if (maybe_sampled)
+    g_instance->RecordFree(address);
 }
 
 void SamplingNativeHeapProfiler::RecordFree(void* address) {
diff --git a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
index 071a3b427..256593e 100644
--- a/third_party/WebKit/Source/platform/runtime_enabled_features.json5
+++ b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
@@ -766,7 +766,7 @@
     },
     {
       name: "PageLifecycle",
-      status: "test",
+      status: "experimental",
     },
     {
       name: "PagePopup",
diff --git a/third_party/WebKit/Source/platform/text/Character.cpp b/third_party/WebKit/Source/platform/text/Character.cpp
index ec7766a1..aa971ab 100644
--- a/third_party/WebKit/Source/platform/text/Character.cpp
+++ b/third_party/WebKit/Source/platform/text/Character.cpp
@@ -208,6 +208,10 @@
 }
 
 bool Character::CanTextDecorationSkipInk(UChar32 codepoint) {
+  if (codepoint == kSolidusCharacter || codepoint == kReverseSolidusCharacter ||
+      codepoint == kLowLineCharacter)
+    return false;
+
   if (Character::IsCJKIdeographOrSymbol(codepoint))
     return false;
 
diff --git a/third_party/WebKit/Source/platform/wtf/text/CharacterNames.h b/third_party/WebKit/Source/platform/wtf/text/CharacterNames.h
index 7c1fe77e..fb449cc8 100644
--- a/third_party/WebKit/Source/platform/wtf/text/CharacterNames.h
+++ b/third_party/WebKit/Source/platform/wtf/text/CharacterNames.h
@@ -103,6 +103,7 @@
 const UChar kPopDirectionalIsolateCharacter = 0x2069;
 const UChar32 kRainbowCharacter = 0x1F308;
 const UChar kReplacementCharacter = 0xFFFD;
+const UChar kReverseSolidusCharacter = 0x005C;
 const UChar kRightDoubleQuotationMarkCharacter = 0x201D;
 const UChar kRightSingleQuotationMarkCharacter = 0x2019;
 const UChar kRightToLeftEmbedCharacter = 0x202B;
@@ -111,6 +112,7 @@
 const UChar kRightToLeftOverrideCharacter = 0x202E;
 const UChar kSesameDotCharacter = 0xFE45;
 const UChar kSmallLetterSharpSCharacter = 0x00DF;
+const UChar kSolidusCharacter = 0x002F;
 const UChar kSoftHyphenCharacter = 0x00AD;
 const UChar kSpaceCharacter = 0x0020;
 const UChar kStaffOfAesculapiusCharacter = 0x2695;
@@ -198,6 +200,7 @@
 using WTF::Unicode::kPopDirectionalIsolateCharacter;
 using WTF::Unicode::kRainbowCharacter;
 using WTF::Unicode::kReplacementCharacter;
+using WTF::Unicode::kReverseSolidusCharacter;
 using WTF::Unicode::kRightDoubleQuotationMarkCharacter;
 using WTF::Unicode::kRightSingleQuotationMarkCharacter;
 using WTF::Unicode::kRightToLeftEmbedCharacter;
@@ -207,6 +210,7 @@
 using WTF::Unicode::kSesameDotCharacter;
 using WTF::Unicode::kSmallLetterSharpSCharacter;
 using WTF::Unicode::kSoftHyphenCharacter;
+using WTF::Unicode::kSolidusCharacter;
 using WTF::Unicode::kSpaceCharacter;
 using WTF::Unicode::kStaffOfAesculapiusCharacter;
 using WTF::Unicode::kTabulationCharacter;
diff --git a/third_party/WebKit/public/platform/modules/locks/lock_manager.mojom b/third_party/WebKit/public/platform/modules/locks/lock_manager.mojom
index 91e8c55..e0eae77 100644
--- a/third_party/WebKit/public/platform/modules/locks/lock_manager.mojom
+++ b/third_party/WebKit/public/platform/modules/locks/lock_manager.mojom
@@ -23,6 +23,7 @@
   Abort(string reason);
 };
 
+// Corresponds to the |mode| enum option in the Web Locks API.
 enum LockMode {
   SHARED,
   EXCLUSIVE
@@ -48,9 +49,14 @@
 // Proposal: https://github.com/inexorabletash/web-locks
 
 interface LockManager {
+  // PREEMPT corresponds to the |steal| option in the API; if used then
+  // all previous locks with the same name are released.
+  // NO_WAIT corresponds to |ifAvailable| option in the API; if used then
+  // the request fails if it cannot be granted immediately.
   enum WaitMode {
     WAIT,
-    NO_WAIT
+    NO_WAIT,
+    PREEMPT
   };
 
   // Request a lock. One of |request|'s methods will be called
diff --git a/third_party/WebKit/public/web/WebSettings.h b/third_party/WebKit/public/web/WebSettings.h
index 2eb78310..0b55aa3 100644
--- a/third_party/WebKit/public/web/WebSettings.h
+++ b/third_party/WebKit/public/web/WebSettings.h
@@ -211,7 +211,7 @@
   virtual void SetMediaPlaybackGestureWhitelistScope(const WebString&) = 0;
   virtual void SetPresentationRequiresUserGesture(bool) = 0;
   virtual void SetEmbeddedMediaExperienceEnabled(bool) = 0;
-  virtual void SetImmersiveModeEnabled(bool) = 0;
+  virtual void SetPagePopupsSuppressed(bool) = 0;
   virtual void SetMinimumAccelerated2dCanvasSize(int) = 0;
   virtual void SetMinimumFontSize(int) = 0;
   virtual void SetMinimumLogicalFontSize(int) = 0;
diff --git a/third_party/glslang/BUILD.gn b/third_party/glslang/BUILD.gn
index 9061e37..e448631b 100644
--- a/third_party/glslang/BUILD.gn
+++ b/third_party/glslang/BUILD.gn
@@ -20,10 +20,9 @@
 config("glslang_local_config") {
   if (is_clang) {
     cflags = [
-      "-Wno-tautological-constant-out-of-range-compare",
       "-Wno-reorder",
       "-Wno-sign-compare",
-      "-Wno-unused-variable",
+      "-Wno-tautological-constant-out-of-range-compare",
     ]
   }
 }
@@ -35,6 +34,8 @@
   ]
 
   all_dependent_configs = [ ":glslang_config" ]
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [ "//build/config/compiler:no_chromium_code" ]
   configs += [ ":glslang_local_config" ]
 }
 
@@ -59,6 +60,8 @@
   ]
 
   all_dependent_configs = [ ":glslang_config" ]
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [ "//build/config/compiler:no_chromium_code" ]
   configs += [ ":glslang_local_config" ]
 }
 
@@ -68,6 +71,8 @@
   ]
 
   all_dependent_configs = [ ":glslang_config" ]
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [ "//build/config/compiler:no_chromium_code" ]
   configs += [ ":glslang_local_config" ]
 }
 
@@ -144,6 +149,8 @@
   }
 
   all_dependent_configs = [ ":glslang_config" ]
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [ "//build/config/compiler:no_chromium_code" ]
   configs += [ ":glslang_local_config" ]
 }
 
@@ -163,6 +170,8 @@
   ]
 
   all_dependent_configs = [ ":glslang_config" ]
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [ "//build/config/compiler:no_chromium_code" ]
   configs += [ ":glslang_local_config" ]
 }
 
diff --git a/third_party/libpng/BUILD.gn b/third_party/libpng/BUILD.gn
index 8ea4214..ebd7bd5 100644
--- a/third_party/libpng/BUILD.gn
+++ b/third_party/libpng/BUILD.gn
@@ -67,14 +67,15 @@
 
   if (current_cpu == "x86" || current_cpu == "x64") {
     sources += [
-      "contrib/intel/filter_sse2_intrinsics.c",
-      "contrib/intel/intel_init.c",
+      "intel/filter_sse2_intrinsics.c",
+      "intel/intel_init.c",
     ]
     defines += [ "PNG_INTEL_SSE_OPT=1" ]
   } else if ((current_cpu == "arm" || current_cpu == "arm64") && arm_use_neon) {
     sources += [
       "arm/arm_init.c",
       "arm/filter_neon_intrinsics.c",
+      "arm/palette_neon_intrinsics.c",
     ]
     defines += [
       "PNG_ARM_NEON_OPT=2",
diff --git a/third_party/libpng/LICENSE b/third_party/libpng/LICENSE
index 30dc124..c1d22b1f 100644
--- a/third_party/libpng/LICENSE
+++ b/third_party/libpng/LICENSE
@@ -12,8 +12,8 @@
 
 This code is released under the libpng license.
 
-libpng versions 1.0.7, July 1, 2000 through 1.6.22, May 26, 2016 are
-Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are
+libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are
+Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
 derived from libpng-1.0.6, and are distributed according to the same
 disclaimer and license as libpng-1.0.6 with the following individuals
 added to the list of Contributing Authors:
@@ -24,6 +24,9 @@
    Cosmin Truta
    Gilles Vollant
    James Yu
+   Mandar Sahastrabuddhe
+   Google Inc.
+   Vadim Barkov
 
 and with the following additions to the disclaimer:
 
@@ -129,4 +132,4 @@
 
 Glenn Randers-Pehrson
 glennrp at users.sourceforge.net
-May 26, 2016
+September 29, 2017
diff --git a/third_party/libpng/README b/third_party/libpng/README
index dc5b52c0..0da5a5e 100644
--- a/third_party/libpng/README
+++ b/third_party/libpng/README
@@ -1,4 +1,4 @@
-README for libpng version 1.6.22 - May 26, 2016 (shared library 16.0)
+README for libpng version 1.6.34 - September 29, 2017 (shared library 16.0)
 See the note about version numbers near the top of png.h
 
 See INSTALL for instructions on how to install libpng.
@@ -23,7 +23,7 @@
 png_uint_32, which will affect shared-library applications that use
 this function.
 
-To avoid problems with changes to the internals of png info_struct,
+To avoid problems with changes to the internals of the png info_struct,
 new APIs have been made available in 0.95 to avoid direct application
 access to info_ptr.  These functions are the png_set_<chunk> and
 png_get_<chunk> functions.  These functions should be used when
@@ -88,11 +88,11 @@
 
 You may also want a copy of the PNG specification.  It is available
 as an RFC, a W3C Recommendation, and an ISO/IEC Standard.  You can find
-these at http://www.libpng.org/pub/png/documents/
+these at http://www.libpng.org/pub/png/pngdocs.html .
 
-This code is currently being archived at libpng.sf.net in the
-[DOWNLOAD] area, and at ftp://ftp.simplesystems.org.  If you can't find it
-in any of those places, e-mail me, and I'll help you find it.
+This code is currently being archived at libpng.sourceforge.io in the
+[DOWNLOAD] area, and at http://libpng.download/src .  If you
+can't find it in any of those places, e-mail me, and I'll help you find it.
 
 I am not a lawyer, but I believe that the Export Control Classification
 Number (ECCN) for libpng is EAR99, which means not subject to export
@@ -179,18 +179,25 @@
       pngwtran.c    =>  Write data transformations
       pngwutil.c    =>  Write utility functions
       arm           =>  Contains optimized code for the ARM platform
+      powerpc       =>  Contains optimized code for the PowerPC platform
       contrib       =>  Contributions
+       arm-neon         =>  Optimized code for ARM-NEON platform
+       powerpc-vsx      =>  Optimized code for POWERPC-VSX platform
        examples         =>  Example programs
        gregbook         =>  source code for PNG reading and writing, from
                             Greg Roelofs' "PNG: The Definitive Guide",
                             O'Reilly, 1999
        libtests         =>  Test programs
+       mips-msa         =>  Optimized code for MIPS-MSA platform
        pngminim         =>  Minimal decoder, encoder, and progressive decoder
                             programs demonstrating use of pngusr.dfa
        pngminus         =>  Simple pnm2png and png2pnm programs
        pngsuite         =>  Test images
+       testpngs
        tools            =>  Various tools
        visupng          =>  Contains a MSVC workspace for VisualPng
+      intel             =>  Optimized code for INTEL-SSE2 platform
+      mips              =>  Optimized code for MIPS platform
       projects      =>  Contains project files and workspaces for
                         building a DLL
        owatcom          =>  Contains a WATCOM project for building libpng
diff --git a/third_party/libpng/README.chromium b/third_party/libpng/README.chromium
index 2a38134..b4a0bba6 100644
--- a/third_party/libpng/README.chromium
+++ b/third_party/libpng/README.chromium
@@ -1,31 +1,15 @@
 Name: libpng
 URL: http://libpng.org/
-Version: 1.6.22
+Version: 1.6.34
 Security Critical: yes
 License: libpng license
 License Android Compatible: yes
 
 Description:
-Updated to 1.6.22, stripped all unneeded files.
+Updated to 1.6.34, stripped all unneeded files.
 
-- Turn on SSE optimizations for Intel platforms by running:
-  "patch -i contrib/intel/intel_sse.patch -p1"
 - Use custom configuration file pnglibconf.h, which turns off all features that
   are not in use.
 - Use custom prefix file pngprefix.h, which avoids namespace conflicts with
   pdfium's copy of libpng.
 - Configures custom png chunk user limits (crbug.com/117369) in pnglibconf.h.
-- Fix for potential memory leak from upstream:
-  https://github.com/glennrp/libpng/commit/8d1672537324d99c6e65eb78fc1678cdd46f75bd
-  https://github.com/glennrp/libpng/commit/6c7459e455a4f7d95c7700e9326bb12396e6eb1f
-- Fix for handling empty first IDAT chunk from upstream:
-  https://github.com/glennrp/libpng/commit/3f46c67c6989f480bd932428aa1705f6625dbabf
-  https://github.com/glennrp/libpng/commit/81f0273d54aa9de663253b197b3c8228d659cc36
-- Fix performance regression in png encoding (and overflow handling in filter heuristic)
-  from upstream (crbug.com/619850):
-  https://github.com/glennrp/libpng/commit/9c04f57cabbf736e91b831858d0eeecca703eabf
-  https://github.com/glennrp/libpng/commit/f7d5419816d85d0b996c403e788bb707b552524f
-- Avoid leaking params on bad pCAL chunk from upstream (crbug.com/636214):
-  https://github.com/glennrp/libpng/commit/7dc03292502cf91a116766d2ab2c4f8fc23e4ab4
-- Fix for large allocation for invalid ICC (crbug.com/729673)
-  https://github.com/glennrp/libpng/commit/92a7c79db2c962d04006b35e2603ba9d5ce75541
diff --git a/third_party/libpng/arm/filter_neon.S b/third_party/libpng/arm/filter_neon.S
index 3b061d6..000764cd 100644
--- a/third_party/libpng/arm/filter_neon.S
+++ b/third_party/libpng/arm/filter_neon.S
@@ -1,9 +1,9 @@
 
 /* filter_neon.S - NEON optimised filter functions
  *
- * Copyright (c) 2014 Glenn Randers-Pehrson
+ * Copyright (c) 2014,2017 Glenn Randers-Pehrson
  * Written by Mans Rullgard, 2011.
- * Last changed in libpng 1.6.16 [December 22, 2014]
+ * Last changed in libpng 1.6.31 [July 27, 2017]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -16,7 +16,7 @@
 #define PNG_VERSION_INFO_ONLY
 #include "../pngpriv.h"
 
-#if defined(__linux__) && defined(__ELF__)
+#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__)
 .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
 #endif
 
diff --git a/third_party/libpng/arm/palette_neon_intrinsics.c b/third_party/libpng/arm/palette_neon_intrinsics.c
new file mode 100644
index 0000000..703b9ff
--- /dev/null
+++ b/third_party/libpng/arm/palette_neon_intrinsics.c
@@ -0,0 +1,137 @@
+/* palette_neon_intrinsics.c - NEON optimised palette expansion functions
+ *
+ * Copyright (c) 2017 The Chromium Authors. All rights reserved.
+ * Written by Richard Townsend <Richard.Townsend@arm.com>, February 2017.
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "../pngpriv.h"
+
+#if PNG_ARM_NEON_IMPLEMENTATION == 1
+
+#include <arm_neon.h>
+
+/* Build an RGBA palette from the RGB and separate alpha palettes. */
+void
+png_riffle_palette_rgba(png_structrp png_ptr, png_row_infop row_info)
+{
+   png_const_colorp palette = png_ptr->palette;
+   png_bytep riffled_palette = png_ptr->riffled_palette;
+   png_const_bytep trans_alpha = png_ptr->trans_alpha;
+   int num_trans = png_ptr->num_trans;
+
+   if (row_info->bit_depth != 8) {
+      png_error(png_ptr, "bit_depth must be 8 for png_riffle_palette_rgba");
+      return;
+   }
+
+   /* Initially black, opaque. */
+   uint8x16x4_t w = {{
+      vdupq_n_u8(0x00),
+      vdupq_n_u8(0x00),
+      vdupq_n_u8(0x00),
+      vdupq_n_u8(0xff),
+   }};
+
+   int i;
+   /* First, riffle the RGB colours into a RGBA palette, the A value is
+    * set to opaque for now. */
+   for (i = 0; i < (1 << row_info->bit_depth); i += 16) {
+      uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i));
+      w.val[0] = v.val[0];
+      w.val[1] = v.val[1];
+      w.val[2] = v.val[2];
+      vst4q_u8(riffled_palette + (i << 2), w);
+   }
+
+   /* Fix up the missing transparency values. */
+   for (i = 0; i < num_trans; i++) {
+      riffled_palette[(i << 2) + 3] = trans_alpha[i];
+   }
+}
+
+
+/* Expands a palettized row into RGBA. */
+int
+png_do_expand_palette_neon_rgba(png_structrp png_ptr, png_row_infop row_info,
+   png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp)
+{
+
+   png_uint_32 row_width = row_info->width;
+   const png_uint_32 *riffled_palette = (const png_uint_32*)png_ptr->riffled_palette;
+   const png_int_32 pixels_per_chunk = 4;
+
+   if (row_width < pixels_per_chunk) {
+      return 0;
+   }
+
+   /* This function originally gets the last byte of the output row.
+      The NEON part writes forward from a given position, so we have
+      to seek this back by 4 pixels x 4 bytes. */
+   *ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1);
+
+   int i;
+   for (i = 0; i < row_width; i += pixels_per_chunk) {
+      uint32x4_t cur;
+      png_bytep sp = *ssp - i, dp = *ddp - (i << 2);
+      cur = vld1q_dup_u32 (riffled_palette + *(sp - 3));
+      cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1);
+      cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2);
+      cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3);
+      vst1q_u32((void *)dp, cur);
+   }
+   if (i != row_width) {
+      i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */
+   }
+
+   /* Decrement output pointers. */
+   *ssp = *ssp - i;
+   *ddp = *ddp - (i << 2);
+   return i;
+}
+
+/* Expands a palettized row into RGB format. */
+int
+png_do_expand_palette_neon_rgb(png_structrp png_ptr, png_row_infop row_info,
+   png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp)
+{
+   png_uint_32 row_width = row_info->width;
+   png_const_bytep palette = (png_const_bytep)png_ptr->palette;
+   const png_uint_32 pixels_per_chunk = 8;
+
+   if (row_width <= pixels_per_chunk) {
+      return 0;
+   }
+
+   /* Seeking this back by 8 pixels x 3 bytes. */
+   *ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1);
+
+   int i;
+   for (i = 0; i < row_width; i += pixels_per_chunk) {
+      uint8x8x3_t cur;
+      png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i);
+      cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7)));
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1);
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2);
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3);
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4);
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5);
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6);
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7);
+      vst3_u8((void *)dp, cur);
+   }
+
+   if (i != row_width) {
+      i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */
+   }
+
+   /* Decrement output pointers. */
+   *ssp = *ssp - i;
+   *ddp = *ddp - ((i << 1) + i);
+   return i;
+}
+
+#endif /* PNG_ARM_NEON_IMPLEMENTATION */
diff --git a/third_party/libpng/contrib/intel/INSTALL b/third_party/libpng/contrib/intel/INSTALL
deleted file mode 100644
index cd5cdd9..0000000
--- a/third_party/libpng/contrib/intel/INSTALL
+++ /dev/null
@@ -1,158 +0,0 @@
-Enabling SSE support
-
-Copyright (c) 2016 Google, Inc.
-Written by Mike Klein, Matt Sarett
-
-This INSTALL file written by Glenn Randers-Pehrson, 2016.
-
-If you have moved intel_init.c and filter_sse2_intrinsics.c to a different
-directory, be sure to update the '#include "../../pngpriv.h"' line in both
-files if necessary to point to the correct relative location of pngpriv.h
-with respect to the new location of those files.
-
-To enable SSE support in libpng, follow the instructions in I, II, or III,
-below:
-
-I. Using patched "configure" scripts:
-
-First, apply intel_sse.patch in your build directory.
-
-   patch -i contrib/intel/intel_sse.patch -p1
-
-Then, if you are not building in a new GIT clone, e.g., in a tar
-distribution, remove any existing pre-built configure scripts:
-
-   ./configure --enable-maintainer-mode
-   make maintainer-clean
-   ./autogen.sh --maintainer --clean
-
-Finally, configure libpng with -DPNG_INTEL_SSE in CPPFLAGS:
-
-   ./autogen.sh --maintainer
-   CPPFLAGS="-DPNG_INTEL_SSE" ./configure [options]
-   make CPPFLAGS="-DPNG_INTEL_SSE" [options]
-   make
-
-II. Using a custom makefile:
-
-If you are using a custom makefile makefile, you will have to update it
-manually to include contrib/intel/*.o in the dependencies, and to define
-PNG_INTEL_SSE.
-
-III. Using manually updated "configure" scripts:
-
-If you prefer, manually edit pngpriv.h, configure.ac, and Makefile.am,
-following the instructions below, then follow the instructions in
-section II of INSTALL in the main libpng directory, then configure libpng
-with -DPNG_INTEL_SSE in CPPFLAGS.
-
-1. Add the following code to configure.ac under HOST SPECIFIC OPTIONS
-directly beneath the section for ARM:
-
------------------cut----------------
-# INTEL
-# =====
-#
-# INTEL SSE (SIMD) support.
-
-AC_ARG_ENABLE([intel-sse],
-   AS_HELP_STRING([[[--enable-intel-sse]]],
-      [Enable Intel SSE optimizations: =no/off, yes/on:]
-      [no/off: disable the optimizations;]
-      [yes/on: enable the optimizations.]
-      [If not specified: determined by the compiler.]),
-   [case "$enableval" in
-      no|off)
-         # disable the default enabling:
-         AC_DEFINE([PNG_INTEL_SSE_OPT], [0],
-                   [Disable Intel SSE optimizations])
-         # Prevent inclusion of the assembler files below:
-         enable_intel_sse=no;;
-      yes|on)
-         AC_DEFINE([PNG_INTEL_SSE_OPT], [1],
-                   [Enable Intel SSE optimizations]);;
-      *)
-         AC_MSG_ERROR([--enable-intel-sse=${enable_intel_sse}: invalid value])
-   esac])
-
-# Add Intel specific files to all builds where the host_cpu is Intel ('x86*')
-# or where Intel optimizations were explicitly requested (this allows a
-# fallback if a future host CPU does not match 'x86*')
-AM_CONDITIONAL([PNG_INTEL_SSE],
-   [test "$enable_intel_sse" != 'no' &&
-    case "$host_cpu" in
-      i?86|x86_64) :;;
-      *)    test "$enable_intel_sse" != '';;
-    esac])
------------------cut----------------
-
-2. Add the following code to Makefile.am under HOST SPECIFIC OPTIONS
-directly beneath the "if PNG_ARM_NEON ... endif" statement:
-
------------------cut----------------
-if PNG_INTEL_SSE
-libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += contrib/intel/intel_init.c\
-    contrib/intel/filter_sse2_intrinsics.c
-endif
------------------cut----------------
-
-3. Add the following lines to pngpriv.h, following the PNG_ARM_NEON_OPT
-code:
-
------------------cut----------------
-#ifndef PNG_INTEL_SSE_OPT
-#   ifdef PNG_INTEL_SSE
-      /* Only check for SSE if the build configuration has been modified to
-       * enable SSE optimizations.  This means that these optimizations will
-       * be off by default.  See contrib/intel for more details.
-       */
-#     if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \
-       defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
-       (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
-#         define PNG_INTEL_SSE_OPT 1
-#      endif
-#   endif
-#endif
-
-#if PNG_INTEL_SSE_OPT > 0
-#   ifndef PNG_INTEL_SSE_IMPLEMENTATION
-#      if defined(__SSE4_1__) || defined(__AVX__)
-          /* We are not actually using AVX, but checking for AVX is the best
-             way we can detect SSE4.1 and SSSE3 on MSVC.
-          */
-#         define PNG_INTEL_SSE_IMPLEMENTATION 3
-#      elif defined(__SSSE3__)
-#         define PNG_INTEL_SSE_IMPLEMENTATION 2
-#      elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
-       (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
-#         define PNG_INTEL_SSE_IMPLEMENTATION 1
-#      else
-#         define PNG_INTEL_SSE_IMPLEMENTATION 0
-#      endif
-#   endif
-
-#   if PNG_INTEL_SSE_IMPLEMENTATION > 0
-#      define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2
-#   endif
-#endif
-
------------------cut----------------
-
-4. Add the following lines to pngpriv.h, following the prototype for
-png_read_filter_row_paeth4_neon:
-
------------------cut----------------
-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop
-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop
-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_sse2,(png_row_infop
-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_sse2,(png_row_infop
-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_sse2,(png_row_infop
-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop
-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
-
------------------cut----------------
diff --git a/third_party/libpng/contrib/intel/intel_sse.patch b/third_party/libpng/contrib/intel/intel_sse.patch
deleted file mode 100644
index d9d02bb..0000000
--- a/third_party/libpng/contrib/intel/intel_sse.patch
+++ /dev/null
@@ -1,164 +0,0 @@
-diff --git libpng-1.6.22-orig/configure.ac libpng-1.6.22/configure.ac
---- libpng-1.6.22-orig/configure.ac	2016-05-25 18:59:10.000000000 -0400
-+++ libpng-1.6.22/configure.ac	2016-05-25 19:48:10.631751170 -0400
-@@ -341,16 +341,50 @@ AC_ARG_ENABLE([arm-neon],
- 
- AM_CONDITIONAL([PNG_ARM_NEON],
-    [test "$enable_arm_neon" != 'no' &&
-     case "$host_cpu" in
-       arm*|aarch64*) :;;
-       *)    test "$enable_arm_neon" != '';;
-     esac])
- 
-+# INTEL
-+# =====
-+#
-+# INTEL SSE (SIMD) support.
-+
-+AC_ARG_ENABLE([intel-sse],
-+   AS_HELP_STRING([[[--enable-intel-sse]]],
-+      [Enable Intel SSE optimizations: =no/off, yes/on:]
-+      [no/off: disable the optimizations;]
-+      [yes/on: enable the optimizations.]
-+      [If not specified: determined by the compiler.]),
-+   [case "$enableval" in
-+      no|off)
-+         # disable the default enabling:
-+         AC_DEFINE([PNG_INTEL_SSE_OPT], [0],
-+                   [Disable Intel SSE optimizations])
-+         # Prevent inclusion of the assembler files below:
-+         enable_intel_sse=no;;
-+      yes|on)
-+         AC_DEFINE([PNG_INTEL_SSE_OPT], [1],
-+                   [Enable Intel SSE optimizations]);;
-+      *)
-+         AC_MSG_ERROR([--enable-intel-sse=${enable_intel_sse}: invalid value])
-+   esac])
-+
-+# Add Intel specific files to all builds where the host_cpu is Intel ('x86*')
-+# or where Intel optimizations were explicitly requested (this allows a
-+# fallback if a future host CPU does not match 'x86*')
-+AM_CONDITIONAL([PNG_INTEL_SSE],
-+   [test "$enable_intel_sse" != 'no' &&
-+    case "$host_cpu" in
-+      i?86|x86_64) :;;
-+      *)    test "$enable_intel_sse" != '';;
-+    esac])
- AC_MSG_NOTICE([[Extra options for compiler: $PNG_COPTS]])
- 
- # Config files, substituting as above
- AC_CONFIG_FILES([Makefile libpng.pc:libpng.pc.in])
- AC_CONFIG_FILES([libpng-config:libpng-config.in],
-    [chmod +x libpng-config])
- 
- AC_OUTPUT
-diff --git libpng-1.6.22-orig/Makefile.am libpng-1.6.22/Makefile.am
---- libpng-1.6.22-orig/Makefile.am	2016-05-17 18:15:12.000000000 -0400
-+++ libpng-1.6.22/Makefile.am	2016-05-25 19:48:10.631751170 -0400
-@@ -89,16 +89,20 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SO
- 	pngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c pngwutil.c\
- 	png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h pngusr.dfa
- 
- if PNG_ARM_NEON
- libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += arm/arm_init.c\
- 	arm/filter_neon.S arm/filter_neon_intrinsics.c
- endif
- 
-+if PNG_INTEL_SSE
-+libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += contrib/intel/intel_init.c\
-+    contrib/intel/filter_sse2_intrinsics.c
-+endif
- nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = pnglibconf.h
- 
- libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS = -no-undefined -export-dynamic \
- 	-version-number @PNGLIB_MAJOR@@PNGLIB_MINOR@:@PNGLIB_RELEASE@:0
- 
- if HAVE_LD_VERSION_SCRIPT
- #   Versioned symbols and restricted exports
- if HAVE_SOLARIS_LD
-diff --git libpng-1.6.22-orig/pngpriv.h libpng-1.6.22/pngpriv.h
---- libpng-1.6.22-orig/pngpriv.h	2016-05-25 18:59:10.000000000 -0400
-+++ libpng-1.6.22/pngpriv.h	2016-05-25 19:48:10.635751171 -0400
-@@ -177,16 +177,52 @@
- #  endif /* !PNG_ARM_NEON_IMPLEMENTATION */
- 
- #  ifndef PNG_ARM_NEON_IMPLEMENTATION
-       /* Use the intrinsics code by default. */
- #     define PNG_ARM_NEON_IMPLEMENTATION 1
- #  endif
- #endif /* PNG_ARM_NEON_OPT > 0 */
- 
-+#ifndef PNG_INTEL_SSE_OPT
-+#   ifdef PNG_INTEL_SSE
-+      /* Only check for SSE if the build configuration has been modified to
-+       * enable SSE optimizations.  This means that these optimizations will
-+       * be off by default.  See contrib/intel for more details.
-+       */
-+#     if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \
-+       defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
-+       (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
-+#         define PNG_INTEL_SSE_OPT 1
-+#      endif
-+#   endif
-+#endif
-+
-+#if PNG_INTEL_SSE_OPT > 0
-+#   ifndef PNG_INTEL_SSE_IMPLEMENTATION
-+#      if defined(__SSE4_1__) || defined(__AVX__)
-+          /* We are not actually using AVX, but checking for AVX is the best
-+             way we can detect SSE4.1 and SSSE3 on MSVC.
-+          */
-+#         define PNG_INTEL_SSE_IMPLEMENTATION 3
-+#      elif defined(__SSSE3__)
-+#         define PNG_INTEL_SSE_IMPLEMENTATION 2
-+#      elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
-+       (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
-+#         define PNG_INTEL_SSE_IMPLEMENTATION 1
-+#      else
-+#         define PNG_INTEL_SSE_IMPLEMENTATION 0
-+#      endif
-+#   endif
-+
-+#   if PNG_INTEL_SSE_IMPLEMENTATION > 0
-+#      define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2
-+#   endif
-+#endif
-+
- /* Is this a build of a DLL where compilation of the object modules requires
-  * different preprocessor settings to those required for a simple library?  If
-  * so PNG_BUILD_DLL must be set.
-  *
-  * If libpng is used inside a DLL but that DLL does not export the libpng APIs
-  * PNG_BUILD_DLL must not be set.  To avoid the code below kicking in build a
-  * static library of libpng then link the DLL against that.
-  */
-@@ -1184,16 +1220,29 @@ PNG_INTERNAL_FUNCTION(void,png_read_filt
-     row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
- PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop
-     row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
- PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop
-     row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
- PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
-     row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
- 
-+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop
-+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
-+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop
-+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
-+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_sse2,(png_row_infop
-+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
-+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_sse2,(png_row_infop
-+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
-+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_sse2,(png_row_infop
-+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
-+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop
-+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
-+
- /* Choose the best filter to use and filter the row data */
- PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
-     png_row_infop row_info),PNG_EMPTY);
- 
- #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
- PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr,
-    png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY);
-    /* Read 'avail_out' bytes of data from the IDAT stream.  If the output buffer
diff --git a/third_party/libpng/contrib/intel/filter_sse2_intrinsics.c b/third_party/libpng/intel/filter_sse2_intrinsics.c
similarity index 82%
rename from third_party/libpng/contrib/intel/filter_sse2_intrinsics.c
rename to third_party/libpng/intel/filter_sse2_intrinsics.c
index aea3f86..7a7d4269 100644
--- a/third_party/libpng/contrib/intel/filter_sse2_intrinsics.c
+++ b/third_party/libpng/intel/filter_sse2_intrinsics.c
@@ -1,19 +1,18 @@
 
 /* filter_sse2_intrinsics.c - SSE2 optimized filter functions
  *
- * Copyright (c) 2016 Google, Inc.
+ * Copyright (c) 2016-2017 Glenn Randers-Pehrson
  * Written by Mike Klein and Matt Sarett
- * Derived from arm/filter_neon_intrinsics.c, which was
- * Copyright (c) 2014,2016 Glenn Randers-Pehrson
+ * Derived from arm/filter_neon_intrinsics.c
  *
- * Last changed in libpng 1.6.22 [May 26, 2016]
+ * Last changed in libpng 1.6.31 [July 27, 2017]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
-#include "../../pngpriv.h"
+#include "../pngpriv.h"
 
 #ifdef PNG_READ_SUPPORTED
 
@@ -41,7 +40,7 @@
    /* We'll load 2 bytes, then 1 byte,
     * then mask them together, and finally load into SSE.
     */
-   const png_uint_16* p01 = p;
+   const png_uint_16* p01 = (png_const_uint_16p)p;
    const png_byte*    p2  = (const png_byte*)(p01+1);
 
    png_uint_32 v012 = (png_uint_32)(*p01)
@@ -54,12 +53,15 @@
     * its bottom two bytes, then its third byte.
     */
    png_uint_32 v012;
+   png_uint_16* p01;
+   png_byte*    p2;
+
    store4(&v012, v);
 
-   png_uint_16* p01 = p;
-   png_byte*    p2  = (png_byte*)(p01+1);
-   *p01 = v012;
-   *p2  = v012 >> 16;
+   p01 = (png_uint_16p)p;
+   p2  = (png_byte*)(p01+1);
+   *p01 = (png_uint_16)v012;
+   *p2  = (png_byte)(v012 >> 16);
 }
 
 void png_read_filter_row_sub3_sse2(png_row_infop row_info, png_bytep row,
@@ -69,10 +71,13 @@
     * There is no pixel to the left of the first pixel.  It's encoded directly.
     * That works with our main loop if we just say that left pixel was zero.
     */
-   png_debug(1, "in png_read_filter_row_sub3_sse2");
+   png_size_t rb;
+
    __m128i a, d = _mm_setzero_si128();
 
-   int rb = row_info->rowbytes;
+   png_debug(1, "in png_read_filter_row_sub3_sse2");
+
+   rb = row_info->rowbytes;
    while (rb >= 4) {
       a = d; d = load4(row);
       d = _mm_add_epi8(d, a);
@@ -89,6 +94,7 @@
       row += 3;
       rb  -= 3;
    }
+   PNG_UNUSED(prev)
 }
 
 void png_read_filter_row_sub4_sse2(png_row_infop row_info, png_bytep row,
@@ -98,11 +104,14 @@
     * There is no pixel to the left of the first pixel.  It's encoded directly.
     * That works with our main loop if we just say that left pixel was zero.
     */
-   png_debug(1, "in png_read_filter_row_sub4_sse2");
+   png_size_t rb;
+
    __m128i a, d = _mm_setzero_si128();
 
-   int rb = row_info->rowbytes;
-   while (rb > 0) {
+   png_debug(1, "in png_read_filter_row_sub4_sse2");
+
+   rb = row_info->rowbytes+4;
+   while (rb > 4) {
       a = d; d = load4(row);
       d = _mm_add_epi8(d, a);
       store4(row, d);
@@ -110,6 +119,7 @@
       row += 4;
       rb  -= 4;
    }
+   PNG_UNUSED(prev)
 }
 
 void png_read_filter_row_avg3_sse2(png_row_infop row_info, png_bytep row,
@@ -120,18 +130,23 @@
     * predicted to be half of the pixel above it.  So again, this works
     * perfectly with our loop if we make sure a starts at zero.
     */
-   png_debug(1, "in png_read_filter_row_avg3_sse2");
+
+   png_size_t rb;
+
    const __m128i zero = _mm_setzero_si128();
+
    __m128i    b;
    __m128i a, d = zero;
 
-   int rb = row_info->rowbytes;
+   png_debug(1, "in png_read_filter_row_avg3_sse2");
+   rb = row_info->rowbytes;
    while (rb >= 4) {
+      __m128i avg;
              b = load4(prev);
       a = d; d = load4(row );
 
       /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
-      __m128i avg = _mm_avg_epu8(a,b);
+      avg = _mm_avg_epu8(a,b);
       /* ...but we can fix it up by subtracting off 1 if it rounded up. */
       avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),
                                             _mm_set1_epi8(1)));
@@ -143,11 +158,12 @@
       rb   -= 3;
    }
    if (rb > 0) {
+      __m128i avg;
              b = load3(prev);
       a = d; d = load3(row );
 
       /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
-      __m128i avg = _mm_avg_epu8(a,b);
+      avg = _mm_avg_epu8(a,b);
       /* ...but we can fix it up by subtracting off 1 if it rounded up. */
       avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),
                                             _mm_set1_epi8(1)));
@@ -169,18 +185,21 @@
     * predicted to be half of the pixel above it.  So again, this works
     * perfectly with our loop if we make sure a starts at zero.
     */
-   png_debug(1, "in png_read_filter_row_avg4_sse2");
+   png_size_t rb;
    const __m128i zero = _mm_setzero_si128();
    __m128i    b;
    __m128i a, d = zero;
 
-   int rb = row_info->rowbytes;
-   while (rb > 0) {
+   png_debug(1, "in png_read_filter_row_avg4_sse2");
+
+   rb = row_info->rowbytes+4;
+   while (rb > 4) {
+      __m128i avg;
              b = load4(prev);
       a = d; d = load4(row );
 
       /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
-      __m128i avg = _mm_avg_epu8(a,b);
+      avg = _mm_avg_epu8(a,b);
       /* ...but we can fix it up by subtracting off 1 if it rounded up. */
       avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),
                                             _mm_set1_epi8(1)));
@@ -208,7 +227,7 @@
    x = _mm_xor_si128(x, is_negative);
 
    /* +1 to negative lanes, else +0. */
-   x = _mm_add_epi16(x, _mm_srli_epi16(is_negative, 15));
+   x = _mm_sub_epi16(x, is_negative);
    return x;
 #endif
 }
@@ -238,38 +257,42 @@
     * Here we zero b and d, which become c and a respectively at the start of
     * the loop.
     */
-   png_debug(1, "in png_read_filter_row_paeth3_sse2");
+   png_size_t rb;
    const __m128i zero = _mm_setzero_si128();
    __m128i c, b = zero,
            a, d = zero;
 
-   int rb = row_info->rowbytes;
+   png_debug(1, "in png_read_filter_row_paeth3_sse2");
+
+   rb = row_info->rowbytes;
    while (rb >= 4) {
       /* It's easiest to do this math (particularly, deal with pc) with 16-bit
        * intermediates.
        */
+      __m128i pa,pb,pc,smallest,nearest;
       c = b; b = _mm_unpacklo_epi8(load4(prev), zero);
       a = d; d = _mm_unpacklo_epi8(load4(row ), zero);
 
       /* (p-a) == (a+b-c - a) == (b-c) */
-      __m128i pa = _mm_sub_epi16(b,c);
+   
+      pa = _mm_sub_epi16(b,c);
 
       /* (p-b) == (a+b-c - b) == (a-c) */
-      __m128i pb = _mm_sub_epi16(a,c);
+      pb = _mm_sub_epi16(a,c);
 
       /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
-      __m128i pc = _mm_add_epi16(pa,pb);
+      pc = _mm_add_epi16(pa,pb);
 
       pa = abs_i16(pa);  /* |p-a| */
       pb = abs_i16(pb);  /* |p-b| */
       pc = abs_i16(pc);  /* |p-c| */
 
-      __m128i smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
+      smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
 
       /* Paeth breaks ties favoring a over b over c. */
-      __m128i nearest  = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
-                         if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
-                                                                     c));
+      nearest  = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
+                 if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
+                                                             c));
 
       /* Note `_epi8`: we need addition to wrap modulo 255. */
       d = _mm_add_epi8(d, nearest);
@@ -283,28 +306,29 @@
       /* It's easiest to do this math (particularly, deal with pc) with 16-bit
        * intermediates.
        */
+      __m128i pa,pb,pc,smallest,nearest;
       c = b; b = _mm_unpacklo_epi8(load3(prev), zero);
       a = d; d = _mm_unpacklo_epi8(load3(row ), zero);
 
       /* (p-a) == (a+b-c - a) == (b-c) */
-      __m128i pa = _mm_sub_epi16(b,c);
+      pa = _mm_sub_epi16(b,c);
 
       /* (p-b) == (a+b-c - b) == (a-c) */
-      __m128i pb = _mm_sub_epi16(a,c);
+      pb = _mm_sub_epi16(a,c);
 
       /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
-      __m128i pc = _mm_add_epi16(pa,pb);
+      pc = _mm_add_epi16(pa,pb);
 
       pa = abs_i16(pa);  /* |p-a| */
       pb = abs_i16(pb);  /* |p-b| */
       pc = abs_i16(pc);  /* |p-c| */
 
-      __m128i smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
+      smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
 
       /* Paeth breaks ties favoring a over b over c. */
-      __m128i nearest  = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
-                         if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
-                                                                     c));
+      nearest  = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
+                 if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
+                                                             c));
 
       /* Note `_epi8`: we need addition to wrap modulo 255. */
       d = _mm_add_epi8(d, nearest);
@@ -332,13 +356,16 @@
     * Here we zero b and d, which become c and a respectively at the start of
     * the loop.
     */
-   png_debug(1, "in png_read_filter_row_paeth4_sse2");
+   png_size_t rb;
    const __m128i zero = _mm_setzero_si128();
+   __m128i pa,pb,pc,smallest,nearest;
    __m128i c, b = zero,
            a, d = zero;
 
-   int rb = row_info->rowbytes;
-   while (rb > 0) {
+   png_debug(1, "in png_read_filter_row_paeth4_sse2");
+
+   rb = row_info->rowbytes+4;
+   while (rb > 4) {
       /* It's easiest to do this math (particularly, deal with pc) with 16-bit
        * intermediates.
        */
@@ -346,22 +373,22 @@
       a = d; d = _mm_unpacklo_epi8(load4(row ), zero);
 
       /* (p-a) == (a+b-c - a) == (b-c) */
-      __m128i pa = _mm_sub_epi16(b,c);
+      pa = _mm_sub_epi16(b,c);
 
       /* (p-b) == (a+b-c - b) == (a-c) */
-      __m128i pb = _mm_sub_epi16(a,c);
+      pb = _mm_sub_epi16(a,c);
 
       /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
-      __m128i pc = _mm_add_epi16(pa,pb);
+      pc = _mm_add_epi16(pa,pb);
 
       pa = abs_i16(pa);  /* |p-a| */
       pb = abs_i16(pb);  /* |p-b| */
       pc = abs_i16(pc);  /* |p-c| */
 
-      __m128i smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
+      smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
 
       /* Paeth breaks ties favoring a over b over c. */
-      __m128i nearest  = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
+      nearest  = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
                          if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
                                                                      c));
 
diff --git a/third_party/libpng/contrib/intel/intel_init.c b/third_party/libpng/intel/intel_init.c
similarity index 86%
rename from third_party/libpng/contrib/intel/intel_init.c
rename to third_party/libpng/intel/intel_init.c
index 328e90e..8f08baf 100644
--- a/third_party/libpng/contrib/intel/intel_init.c
+++ b/third_party/libpng/intel/intel_init.c
@@ -1,19 +1,18 @@
 
 /* intel_init.c - SSE2 optimized filter functions
  *
- * Copyright (c) 2016 Google, Inc.
- * Written by Mike Klein and Matt Sarett
- * Derived from arm/arm_init.c, which was
- * Copyright (c) 2014,2016 Glenn Randers-Pehrson
+ * Copyright (c) 2016-2017 Glenn Randers-Pehrson
+ * Written by Mike Klein and Matt Sarett, Google, Inc.
+ * Derived from arm/arm_init.c
  *
- * Last changed in libpng 1.6.22 [May 26, 2016]
+ * Last changed in libpng 1.6.29 [March 16, 2017]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
-#include "../../pngpriv.h"
+#include "../pngpriv.h"
 
 #ifdef PNG_READ_SUPPORTED
 #if PNG_INTEL_SSE_IMPLEMENTATION > 0
diff --git a/third_party/libpng/patches/0000-plte.patch b/third_party/libpng/patches/0000-plte.patch
new file mode 100644
index 0000000..45a5dcf
--- /dev/null
+++ b/third_party/libpng/patches/0000-plte.patch
@@ -0,0 +1,1180 @@
+From b764276b183d379d5b80e3f601ac42f574da5455 Mon Sep 17 00:00:00 2001
+From: Chris Blume <cblume@chromium.org>
+Date: Tue, 16 Jan 2018 21:19:28 +0000
+Subject: [PATCH] Revert "Revert "libpng: Optimize png_do_expand_palette with
+ NEON.""
+
+This reverts commit 20a18ebc02429a40e4bc33fa28c4de29a39b609c.
+
+Reason for revert: <INSERT REASONING HERE>
+
+Original change's description:
+> Revert "libpng: Optimize png_do_expand_palette with NEON."
+>
+> This reverts commit c4811af6d72836d44a3630beecebb0ff55875ab1.
+>
+> Reason for revert: This is failing to compile on ios-device-xcode-clang bot.
+>
+> https://uberchromegw.corp.google.com/i/chromium.mac/builders/ios-device-xcode-clang/builds/50225
+>
+> Original change's description:
+> > libpng: Optimize png_do_expand_palette with NEON.
+> >
+> > ARM-specific optimization processes 8 or 4 pixels at once.
+> >
+> > * Without transparency: 22% performance gain on the A53 little core.
+> > * With transparency: 10% improvement on a big A72 core, 24% on little.
+> >
+> > (Numbers from image_decode_bench with PNG140 on the elm chromebook).
+> >
+> > Bug: 706134
+> > Change-Id: I7b4a93d72a0afa2823f3bf9ff5f798b88c843e54
+> > Reviewed-on: https://chromium-review.googlesource.com/817116
+> > Reviewed-by: Adenilson Cavalcanti <cavalcantii@chromium.org>
+> > Reviewed-by: Mike Klein <mtklein@chromium.org>
+> > Reviewed-by: Leon Scroggins <scroggo@chromium.org>
+> > Reviewed-by: Chris Blume <cblume@chromium.org>
+> > Commit-Queue: Adenilson Cavalcanti <cavalcantii@chromium.org>
+> > Cr-Commit-Position: refs/heads/master@{#529473}
+>
+> TBR=scroggo@chromium.org,cavalcantii@chromium.org,richard.townsend@arm.com,cblume@chromium.org,mtklein@chromium.org
+>
+> Change-Id: I2cd943e15ceadf4311b1b49a56de00d10684e294
+> No-Presubmit: true
+> No-Tree-Checks: true
+> No-Try: true
+> Bug: 706134
+> Reviewed-on: https://chromium-review.googlesource.com/868770
+> Reviewed-by: Jonathan Ross <jonross@chromium.org>
+> Commit-Queue: Jonathan Ross <jonross@chromium.org>
+> Cr-Commit-Position: refs/heads/master@{#529484}
+
+TBR=scroggo@chromium.org,jonross@chromium.org,cavalcantii@chromium.org,richard.townsend@arm.com,cblume@chromium.org,mtklein@chromium.org
+
+Change-Id: I6baf17d35efbd5c6bc348d4f81264e8e1023be4f
+No-Presubmit: true
+No-Tree-Checks: true
+No-Try: true
+Bug: 706134
+---
+ third_party/libpng/BUILD.gn                      |   1 +
+ third_party/libpng/arm/palette_neon_intrinsics.c | 137 ++++
+ third_party/libpng/patches/0000-plte.patch       | 776 +++++++++++++++++++++++
+ third_party/libpng/patches/README                |   4 +
+ third_party/libpng/pngpriv.h                     |  23 +
+ third_party/libpng/pngrtran.c                    |  49 +-
+ third_party/libpng/pngstruct.h                   |   4 +
+ third_party/libpng/pngwrite.c                    |   4 +
+ 8 files changed, 990 insertions(+), 8 deletions(-)
+ create mode 100644 third_party/libpng/arm/palette_neon_intrinsics.c
+ create mode 100644 third_party/libpng/patches/0000-plte.patch
+ create mode 100644 third_party/libpng/patches/README
+
+diff --git a/third_party/libpng/BUILD.gn b/third_party/libpng/BUILD.gn
+index e2658a7ba623..e48c790326c7 100644
+--- a/third_party/libpng/BUILD.gn
++++ b/third_party/libpng/BUILD.gn
+@@ -75,6 +75,7 @@ source_set("libpng_sources") {
+     sources += [
+       "arm/arm_init.c",
+       "arm/filter_neon_intrinsics.c",
++      "arm/palette_neon_intrinsics.c",
+     ]
+     defines += [
+       "PNG_ARM_NEON_OPT=2",
+diff --git a/third_party/libpng/arm/palette_neon_intrinsics.c b/third_party/libpng/arm/palette_neon_intrinsics.c
+new file mode 100644
+index 000000000000..703b9ff25053
+--- /dev/null
++++ b/third_party/libpng/arm/palette_neon_intrinsics.c
+@@ -0,0 +1,137 @@
++/* palette_neon_intrinsics.c - NEON optimised palette expansion functions
++ *
++ * Copyright (c) 2017 The Chromium Authors. All rights reserved.
++ * Written by Richard Townsend <Richard.Townsend@arm.com>, February 2017.
++ *
++ * This code is released under the libpng license.
++ * For conditions of distribution and use, see the disclaimer
++ * and license in png.h
++ */
++
++#include "../pngpriv.h"
++
++#if PNG_ARM_NEON_IMPLEMENTATION == 1
++
++#include <arm_neon.h>
++
++/* Build an RGBA palette from the RGB and separate alpha palettes. */
++void
++png_riffle_palette_rgba(png_structrp png_ptr, png_row_infop row_info)
++{
++   png_const_colorp palette = png_ptr->palette;
++   png_bytep riffled_palette = png_ptr->riffled_palette;
++   png_const_bytep trans_alpha = png_ptr->trans_alpha;
++   int num_trans = png_ptr->num_trans;
++
++   if (row_info->bit_depth != 8) {
++      png_error(png_ptr, "bit_depth must be 8 for png_riffle_palette_rgba");
++      return;
++   }
++
++   /* Initially black, opaque. */
++   uint8x16x4_t w = {{
++      vdupq_n_u8(0x00),
++      vdupq_n_u8(0x00),
++      vdupq_n_u8(0x00),
++      vdupq_n_u8(0xff),
++   }};
++
++   int i;
++   /* First, riffle the RGB colours into a RGBA palette, the A value is
++    * set to opaque for now. */
++   for (i = 0; i < (1 << row_info->bit_depth); i += 16) {
++      uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i));
++      w.val[0] = v.val[0];
++      w.val[1] = v.val[1];
++      w.val[2] = v.val[2];
++      vst4q_u8(riffled_palette + (i << 2), w);
++   }
++
++   /* Fix up the missing transparency values. */
++   for (i = 0; i < num_trans; i++) {
++      riffled_palette[(i << 2) + 3] = trans_alpha[i];
++   }
++}
++
++
++/* Expands a palettized row into RGBA. */
++int
++png_do_expand_palette_neon_rgba(png_structrp png_ptr, png_row_infop row_info,
++   png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp)
++{
++
++   png_uint_32 row_width = row_info->width;
++   const png_uint_32 *riffled_palette = (const png_uint_32*)png_ptr->riffled_palette;
++   const png_int_32 pixels_per_chunk = 4;
++
++   if (row_width < pixels_per_chunk) {
++      return 0;
++   }
++
++   /* This function originally gets the last byte of the output row.
++      The NEON part writes forward from a given position, so we have
++      to seek this back by 4 pixels x 4 bytes. */
++   *ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1);
++
++   int i;
++   for (i = 0; i < row_width; i += pixels_per_chunk) {
++      uint32x4_t cur;
++      png_bytep sp = *ssp - i, dp = *ddp - (i << 2);
++      cur = vld1q_dup_u32 (riffled_palette + *(sp - 3));
++      cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1);
++      cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2);
++      cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3);
++      vst1q_u32((void *)dp, cur);
++   }
++   if (i != row_width) {
++      i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */
++   }
++
++   /* Decrement output pointers. */
++   *ssp = *ssp - i;
++   *ddp = *ddp - (i << 2);
++   return i;
++}
++
++/* Expands a palettized row into RGB format. */
++int
++png_do_expand_palette_neon_rgb(png_structrp png_ptr, png_row_infop row_info,
++   png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp)
++{
++   png_uint_32 row_width = row_info->width;
++   png_const_bytep palette = (png_const_bytep)png_ptr->palette;
++   const png_uint_32 pixels_per_chunk = 8;
++
++   if (row_width <= pixels_per_chunk) {
++      return 0;
++   }
++
++   /* Seeking this back by 8 pixels x 3 bytes. */
++   *ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1);
++
++   int i;
++   for (i = 0; i < row_width; i += pixels_per_chunk) {
++      uint8x8x3_t cur;
++      png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i);
++      cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7)));
++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1);
++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2);
++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3);
++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4);
++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5);
++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6);
++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7);
++      vst3_u8((void *)dp, cur);
++   }
++
++   if (i != row_width) {
++      i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */
++   }
++
++   /* Decrement output pointers. */
++   *ssp = *ssp - i;
++   *ddp = *ddp - ((i << 1) + i);
++   return i;
++}
++
++#endif /* PNG_ARM_NEON_IMPLEMENTATION */
+diff --git a/third_party/libpng/patches/0000-plte.patch b/third_party/libpng/patches/0000-plte.patch
+new file mode 100644
+index 000000000000..feea4d874335
+--- /dev/null
++++ b/third_party/libpng/patches/0000-plte.patch
+@@ -0,0 +1,776 @@
++From 5d94e310951211886ee460701176cb36c6e4bc88 Mon Sep 17 00:00:00 2001
++From: Chris Blume <cblume@chromium.org>
++Date: Tue, 16 Jan 2018 21:19:28 +0000
++Subject: [PATCH 1/2] Revert "Revert "libpng: Optimize png_do_expand_palette
++ with NEON.""
++
++This reverts commit 20a18ebc02429a40e4bc33fa28c4de29a39b609c.
++
++Reason for revert: <INSERT REASONING HERE>
++
++Original change's description:
++> Revert "libpng: Optimize png_do_expand_palette with NEON."
++>
++> This reverts commit c4811af6d72836d44a3630beecebb0ff55875ab1.
++>
++> Reason for revert: This is failing to compile on ios-device-xcode-clang bot.
++>
++> https://uberchromegw.corp.google.com/i/chromium.mac/builders/ios-device-xcode-clang/builds/50225
++>
++> Original change's description:
++> > libpng: Optimize png_do_expand_palette with NEON.
++> >
++> > ARM-specific optimization processes 8 or 4 pixels at once.
++> >
++> > * Without transparency: 22% performance gain on the A53 little core.
++> > * With transparency: 10% improvement on a big A72 core, 24% on little.
++> >
++> > (Numbers from image_decode_bench with PNG140 on the elm chromebook).
++> >
++> > Bug: 706134
++> > Change-Id: I7b4a93d72a0afa2823f3bf9ff5f798b88c843e54
++> > Reviewed-on: https://chromium-review.googlesource.com/817116
++> > Reviewed-by: Adenilson Cavalcanti <cavalcantii@chromium.org>
++> > Reviewed-by: Mike Klein <mtklein@chromium.org>
++> > Reviewed-by: Leon Scroggins <scroggo@chromium.org>
++> > Reviewed-by: Chris Blume <cblume@chromium.org>
++> > Commit-Queue: Adenilson Cavalcanti <cavalcantii@chromium.org>
++> > Cr-Commit-Position: refs/heads/master@{#529473}
++>
++> TBR=scroggo@chromium.org,cavalcantii@chromium.org,richard.townsend@arm.com,cblume@chromium.org,mtklein@chromium.org
++>
++> Change-Id: I2cd943e15ceadf4311b1b49a56de00d10684e294
++> No-Presubmit: true
++> No-Tree-Checks: true
++> No-Try: true
++> Bug: 706134
++> Reviewed-on: https://chromium-review.googlesource.com/868770
++> Reviewed-by: Jonathan Ross <jonross@chromium.org>
++> Commit-Queue: Jonathan Ross <jonross@chromium.org>
++> Cr-Commit-Position: refs/heads/master@{#529484}
++
++TBR=scroggo@chromium.org,jonross@chromium.org,cavalcantii@chromium.org,richard.townsend@arm.com,cblume@chromium.org,mtklein@chromium.org
++
++Change-Id: I6baf17d35efbd5c6bc348d4f81264e8e1023be4f
++No-Presubmit: true
++No-Tree-Checks: true
++No-Try: true
++Bug: 706134
++---
++ third_party/libpng/BUILD.gn                      |   1 +
++ third_party/libpng/arm/palette_neon_intrinsics.c | 137 +++++++++
++ third_party/libpng/patches/0000-plte.patch       | 340 +++++++++++++++++++++++
++ third_party/libpng/patches/README                |   4 +
++ third_party/libpng/pngpriv.h                     |  23 ++
++ third_party/libpng/pngrtran.c                    |  49 +++-
++ third_party/libpng/pngstruct.h                   |   4 +
++ third_party/libpng/pngwrite.c                    |   4 +
++ 8 files changed, 554 insertions(+), 8 deletions(-)
++ create mode 100644 third_party/libpng/arm/palette_neon_intrinsics.c
++ create mode 100644 third_party/libpng/patches/0000-plte.patch
++ create mode 100644 third_party/libpng/patches/README
++
++diff --git a/third_party/libpng/BUILD.gn b/third_party/libpng/BUILD.gn
++index e2658a7ba623..e48c790326c7 100644
++--- a/third_party/libpng/BUILD.gn
+++++ b/third_party/libpng/BUILD.gn
++@@ -75,6 +75,7 @@ source_set("libpng_sources") {
++     sources += [
++       "arm/arm_init.c",
++       "arm/filter_neon_intrinsics.c",
+++      "arm/palette_neon_intrinsics.c",
++     ]
++     defines += [
++       "PNG_ARM_NEON_OPT=2",
++diff --git a/third_party/libpng/arm/palette_neon_intrinsics.c b/third_party/libpng/arm/palette_neon_intrinsics.c
++new file mode 100644
++index 000000000000..0c0c0a909f8d
++--- /dev/null
+++++ b/third_party/libpng/arm/palette_neon_intrinsics.c
++@@ -0,0 +1,137 @@
+++/* palette_neon_intrinsics.c - NEON optimised palette expansion functions
+++ *
+++ * Copyright (c) 2017 The Chromium Authors. All rights reserved.
+++ * Written by Richard Townsend <Richard.Townsend@arm.com>, February 2017.
+++ *
+++ * This code is released under the libpng license.
+++ * For conditions of distribution and use, see the disclaimer
+++ * and license in png.h
+++ */
+++
+++#include "../pngpriv.h"
+++
+++#if PNG_ARM_NEON_IMPLEMENTATION == 1
+++
+++#include <arm_neon.h>
+++
+++/* Build an RGBA palette from the RGB and separate alpha palettes. */
+++void
+++png_riffle_palette_rgba(png_structrp png_ptr, png_row_infop row_info)
+++{
+++   png_const_colorp palette = png_ptr->palette;
+++   png_bytep riffled_palette = png_ptr->riffled_palette;
+++   png_const_bytep trans_alpha = png_ptr->trans_alpha;
+++   int num_trans = png_ptr->num_trans;
+++
+++   if (row_info->bit_depth != 8) {
+++      png_error(png_ptr, "bit_depth must be 8 for png_riffle_palette_rgba");
+++      return;
+++   }
+++
+++   /* Initially black, opaque. */
+++   uint8x16x4_t w = {
+++      vdupq_n_u8(0x00),
+++      vdupq_n_u8(0x00),
+++      vdupq_n_u8(0x00),
+++      vdupq_n_u8(0xff),
+++   };
+++
+++   int i;
+++   /* First, riffle the RGB colours into a RGBA palette, the A value is
+++    * set to opaque for now. */
+++   for (i = 0; i < (1 << row_info->bit_depth); i += 16) {
+++      uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i));
+++      w.val[0] = v.val[0];
+++      w.val[1] = v.val[1];
+++      w.val[2] = v.val[2];
+++      vst4q_u8(riffled_palette + (i << 2), w);
+++   }
+++
+++   /* Fix up the missing transparency values. */
+++   for (i = 0; i < num_trans; i++) {
+++      riffled_palette[(i << 2) + 3] = trans_alpha[i];
+++   }
+++}
+++
+++
+++/* Expands a palettized row into RGBA. */
+++int
+++png_do_expand_palette_neon_rgba(png_structrp png_ptr, png_row_infop row_info,
+++   png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp)
+++{
+++
+++   png_uint_32 row_width = row_info->width;
+++   const png_uint_32 *riffled_palette = (const png_uint_32*)png_ptr->riffled_palette;
+++   const png_int_32 pixels_per_chunk = 4;
+++
+++   if (row_width < pixels_per_chunk) {
+++      return 0;
+++   }
+++
+++   /* This function originally gets the last byte of the output row.
+++      The NEON part writes forward from a given position, so we have
+++      to seek this back by 4 pixels x 4 bytes. */
+++   *ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1);
+++
+++   int i;
+++   for (i = 0; i < row_width; i += pixels_per_chunk) {
+++      uint32x4_t cur;
+++      png_bytep sp = *ssp - i, dp = *ddp - (i << 2);
+++      cur = vld1q_dup_u32 (riffled_palette + *(sp - 3));
+++      cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1);
+++      cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2);
+++      cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3);
+++      vst1q_u32((void *)dp, cur);
+++   }
+++   if (i != row_width) {
+++      i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */
+++   }
+++
+++   /* Decrement output pointers. */
+++   *ssp = *ssp - i;
+++   *ddp = *ddp - (i << 2);
+++   return i;
+++}
+++
+++/* Expands a palettized row into RGB format. */
+++int
+++png_do_expand_palette_neon_rgb(png_structrp png_ptr, png_row_infop row_info,
+++   png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp)
+++{
+++   png_uint_32 row_width = row_info->width;
+++   png_const_bytep palette = (png_const_bytep)png_ptr->palette;
+++   const png_uint_32 pixels_per_chunk = 8;
+++
+++   if (row_width <= pixels_per_chunk) {
+++      return 0;
+++   }
+++
+++   /* Seeking this back by 8 pixels x 3 bytes. */
+++   *ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1);
+++
+++   int i;
+++   for (i = 0; i < row_width; i += pixels_per_chunk) {
+++      uint8x8x3_t cur;
+++      png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i);
+++      cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7)));
+++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1);
+++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2);
+++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3);
+++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4);
+++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5);
+++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6);
+++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7);
+++      vst3_u8((void *)dp, cur);
+++   }
+++
+++   if (i != row_width) {
+++      i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */
+++   }
+++
+++   /* Decrement output pointers. */
+++   *ssp = *ssp - i;
+++   *ddp = *ddp - ((i << 1) + i);
+++   return i;
+++}
+++
+++#endif /* PNG_ARM_NEON_IMPLEMENTATION */
++diff --git a/third_party/libpng/patches/0000-plte.patch b/third_party/libpng/patches/0000-plte.patch
++new file mode 100644
++index 000000000000..6fceb2f2275a
++--- /dev/null
+++++ b/third_party/libpng/patches/0000-plte.patch
++@@ -0,0 +1,340 @@
+++From aa270a19f7bb9d9cba207b38c0a98cb3a3dc681e Mon Sep 17 00:00:00 2001
+++From: Richard Townsend <Richard.Townsend@arm.com>
+++Date: Mon, 20 Feb 2017 14:06:14 +0000
+++Subject: [PATCH] libpng: Optimize png_do_expand_palette with NEON.
+++
+++ARM-specific optimization processes 8 or 4 pixels at once.
+++
+++* Without transparency: 22% performance gain on the A53 little core.
+++* With transparency: 10% improvement on a big A72 core, 24% on little.
+++
+++(Numbers from image_decode_bench with PNG140 on the elm chromebook).
+++
+++Bug: 706134
+++Change-Id: I7b4a93d72a0afa2823f3bf9ff5f798b88c843e54
+++---
+++ third_party/libpng/BUILD.gn                      |   1 +
+++ third_party/libpng/arm/palette_neon_intrinsics.c | 137 +++++++++++++++++++++++
+++ third_party/libpng/pngpriv.h                     |  23 ++++
+++ third_party/libpng/pngrtran.c                    |  49 ++++++--
+++ third_party/libpng/pngstruct.h                   |   4 +
+++ third_party/libpng/pngwrite.c                    |   4 +
+++ 6 files changed, 210 insertions(+), 8 deletions(-)
+++ create mode 100644 third_party/libpng/arm/palette_neon_intrinsics.c
+++
+++diff --git a/third_party/libpng/BUILD.gn b/third_party/libpng/BUILD.gn
+++index e2658a7ba623..e48c790326c7 100644
+++--- a/third_party/libpng/BUILD.gn
++++++ b/third_party/libpng/BUILD.gn
+++@@ -75,6 +75,7 @@ source_set("libpng_sources") {
+++     sources += [
+++       "arm/arm_init.c",
+++       "arm/filter_neon_intrinsics.c",
++++      "arm/palette_neon_intrinsics.c",
+++     ]
+++     defines += [
+++       "PNG_ARM_NEON_OPT=2",
+++diff --git a/third_party/libpng/arm/palette_neon_intrinsics.c b/third_party/libpng/arm/palette_neon_intrinsics.c
+++new file mode 100644
+++index 000000000000..0c0c0a909f8d
+++--- /dev/null
++++++ b/third_party/libpng/arm/palette_neon_intrinsics.c
+++@@ -0,0 +1,137 @@
++++/* palette_neon_intrinsics.c - NEON optimised palette expansion functions
++++ *
++++ * Copyright (c) 2017 The Chromium Authors. All rights reserved.
++++ * Written by Richard Townsend <Richard.Townsend@arm.com>, February 2017.
++++ *
++++ * This code is released under the libpng license.
++++ * For conditions of distribution and use, see the disclaimer
++++ * and license in png.h
++++ */
++++
++++#include "../pngpriv.h"
++++
++++#if PNG_ARM_NEON_IMPLEMENTATION == 1
++++
++++#include <arm_neon.h>
++++
++++/* Build an RGBA palette from the RGB and separate alpha palettes. */
++++void
++++png_riffle_palette_rgba(png_structrp png_ptr, png_row_infop row_info)
++++{
++++   png_const_colorp palette = png_ptr->palette;
++++   png_bytep riffled_palette = png_ptr->riffled_palette;
++++   png_const_bytep trans_alpha = png_ptr->trans_alpha;
++++   int num_trans = png_ptr->num_trans;
++++
++++   if (row_info->bit_depth != 8) {
++++      png_error(png_ptr, "bit_depth must be 8 for png_riffle_palette_rgba");
++++      return;
++++   }
++++
++++   /* Initially black, opaque. */
++++   uint8x16x4_t w = {
++++      vdupq_n_u8(0x00),
++++      vdupq_n_u8(0x00),
++++      vdupq_n_u8(0x00),
++++      vdupq_n_u8(0xff),
++++   };
++++
++++   int i;
++++   /* First, riffle the RGB colours into a RGBA palette, the A value is
++++    * set to opaque for now. */
++++   for (i = 0; i < (1 << row_info->bit_depth); i += 16) {
++++      uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i));
++++      w.val[0] = v.val[0];
++++      w.val[1] = v.val[1];
++++      w.val[2] = v.val[2];
++++      vst4q_u8(riffled_palette + (i << 2), w);
++++   }
++++
++++   /* Fix up the missing transparency values. */
++++   for (i = 0; i < num_trans; i++) {
++++      riffled_palette[(i << 2) + 3] = trans_alpha[i];
++++   }
++++}
++++
++++
++++/* Expands a palettized row into RGBA. */
++++int
++++png_do_expand_palette_neon_rgba(png_structrp png_ptr, png_row_infop row_info,
++++   png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp)
++++{
++++
++++   png_uint_32 row_width = row_info->width;
++++   const png_uint_32 *riffled_palette = (const png_uint_32*)png_ptr->riffled_palette;
++++   const png_int_32 pixels_per_chunk = 4;
++++
++++   if (row_width < pixels_per_chunk) {
++++      return 0;
++++   }
++++
++++   /* This function originally gets the last byte of the output row.
++++      The NEON part writes forward from a given position, so we have
++++      to seek this back by 4 pixels x 4 bytes. */
++++   *ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1);
++++
++++   int i;
++++   for (i = 0; i < row_width; i += pixels_per_chunk) {
++++      uint32x4_t cur;
++++      png_bytep sp = *ssp - i, dp = *ddp - (i << 2);
++++      cur = vld1q_dup_u32 (riffled_palette + *(sp - 3));
++++      cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1);
++++      cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2);
++++      cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3);
++++      vst1q_u32((void *)dp, cur);
++++   }
++++   if (i != row_width) {
++++      i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */
++++   }
++++
++++   /* Decrement output pointers. */
++++   *ssp = *ssp - i;
++++   *ddp = *ddp - (i << 2);
++++   return i;
++++}
++++
++++/* Expands a palettized row into RGB format. */
++++int
++++png_do_expand_palette_neon_rgb(png_structrp png_ptr, png_row_infop row_info,
++++   png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp)
++++{
++++   png_uint_32 row_width = row_info->width;
++++   png_const_bytep palette = (png_const_bytep)png_ptr->palette;
++++   const png_uint_32 pixels_per_chunk = 8;
++++
++++   if (row_width <= pixels_per_chunk) {
++++      return 0;
++++   }
++++
++++   /* Seeking this back by 8 pixels x 3 bytes. */
++++   *ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1);
++++
++++   int i;
++++   for (i = 0; i < row_width; i += pixels_per_chunk) {
++++      uint8x8x3_t cur;
++++      png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i);
++++      cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7)));
++++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1);
++++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2);
++++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3);
++++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4);
++++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5);
++++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6);
++++      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7);
++++      vst3_u8((void *)dp, cur);
++++   }
++++
++++   if (i != row_width) {
++++      i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */
++++   }
++++
++++   /* Decrement output pointers. */
++++   *ssp = *ssp - i;
++++   *ddp = *ddp - ((i << 1) + i);
++++   return i;
++++}
++++
++++#endif /* PNG_ARM_NEON_IMPLEMENTATION */
+++diff --git a/third_party/libpng/pngpriv.h b/third_party/libpng/pngpriv.h
+++index 1f2e90f2b37b..5652525b2b51 100644
+++--- a/third_party/libpng/pngpriv.h
++++++ b/third_party/libpng/pngpriv.h
+++@@ -2108,6 +2108,29 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,
+++ PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
+++    png_const_charp key, png_bytep new_key), PNG_EMPTY);
+++ 
++++#if PNG_ARM_NEON_IMPLEMENTATION == 1
++++PNG_INTERNAL_FUNCTION(void,
++++                      png_riffle_palette_rgba,
++++                      (png_structrp, png_row_infop),
++++                      PNG_EMPTY);
++++PNG_INTERNAL_FUNCTION(int,
++++                      png_do_expand_palette_neon_rgba,
++++                      (png_structrp,
++++                       png_row_infop,
++++                       png_const_bytep,
++++                       const png_bytepp,
++++                       const png_bytepp),
++++                      PNG_EMPTY);
++++PNG_INTERNAL_FUNCTION(int,
++++                      png_do_expand_palette_neon_rgb,
++++                      (png_structrp,
++++                       png_row_infop,
++++                       png_const_bytep,
++++                       const png_bytepp,
++++                       const png_bytepp),
++++                      PNG_EMPTY);
++++#endif
++++
+++ /* Maintainer: Put new private prototypes here ^ */
+++ 
+++ #include "pngdebug.h"
+++diff --git a/third_party/libpng/pngrtran.c b/third_party/libpng/pngrtran.c
+++index c1896503130e..9dd82c929bdc 100644
+++--- a/third_party/libpng/pngrtran.c
++++++ b/third_party/libpng/pngrtran.c
+++@@ -18,6 +18,13 @@
+++ 
+++ #include "pngpriv.h"
+++ 
++++#ifdef PNG_ARM_NEON_IMPLEMENTATION
++++#if PNG_ARM_NEON_IMPLEMENTATION == 1
++++#define PNG_ARM_NEON_INTRINSICS_AVAILABLE
++++#include <arm_neon.h>
++++#endif
++++#endif
++++
+++ #ifdef PNG_READ_SUPPORTED
+++ 
+++ /* Set the action on getting a CRC error for an ancillary or critical chunk. */
+++@@ -4202,8 +4209,9 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
+++  * upon whether you supply trans and num_trans.
+++  */
+++ static void
+++-png_do_expand_palette(png_row_infop row_info, png_bytep row,
+++-    png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
++++png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
++++   png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha,
++++   int num_trans)
+++ {
+++    int shift, value;
+++    png_bytep sp, dp;
+++@@ -4307,14 +4315,22 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
+++                sp = row + (png_size_t)row_width - 1;
+++                dp = row + ((png_size_t)row_width << 2) - 1;
+++ 
+++-               for (i = 0; i < row_width; i++)
++++               i = 0;
++++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
++++               if (png_ptr->riffled_palette != NULL) {
++++                  /* The RGBA optimization works with png_ptr->bit_depth == 8
++++                     but sometimes row_info->bit_depth has been changed to 8.
++++                     In these cases, the palette hasn't been riffled. */
++++                  i = png_do_expand_palette_neon_rgba(png_ptr, row_info, row, &sp, &dp);
++++               }
++++#endif
++++
++++               for (; i < row_width; i++)
+++                {
+++                   if ((int)(*sp) >= num_trans)
+++                      *dp-- = 0xff;
+++-
+++                   else
+++                      *dp-- = trans_alpha[*sp];
+++-
+++                   *dp-- = palette[*sp].blue;
+++                   *dp-- = palette[*sp].green;
+++                   *dp-- = palette[*sp].red;
+++@@ -4331,8 +4347,12 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
+++             {
+++                sp = row + (png_size_t)row_width - 1;
+++                dp = row + (png_size_t)(row_width * 3) - 1;
++++               i = 0;
++++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
++++               i = png_do_expand_palette_neon_rgb(png_ptr, row_info, row, &sp, &dp);
++++#endif
+++ 
+++-               for (i = 0; i < row_width; i++)
++++               for (; i < row_width; i++)
+++                {
+++                   *dp-- = palette[*sp].blue;
+++                   *dp-- = palette[*sp].green;
+++@@ -4748,8 +4768,21 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
+++    {
+++       if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+++       {
+++-         png_do_expand_palette(row_info, png_ptr->row_buf + 1,
+++-             png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
++++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
++++       if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8)) {
++++          /* Allocate space for the decompressed full palette. */
++++          if (png_ptr->riffled_palette == NULL) {
++++              png_ptr->riffled_palette = png_malloc(png_ptr, 256*4);
++++              if (png_ptr->riffled_palette == NULL) {
++++                  png_error(png_ptr, "NULL row buffer");
++++              }
++++              /* Build the RGBA palette. */
++++              png_riffle_palette_rgba(png_ptr, row_info);
++++          }
++++       }
++++#endif
++++         png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1,
++++            png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
+++       }
+++ 
+++       else
+++diff --git a/third_party/libpng/pngstruct.h b/third_party/libpng/pngstruct.h
+++index d83f971253fe..aac88df02d32 100644
+++--- a/third_party/libpng/pngstruct.h
++++++ b/third_party/libpng/pngstruct.h
+++@@ -228,6 +228,10 @@ struct png_struct_def
+++                                * big_row_buf; while writing it is separately
+++                                * allocated.
+++                                */
++++#ifdef PNG_READ_EXPAND_SUPPORTED
++++   /* Buffer to accelerate palette transformations. */
++++   png_bytep riffled_palette;
++++#endif
+++ #ifdef PNG_WRITE_FILTER_SUPPORTED
+++    png_bytep try_row;    /* buffer to save trial row when filtering */
+++    png_bytep tst_row;    /* buffer to save best trial row when filtering */
+++diff --git a/third_party/libpng/pngwrite.c b/third_party/libpng/pngwrite.c
+++index a16d77ce00c6..e25e5dcfdc18 100644
+++--- a/third_party/libpng/pngwrite.c
++++++ b/third_party/libpng/pngwrite.c
+++@@ -948,6 +948,10 @@ png_write_destroy(png_structrp png_ptr)
+++    png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
+++    png_free(png_ptr, png_ptr->row_buf);
+++    png_ptr->row_buf = NULL;
++++#ifdef PNG_READ_EXPANDED_SUPPORTED
++++   png_free(png_ptr, png_ptr->riffled_palette);
++++   png_ptr->riffled_palette = NULL;
++++#endif
+++ #ifdef PNG_WRITE_FILTER_SUPPORTED
+++    png_free(png_ptr, png_ptr->prev_row);
+++    png_free(png_ptr, png_ptr->try_row);
+++-- 
+++2.15.1
+++
++diff --git a/third_party/libpng/patches/README b/third_party/libpng/patches/README
++new file mode 100644
++index 000000000000..786aeabede37
++--- /dev/null
+++++ b/third_party/libpng/patches/README
++@@ -0,0 +1,4 @@
+++This directory contains patches applied on top of libpng, which haven't been
+++upstreamed to the canonical libpng repository [1] yet.
+++
+++[1] https://github.com/glennrp/libpng
++diff --git a/third_party/libpng/pngpriv.h b/third_party/libpng/pngpriv.h
++index 1f2e90f2b37b..5652525b2b51 100644
++--- a/third_party/libpng/pngpriv.h
+++++ b/third_party/libpng/pngpriv.h
++@@ -2108,6 +2108,29 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,
++ PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
++    png_const_charp key, png_bytep new_key), PNG_EMPTY);
++ 
+++#if PNG_ARM_NEON_IMPLEMENTATION == 1
+++PNG_INTERNAL_FUNCTION(void,
+++                      png_riffle_palette_rgba,
+++                      (png_structrp, png_row_infop),
+++                      PNG_EMPTY);
+++PNG_INTERNAL_FUNCTION(int,
+++                      png_do_expand_palette_neon_rgba,
+++                      (png_structrp,
+++                       png_row_infop,
+++                       png_const_bytep,
+++                       const png_bytepp,
+++                       const png_bytepp),
+++                      PNG_EMPTY);
+++PNG_INTERNAL_FUNCTION(int,
+++                      png_do_expand_palette_neon_rgb,
+++                      (png_structrp,
+++                       png_row_infop,
+++                       png_const_bytep,
+++                       const png_bytepp,
+++                       const png_bytepp),
+++                      PNG_EMPTY);
+++#endif
+++
++ /* Maintainer: Put new private prototypes here ^ */
++ 
++ #include "pngdebug.h"
++diff --git a/third_party/libpng/pngrtran.c b/third_party/libpng/pngrtran.c
++index c1896503130e..9dd82c929bdc 100644
++--- a/third_party/libpng/pngrtran.c
+++++ b/third_party/libpng/pngrtran.c
++@@ -18,6 +18,13 @@
++ 
++ #include "pngpriv.h"
++ 
+++#ifdef PNG_ARM_NEON_IMPLEMENTATION
+++#if PNG_ARM_NEON_IMPLEMENTATION == 1
+++#define PNG_ARM_NEON_INTRINSICS_AVAILABLE
+++#include <arm_neon.h>
+++#endif
+++#endif
+++
++ #ifdef PNG_READ_SUPPORTED
++ 
++ /* Set the action on getting a CRC error for an ancillary or critical chunk. */
++@@ -4202,8 +4209,9 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
++  * upon whether you supply trans and num_trans.
++  */
++ static void
++-png_do_expand_palette(png_row_infop row_info, png_bytep row,
++-    png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
+++png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
+++   png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha,
+++   int num_trans)
++ {
++    int shift, value;
++    png_bytep sp, dp;
++@@ -4307,14 +4315,22 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
++                sp = row + (png_size_t)row_width - 1;
++                dp = row + ((png_size_t)row_width << 2) - 1;
++ 
++-               for (i = 0; i < row_width; i++)
+++               i = 0;
+++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
+++               if (png_ptr->riffled_palette != NULL) {
+++                  /* The RGBA optimization works with png_ptr->bit_depth == 8
+++                     but sometimes row_info->bit_depth has been changed to 8.
+++                     In these cases, the palette hasn't been riffled. */
+++                  i = png_do_expand_palette_neon_rgba(png_ptr, row_info, row, &sp, &dp);
+++               }
+++#endif
+++
+++               for (; i < row_width; i++)
++                {
++                   if ((int)(*sp) >= num_trans)
++                      *dp-- = 0xff;
++-
++                   else
++                      *dp-- = trans_alpha[*sp];
++-
++                   *dp-- = palette[*sp].blue;
++                   *dp-- = palette[*sp].green;
++                   *dp-- = palette[*sp].red;
++@@ -4331,8 +4347,12 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
++             {
++                sp = row + (png_size_t)row_width - 1;
++                dp = row + (png_size_t)(row_width * 3) - 1;
+++               i = 0;
+++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
+++               i = png_do_expand_palette_neon_rgb(png_ptr, row_info, row, &sp, &dp);
+++#endif
++ 
++-               for (i = 0; i < row_width; i++)
+++               for (; i < row_width; i++)
++                {
++                   *dp-- = palette[*sp].blue;
++                   *dp-- = palette[*sp].green;
++@@ -4748,8 +4768,21 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
++    {
++       if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
++       {
++-         png_do_expand_palette(row_info, png_ptr->row_buf + 1,
++-             png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
+++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
+++       if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8)) {
+++          /* Allocate space for the decompressed full palette. */
+++          if (png_ptr->riffled_palette == NULL) {
+++              png_ptr->riffled_palette = png_malloc(png_ptr, 256*4);
+++              if (png_ptr->riffled_palette == NULL) {
+++                  png_error(png_ptr, "NULL row buffer");
+++              }
+++              /* Build the RGBA palette. */
+++              png_riffle_palette_rgba(png_ptr, row_info);
+++          }
+++       }
+++#endif
+++         png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1,
+++            png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
++       }
++ 
++       else
++diff --git a/third_party/libpng/pngstruct.h b/third_party/libpng/pngstruct.h
++index d83f971253fe..aac88df02d32 100644
++--- a/third_party/libpng/pngstruct.h
+++++ b/third_party/libpng/pngstruct.h
++@@ -228,6 +228,10 @@ struct png_struct_def
++                                * big_row_buf; while writing it is separately
++                                * allocated.
++                                */
+++#ifdef PNG_READ_EXPAND_SUPPORTED
+++   /* Buffer to accelerate palette transformations. */
+++   png_bytep riffled_palette;
+++#endif
++ #ifdef PNG_WRITE_FILTER_SUPPORTED
++    png_bytep try_row;    /* buffer to save trial row when filtering */
++    png_bytep tst_row;    /* buffer to save best trial row when filtering */
++diff --git a/third_party/libpng/pngwrite.c b/third_party/libpng/pngwrite.c
++index a16d77ce00c6..e25e5dcfdc18 100644
++--- a/third_party/libpng/pngwrite.c
+++++ b/third_party/libpng/pngwrite.c
++@@ -948,6 +948,10 @@ png_write_destroy(png_structrp png_ptr)
++    png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
++    png_free(png_ptr, png_ptr->row_buf);
++    png_ptr->row_buf = NULL;
+++#ifdef PNG_READ_EXPANDED_SUPPORTED
+++   png_free(png_ptr, png_ptr->riffled_palette);
+++   png_ptr->riffled_palette = NULL;
+++#endif
++ #ifdef PNG_WRITE_FILTER_SUPPORTED
++    png_free(png_ptr, png_ptr->prev_row);
++    png_free(png_ptr, png_ptr->try_row);
++-- 
++2.16.0.rc1.238.g530d649a79-goog
++
++
++From 736276e0ec02b5078ca98cfe6ed0bb3f86524a8b Mon Sep 17 00:00:00 2001
++From: Chris Blume <cblume@google.com>
++Date: Tue, 16 Jan 2018 13:25:38 -0800
++Subject: [PATCH 2/2] Explicitly initialize the member of the variable
++
++---
++ third_party/libpng/arm/palette_neon_intrinsics.c | 4 ++--
++ 1 file changed, 2 insertions(+), 2 deletions(-)
++
++diff --git a/third_party/libpng/arm/palette_neon_intrinsics.c b/third_party/libpng/arm/palette_neon_intrinsics.c
++index 0c0c0a909f8d..703b9ff25053 100644
++--- a/third_party/libpng/arm/palette_neon_intrinsics.c
+++++ b/third_party/libpng/arm/palette_neon_intrinsics.c
++@@ -29,12 +29,12 @@ png_riffle_palette_rgba(png_structrp png_ptr, png_row_infop row_info)
++    }
++ 
++    /* Initially black, opaque. */
++-   uint8x16x4_t w = {
+++   uint8x16x4_t w = {{
++       vdupq_n_u8(0x00),
++       vdupq_n_u8(0x00),
++       vdupq_n_u8(0x00),
++       vdupq_n_u8(0xff),
++-   };
+++   }};
++ 
++    int i;
++    /* First, riffle the RGB colours into a RGBA palette, the A value is
++-- 
++2.16.0.rc1.238.g530d649a79-goog
++
+diff --git a/third_party/libpng/patches/README b/third_party/libpng/patches/README
+new file mode 100644
+index 000000000000..786aeabede37
+--- /dev/null
++++ b/third_party/libpng/patches/README
+@@ -0,0 +1,4 @@
++This directory contains patches applied on top of libpng, which haven't been
++upstreamed to the canonical libpng repository [1] yet.
++
++[1] https://github.com/glennrp/libpng
+diff --git a/third_party/libpng/pngpriv.h b/third_party/libpng/pngpriv.h
+index 1f2e90f2b37b..5652525b2b51 100644
+--- a/third_party/libpng/pngpriv.h
++++ b/third_party/libpng/pngpriv.h
+@@ -2108,6 +2108,29 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,
+ PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
+    png_const_charp key, png_bytep new_key), PNG_EMPTY);
+ 
++#if PNG_ARM_NEON_IMPLEMENTATION == 1
++PNG_INTERNAL_FUNCTION(void,
++                      png_riffle_palette_rgba,
++                      (png_structrp, png_row_infop),
++                      PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int,
++                      png_do_expand_palette_neon_rgba,
++                      (png_structrp,
++                       png_row_infop,
++                       png_const_bytep,
++                       const png_bytepp,
++                       const png_bytepp),
++                      PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int,
++                      png_do_expand_palette_neon_rgb,
++                      (png_structrp,
++                       png_row_infop,
++                       png_const_bytep,
++                       const png_bytepp,
++                       const png_bytepp),
++                      PNG_EMPTY);
++#endif
++
+ /* Maintainer: Put new private prototypes here ^ */
+ 
+ #include "pngdebug.h"
+diff --git a/third_party/libpng/pngrtran.c b/third_party/libpng/pngrtran.c
+index c1896503130e..9dd82c929bdc 100644
+--- a/third_party/libpng/pngrtran.c
++++ b/third_party/libpng/pngrtran.c
+@@ -18,6 +18,13 @@
+ 
+ #include "pngpriv.h"
+ 
++#ifdef PNG_ARM_NEON_IMPLEMENTATION
++#if PNG_ARM_NEON_IMPLEMENTATION == 1
++#define PNG_ARM_NEON_INTRINSICS_AVAILABLE
++#include <arm_neon.h>
++#endif
++#endif
++
+ #ifdef PNG_READ_SUPPORTED
+ 
+ /* Set the action on getting a CRC error for an ancillary or critical chunk. */
+@@ -4202,8 +4209,9 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
+  * upon whether you supply trans and num_trans.
+  */
+ static void
+-png_do_expand_palette(png_row_infop row_info, png_bytep row,
+-    png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
++png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
++   png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha,
++   int num_trans)
+ {
+    int shift, value;
+    png_bytep sp, dp;
+@@ -4307,14 +4315,22 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
+                sp = row + (png_size_t)row_width - 1;
+                dp = row + ((png_size_t)row_width << 2) - 1;
+ 
+-               for (i = 0; i < row_width; i++)
++               i = 0;
++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
++               if (png_ptr->riffled_palette != NULL) {
++                  /* The RGBA optimization works with png_ptr->bit_depth == 8
++                     but sometimes row_info->bit_depth has been changed to 8.
++                     In these cases, the palette hasn't been riffled. */
++                  i = png_do_expand_palette_neon_rgba(png_ptr, row_info, row, &sp, &dp);
++               }
++#endif
++
++               for (; i < row_width; i++)
+                {
+                   if ((int)(*sp) >= num_trans)
+                      *dp-- = 0xff;
+-
+                   else
+                      *dp-- = trans_alpha[*sp];
+-
+                   *dp-- = palette[*sp].blue;
+                   *dp-- = palette[*sp].green;
+                   *dp-- = palette[*sp].red;
+@@ -4331,8 +4347,12 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
+             {
+                sp = row + (png_size_t)row_width - 1;
+                dp = row + (png_size_t)(row_width * 3) - 1;
++               i = 0;
++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
++               i = png_do_expand_palette_neon_rgb(png_ptr, row_info, row, &sp, &dp);
++#endif
+ 
+-               for (i = 0; i < row_width; i++)
++               for (; i < row_width; i++)
+                {
+                   *dp-- = palette[*sp].blue;
+                   *dp-- = palette[*sp].green;
+@@ -4748,8 +4768,21 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
+    {
+       if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+       {
+-         png_do_expand_palette(row_info, png_ptr->row_buf + 1,
+-             png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
++       if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8)) {
++          /* Allocate space for the decompressed full palette. */
++          if (png_ptr->riffled_palette == NULL) {
++              png_ptr->riffled_palette = png_malloc(png_ptr, 256*4);
++              if (png_ptr->riffled_palette == NULL) {
++                  png_error(png_ptr, "NULL row buffer");
++              }
++              /* Build the RGBA palette. */
++              png_riffle_palette_rgba(png_ptr, row_info);
++          }
++       }
++#endif
++         png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1,
++            png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
+       }
+ 
+       else
+diff --git a/third_party/libpng/pngstruct.h b/third_party/libpng/pngstruct.h
+index d83f971253fe..aac88df02d32 100644
+--- a/third_party/libpng/pngstruct.h
++++ b/third_party/libpng/pngstruct.h
+@@ -228,6 +228,10 @@ struct png_struct_def
+                                * big_row_buf; while writing it is separately
+                                * allocated.
+                                */
++#ifdef PNG_READ_EXPAND_SUPPORTED
++   /* Buffer to accelerate palette transformations. */
++   png_bytep riffled_palette;
++#endif
+ #ifdef PNG_WRITE_FILTER_SUPPORTED
+    png_bytep try_row;    /* buffer to save trial row when filtering */
+    png_bytep tst_row;    /* buffer to save best trial row when filtering */
+diff --git a/third_party/libpng/pngwrite.c b/third_party/libpng/pngwrite.c
+index a16d77ce00c6..e25e5dcfdc18 100644
+--- a/third_party/libpng/pngwrite.c
++++ b/third_party/libpng/pngwrite.c
+@@ -948,6 +948,10 @@ png_write_destroy(png_structrp png_ptr)
+    png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
+    png_free(png_ptr, png_ptr->row_buf);
+    png_ptr->row_buf = NULL;
++#ifdef PNG_READ_EXPANDED_SUPPORTED
++   png_free(png_ptr, png_ptr->riffled_palette);
++   png_ptr->riffled_palette = NULL;
++#endif
+ #ifdef PNG_WRITE_FILTER_SUPPORTED
+    png_free(png_ptr, png_ptr->prev_row);
+    png_free(png_ptr, png_ptr->try_row);
+-- 
+2.16.0.rc1.238.g530d649a79-goog
+
diff --git a/third_party/libpng/patches/README b/third_party/libpng/patches/README
new file mode 100644
index 0000000..786aeab
--- /dev/null
+++ b/third_party/libpng/patches/README
@@ -0,0 +1,4 @@
+This directory contains patches applied on top of libpng, which haven't been
+upstreamed to the canonical libpng repository [1] yet.
+
+[1] https://github.com/glennrp/libpng
diff --git a/third_party/libpng/png.c b/third_party/libpng/png.c
index 6e4cbed..ff02c56 100644
--- a/third_party/libpng/png.c
+++ b/third_party/libpng/png.c
@@ -1,8 +1,8 @@
 
 /* png.c - location for general purpose libpng functions
  *
- * Last changed in libpng 1.6.19 [November 12, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -14,7 +14,27 @@
 #include "pngpriv.h"
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_22 Your_png_h_is_not_version_1_6_22;
+typedef png_libpng_version_1_6_34 Your_png_h_is_not_version_1_6_34;
+
+#ifdef __GNUC__
+/* The version tests may need to be added to, but the problem warning has
+ * consistently been fixed in GCC versions which obtain wide-spread release.
+ * The problem is that many versions of GCC rearrange comparison expressions in
+ * the optimizer in such a way that the results of the comparison will change
+ * if signed integer overflow occurs.  Such comparisons are not permitted in
+ * ANSI C90, however GCC isn't clever enough to work out that that do not occur
+ * below in png_ascii_from_fp and png_muldiv, so it produces a warning with
+ * -Wextra.  Unfortunately this is highly dependent on the optimizer and the
+ * machine architecture so the warning comes and goes unpredictably and is
+ * impossible to "fix", even were that a good idea.
+ */
+#if __GNUC__ == 7 && __GNUC_MINOR__ == 1
+#define GCC_STRICT_OVERFLOW 1
+#endif /* GNU 7.1.x */
+#endif /* GNU */
+#ifndef GCC_STRICT_OVERFLOW
+#define GCC_STRICT_OVERFLOW 0
+#endif
 
 /* Tells libpng that we have already handled the first "num_bytes" bytes
  * of the PNG file signature.  If the PNG data is embedded into another
@@ -85,7 +105,7 @@
    if (items >= (~(png_alloc_size_t)0)/size)
    {
       png_warning (png_voidcast(png_structrp, png_ptr),
-         "Potential overflow in png_zalloc()");
+          "Potential overflow in png_zalloc()");
       return NULL;
    }
 
@@ -172,10 +192,10 @@
 int
 png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
 {
-     /* Libpng versions 1.0.0 and later are binary compatible if the version
-      * string matches through the second '.'; we must recompile any
-      * applications that use any older library version.
-      */
+   /* Libpng versions 1.0.0 and later are binary compatible if the version
+    * string matches through the second '.'; we must recompile any
+    * applications that use any older library version.
+    */
 
    if (user_png_ver != NULL)
    {
@@ -297,7 +317,7 @@
          if (png_user_version_check(&create_struct, user_png_ver) != 0)
          {
             png_structrp png_ptr = png_voidcast(png_structrp,
-               png_malloc_warn(&create_struct, (sizeof *png_ptr)));
+                png_malloc_warn(&create_struct, (sizeof *png_ptr)));
 
             if (png_ptr != NULL)
             {
@@ -346,7 +366,7 @@
     * has always been done in 'example.c'.
     */
    info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
-      (sizeof *info_ptr)));
+       (sizeof *info_ptr)));
 
    if (info_ptr != NULL)
       memset(info_ptr, 0, (sizeof *info_ptr));
@@ -402,7 +422,7 @@
  */
 PNG_FUNCTION(void,PNGAPI
 png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
-   PNG_DEPRECATED)
+    PNG_DEPRECATED)
 {
    png_inforp info_ptr = *ptr_ptr;
 
@@ -417,7 +437,7 @@
       /* The following line is why this API should not be used: */
       free(info_ptr);
       info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
-         (sizeof *info_ptr)));
+          (sizeof *info_ptr)));
       if (info_ptr == NULL)
          return;
       *ptr_ptr = info_ptr;
@@ -430,7 +450,7 @@
 /* The following API is not called internally */
 void PNGAPI
 png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
-   int freer, png_uint_32 mask)
+    int freer, png_uint_32 mask)
 {
    png_debug(1, "in png_data_freer");
 
@@ -449,7 +469,7 @@
 
 void PNGAPI
 png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
-   int num)
+    int num)
 {
    png_debug(1, "in png_free_data");
 
@@ -458,7 +478,7 @@
 
 #ifdef PNG_TEXT_SUPPORTED
    /* Free text item num or (if num == -1) all text items */
-   if (info_ptr->text != 0 &&
+   if (info_ptr->text != NULL &&
        ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0)
    {
       if (num != -1)
@@ -477,6 +497,7 @@
          png_free(png_ptr, info_ptr->text);
          info_ptr->text = NULL;
          info_ptr->num_text = 0;
+         info_ptr->max_text = 0;
       }
    }
 #endif
@@ -541,7 +562,7 @@
 
 #ifdef PNG_sPLT_SUPPORTED
    /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
-   if (info_ptr->splt_palettes != 0 &&
+   if (info_ptr->splt_palettes != NULL &&
        ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0)
    {
       if (num != -1)
@@ -571,7 +592,7 @@
 #endif
 
 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
-   if (info_ptr->unknown_chunks != 0 &&
+   if (info_ptr->unknown_chunks != NULL &&
        ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0)
    {
       if (num != -1)
@@ -594,6 +615,26 @@
    }
 #endif
 
+#ifdef PNG_eXIf_SUPPORTED
+   /* Free any eXIf entry */
+   if (((mask & PNG_FREE_EXIF) & info_ptr->free_me) != 0)
+   {
+# ifdef PNG_READ_eXIf_SUPPORTED
+      if (info_ptr->eXIf_buf)
+      {
+         png_free(png_ptr, info_ptr->eXIf_buf);
+         info_ptr->eXIf_buf = NULL;
+      }
+# endif
+      if (info_ptr->exif)
+      {
+         png_free(png_ptr, info_ptr->exif);
+         info_ptr->exif = NULL;
+      }
+      info_ptr->valid &= ~PNG_INFO_eXIf;
+   }
+#endif
+
 #ifdef PNG_hIST_SUPPORTED
    /* Free any hIST entry */
    if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)
@@ -617,7 +658,7 @@
    /* Free any image bits attached to the info structure */
    if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0)
    {
-      if (info_ptr->row_pointers != 0)
+      if (info_ptr->row_pointers != NULL)
       {
          png_uint_32 row;
          for (row = 0; row < info_ptr->height; row++)
@@ -684,7 +725,7 @@
 void PNGAPI
 png_save_int_32(png_bytep buf, png_int_32 i)
 {
-   png_save_uint_32(buf, i);
+   png_save_uint_32(buf, (png_uint_32)i);
 }
 #  endif
 
@@ -775,15 +816,15 @@
 #else
 #  ifdef __STDC__
    return PNG_STRING_NEWLINE \
-      "libpng version 1.6.22 - May 26, 2016" PNG_STRING_NEWLINE \
-      "Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson" \
+      "libpng version 1.6.34 - September 29, 2017" PNG_STRING_NEWLINE \
+      "Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson" \
       PNG_STRING_NEWLINE \
       "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
       "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
       PNG_STRING_NEWLINE;
 #  else
-   return "libpng version 1.6.22 - May 26, 2016\
-      Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson\
+   return "libpng version 1.6.34 - September 29, 2017\
+      Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson\
       Copyright (c) 1996-1997 Andreas Dilger\
       Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
 #  endif
@@ -1033,7 +1074,7 @@
 #ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
 static int
 png_colorspace_check_gamma(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, png_fixed_point gAMA, int from)
+    png_colorspacerp colorspace, png_fixed_point gAMA, int from)
    /* This is called to check a new gamma value against an existing one.  The
     * routine returns false if the new gamma value should not be written.
     *
@@ -1047,7 +1088,7 @@
    png_fixed_point gtest;
 
    if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
-      (png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) == 0  ||
+       (png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) == 0  ||
       png_gamma_significant(gtest) != 0))
    {
       /* Either this is an sRGB image, in which case the calculated gamma
@@ -1059,7 +1100,7 @@
       if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
       {
          png_chunk_report(png_ptr, "gamma value does not match sRGB",
-            PNG_CHUNK_ERROR);
+             PNG_CHUNK_ERROR);
          /* Do not overwrite an sRGB value */
          return from == 2;
       }
@@ -1067,7 +1108,7 @@
       else /* sRGB tag not involved */
       {
          png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
-            PNG_CHUNK_WARNING);
+             PNG_CHUNK_WARNING);
          return from == 1;
       }
    }
@@ -1077,7 +1118,7 @@
 
 void /* PRIVATE */
 png_colorspace_set_gamma(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, png_fixed_point gAMA)
+    png_colorspacerp colorspace, png_fixed_point gAMA)
 {
    /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
     * occur.  Since the fixed point representation is asymetrical it is
@@ -1635,8 +1676,8 @@
 
 static int
 png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
-   int preferred)
+    png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
+    int preferred)
 {
    if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
       return 0;
@@ -1683,7 +1724,7 @@
 
 int /* PRIVATE */
 png_colorspace_set_chromaticities(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, const png_xy *xy, int preferred)
+    png_colorspacerp colorspace, const png_xy *xy, int preferred)
 {
    /* We must check the end points to ensure they are reasonable - in the past
     * color management systems have crashed as a result of getting bogus
@@ -1697,7 +1738,7 @@
    {
       case 0: /* success */
          return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
-            preferred);
+             preferred);
 
       case 1:
          /* We can't invert the chromaticities so we can't produce value XYZ
@@ -1720,7 +1761,7 @@
 
 int /* PRIVATE */
 png_colorspace_set_endpoints(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
+    png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
 {
    png_XYZ XYZ = *XYZ_in;
    png_xy xy;
@@ -1729,7 +1770,7 @@
    {
       case 0:
          return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
-            preferred);
+             preferred);
 
       case 1:
          /* End points are invalid. */
@@ -1786,7 +1827,7 @@
 
 static int
 png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_alloc_size_t value, png_const_charp reason)
+    png_const_charp name, png_alloc_size_t value, png_const_charp reason)
 {
    size_t pos;
    char message[196]; /* see below for calculation */
@@ -1811,8 +1852,8 @@
          char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
 
          pos = png_safecat(message, (sizeof message), pos,
-            png_format_number(number, number+(sizeof number),
-               PNG_NUMBER_FORMAT_x, value));
+             png_format_number(number, number+(sizeof number),
+             PNG_NUMBER_FORMAT_x, value));
          pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
       }
 #  endif
@@ -1826,7 +1867,7 @@
     * application errors the PNG won't be written.)
     */
    png_chunk_report(png_ptr, message,
-      (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
+       (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
 
    return 0;
 }
@@ -1835,7 +1876,7 @@
 #ifdef PNG_sRGB_SUPPORTED
 int /* PRIVATE */
 png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   int intent)
+    int intent)
 {
    /* sRGB sets known gamma, end points and (from the chunk) intent. */
    /* IMPORTANT: these are not necessarily the values found in an ICC profile
@@ -1872,12 +1913,12 @@
     */
    if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
       return png_icc_profile_error(png_ptr, colorspace, "sRGB",
-         (unsigned)intent, "invalid sRGB rendering intent");
+          (png_alloc_size_t)intent, "invalid sRGB rendering intent");
 
    if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
-      colorspace->rendering_intent != intent)
+       colorspace->rendering_intent != intent)
       return png_icc_profile_error(png_ptr, colorspace, "sRGB",
-         (unsigned)intent, "inconsistent rendering intents");
+         (png_alloc_size_t)intent, "inconsistent rendering intents");
 
    if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
    {
@@ -1889,8 +1930,8 @@
     * warn but overwrite the value with the correct one.
     */
    if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
-      !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
-         100))
+       !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
+       100))
       png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
          PNG_CHUNK_ERROR);
 
@@ -1898,7 +1939,7 @@
     * returns true when the 'from' argument corresponds to sRGB (2).
     */
    (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
-      2/*from sRGB*/);
+       2/*from sRGB*/);
 
    /* intent: bugs in GCC force 'int' to be used as the parameter type. */
    colorspace->rendering_intent = (png_uint_16)intent;
@@ -1933,12 +1974,11 @@
 
 static int /* bool */
 icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_uint_32 profile_length)
+    png_const_charp name, png_uint_32 profile_length)
 {
    if (profile_length < 132)
       return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
-         "too short");
-
+          "too short");
    return 1;
 }
 
@@ -1978,8 +2018,8 @@
 
 int /* PRIVATE */
 png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_uint_32 profile_length,
-   png_const_bytep profile/* first 132 bytes only */, int color_type)
+    png_const_charp name, png_uint_32 profile_length,
+    png_const_bytep profile/* first 132 bytes only */, int color_type)
 {
    png_uint_32 temp;
 
@@ -1991,18 +2031,18 @@
    temp = png_get_uint_32(profile);
    if (temp != profile_length)
       return png_icc_profile_error(png_ptr, colorspace, name, temp,
-         "length does not match profile");
+          "length does not match profile");
 
    temp = (png_uint_32) (*(profile+8));
    if (temp > 3 && (profile_length & 3))
       return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
-         "invalid length");
+          "invalid length");
 
    temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
    if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
       profile_length < 132+12*temp) /* truncated tag table */
       return png_icc_profile_error(png_ptr, colorspace, name, temp,
-         "tag count too large");
+          "tag count too large");
 
    /* The 'intent' must be valid or we can't store it, ICC limits the intent to
     * 16 bits.
@@ -2010,14 +2050,14 @@
    temp = png_get_uint_32(profile+64);
    if (temp >= 0xffff) /* The ICC limit */
       return png_icc_profile_error(png_ptr, colorspace, name, temp,
-         "invalid rendering intent");
+          "invalid rendering intent");
 
    /* This is just a warning because the profile may be valid in future
     * versions.
     */
    if (temp >= PNG_sRGB_INTENT_LAST)
       (void)png_icc_profile_error(png_ptr, NULL, name, temp,
-         "intent outside defined range");
+          "intent outside defined range");
 
    /* At this point the tag table can't be checked because it hasn't necessarily
     * been loaded; however, various header fields can be checked.  These checks
@@ -2034,7 +2074,7 @@
    temp = png_get_uint_32(profile+36); /* signature 'ascp' */
    if (temp != 0x61637370)
       return png_icc_profile_error(png_ptr, colorspace, name, temp,
-         "invalid signature");
+          "invalid signature");
 
    /* Currently the PCS illuminant/adopted white point (the computational
     * white point) are required to be D50,
@@ -2045,7 +2085,7 @@
     */
    if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
       (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
-         "PCS illuminant is not D50");
+          "PCS illuminant is not D50");
 
    /* The PNG spec requires this:
     * "If the iCCP chunk is present, the image samples conform to the colour
@@ -2073,18 +2113,18 @@
       case 0x52474220: /* 'RGB ' */
          if ((color_type & PNG_COLOR_MASK_COLOR) == 0)
             return png_icc_profile_error(png_ptr, colorspace, name, temp,
-               "RGB color space not permitted on grayscale PNG");
+                "RGB color space not permitted on grayscale PNG");
          break;
 
       case 0x47524159: /* 'GRAY' */
          if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
             return png_icc_profile_error(png_ptr, colorspace, name, temp,
-               "Gray color space not permitted on RGB PNG");
+                "Gray color space not permitted on RGB PNG");
          break;
 
       default:
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
-            "invalid ICC profile color space");
+             "invalid ICC profile color space");
    }
 
    /* It is up to the application to check that the profile class matches the
@@ -2109,7 +2149,7 @@
       case 0x61627374: /* 'abst' */
          /* May not be embedded in an image */
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
-            "invalid embedded Abstract ICC profile");
+             "invalid embedded Abstract ICC profile");
 
       case 0x6c696e6b: /* 'link' */
          /* DeviceLink profiles cannot be interpreted in a non-device specific
@@ -2119,7 +2159,7 @@
           * PNG.
           */
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
-            "unexpected DeviceLink ICC profile class");
+             "unexpected DeviceLink ICC profile class");
 
       case 0x6e6d636c: /* 'nmcl' */
          /* A NamedColor profile is also device specific, however it doesn't
@@ -2127,7 +2167,7 @@
           * certainly it will fail the tests below.
           */
          (void)png_icc_profile_error(png_ptr, NULL, name, temp,
-            "unexpected NamedColor ICC profile class");
+             "unexpected NamedColor ICC profile class");
          break;
 
       default:
@@ -2137,7 +2177,7 @@
           * understood profiles.
           */
          (void)png_icc_profile_error(png_ptr, NULL, name, temp,
-            "unrecognized ICC profile class");
+             "unrecognized ICC profile class");
          break;
    }
 
@@ -2153,7 +2193,7 @@
 
       default:
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
-            "unexpected ICC PCS encoding");
+             "unexpected ICC PCS encoding");
    }
 
    return 1;
@@ -2161,8 +2201,8 @@
 
 int /* PRIVATE */
 png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_uint_32 profile_length,
-   png_const_bytep profile /* header plus whole tag table */)
+    png_const_charp name, png_uint_32 profile_length,
+    png_const_bytep profile /* header plus whole tag table */)
 {
    png_uint_32 tag_count = png_get_uint_32(profile+128);
    png_uint_32 itag;
@@ -2183,22 +2223,23 @@
        * being in range.  All defined tag types have an 8 byte header - a 4 byte
        * type signature then 0.
        */
-      if ((tag_start & 3) != 0)
-      {
-         /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is
-          * only a warning here because libpng does not care about the
-          * alignment.
-          */
-         (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
-            "ICC profile tag start not a multiple of 4");
-      }
 
       /* This is a hard error; potentially it can cause read outside the
        * profile.
        */
       if (tag_start > profile_length || tag_length > profile_length - tag_start)
          return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
-            "ICC profile tag outside profile");
+             "ICC profile tag outside profile");
+
+      if ((tag_start & 3) != 0)
+      {
+         /* CNHP730S.icc shipped with Microsoft Windows 64 violates this; it is
+          * only a warning here because libpng does not care about the
+          * alignment.
+          */
+         (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
+             "ICC profile tag start not a multiple of 4");
+      }
    }
 
    return 1; /* success, maybe with warnings */
@@ -2226,22 +2267,22 @@
     */
    /* adler32, crc32, MD5[4], intent, date, length, file-name */
    PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
-      PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
-      "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
+       PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
+       "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
 
    /* ICC sRGB v2 perceptual no black-compensation: */
    PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
-      PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
-      "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
+       PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
+       "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
 
    PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
-      PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
-      "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
+       PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
+       "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
 
    /* ICC sRGB v4 perceptual */
    PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
-      PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
-      "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
+       PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
+       "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
 
    /* The following profiles have no known MD5 checksum. If there is a match
     * on the (empty) MD5 the other fields are used to attempt a match and
@@ -2249,8 +2290,8 @@
     * which suggests that they were also made by Hewlett Packard.
     */
    PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
-      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
-      "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
+       PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
+       "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
 
    /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
     * match the D50 PCS illuminant in the header (it is in fact the D65 values,
@@ -2260,17 +2301,17 @@
     * chromaticAdaptationTag.
     */
    PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
-      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
-      "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
+       PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
+       "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
 
    PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
-      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
-      "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
+       PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
+       "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
 };
 
 static int
 png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
-   png_const_bytep profile, uLong adler)
+    png_const_bytep profile, uLong adler)
 {
    /* The quick check is to verify just the MD5 signature and trust the
     * rest of the data.  Because the profile has already been verified for
@@ -2354,7 +2395,7 @@
                       * which is made irrelevant by this error.
                       */
                      png_chunk_report(png_ptr, "known incorrect sRGB profile",
-                        PNG_CHUNK_ERROR);
+                         PNG_CHUNK_ERROR);
                   }
 
                   /* Warn that this being done; this isn't even an error since
@@ -2364,8 +2405,8 @@
                   else if (png_sRGB_checks[i].have_md5 == 0)
                   {
                      png_chunk_report(png_ptr,
-                        "out-of-date sRGB profile with no signature",
-                        PNG_CHUNK_WARNING);
+                         "out-of-date sRGB profile with no signature",
+                         PNG_CHUNK_WARNING);
                   }
 
                   return 1+png_sRGB_checks[i].is_broken;
@@ -2388,38 +2429,36 @@
 
    return 0; /* no match */
 }
-#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
 
 void /* PRIVATE */
 png_icc_set_sRGB(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
+    png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
 {
    /* Is this profile one of the known ICC sRGB profiles?  If it is, just set
     * the sRGB information.
     */
-#if PNG_sRGB_PROFILE_CHECKS >= 0
    if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)
-#endif
       (void)png_colorspace_set_sRGB(png_ptr, colorspace,
          (int)/*already checked*/png_get_uint_32(profile+64));
 }
+#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
 #endif /* sRGB */
 
 int /* PRIVATE */
 png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
-   int color_type)
+    png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
+    int color_type)
 {
    if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
       return 0;
 
    if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
        png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
-          color_type) != 0 &&
+           color_type) != 0 &&
        png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
-          profile) != 0)
+           profile) != 0)
    {
-#     ifdef PNG_sRGB_SUPPORTED
+#     if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
          /* If no sRGB support, don't try storing sRGB information */
          png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
 #     endif
@@ -2478,7 +2517,7 @@
          /* Check for an internal error. */
          if (r+g+b != 32768)
             png_error(png_ptr,
-               "internal error handling cHRM coefficients");
+                "internal error handling cHRM coefficients");
 
          else
          {
@@ -2504,7 +2543,7 @@
 static int /* PRIVATE */
 png_gt(size_t a, size_t b)
 {
-    return a > b;
+   return a > b;
 }
 #else
 #   define png_gt(a,b) ((a) > (b))
@@ -2512,9 +2551,9 @@
 
 void /* PRIVATE */
 png_check_IHDR(png_const_structrp png_ptr,
-   png_uint_32 width, png_uint_32 height, int bit_depth,
-   int color_type, int interlace_type, int compression_type,
-   int filter_type)
+    png_uint_32 width, png_uint_32 height, int bit_depth,
+    int color_type, int interlace_type, int compression_type,
+    int filter_type)
 {
    int error = 0;
 
@@ -2531,7 +2570,7 @@
       error = 1;
    }
 
-   if (png_gt(((width + 7) & (~7)),
+   if (png_gt(((width + 7) & (~7U)),
        ((PNG_SIZE_MAX
            - 48        /* big_row_buf hack */
            - 1)        /* filter byte */
@@ -2677,7 +2716,7 @@
 
 int /* PRIVATE */
 png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
-   png_size_tp whereami)
+    png_size_tp whereami)
 {
    int state = *statep;
    png_size_t i = *whereami;
@@ -2833,7 +2872,7 @@
    if (power < 0)
    {
       if (power < DBL_MIN_10_EXP) return 0;
-      recip = 1, power = -power;
+      recip = 1; power = -power;
    }
 
    if (power > 0)
@@ -2858,6 +2897,14 @@
 /* Function to format a floating point value in ASCII with a given
  * precision.
  */
+#if GCC_STRICT_OVERFLOW
+#pragma GCC diagnostic push
+/* The problem arises below with exp_b10, which can never overflow because it
+ * comes, originally, from frexp and is therefore limited to a range which is
+ * typically +/-710 (log2(DBL_MAX)/log2(DBL_MIN)).
+ */
+#pragma GCC diagnostic warning "-Wstrict-overflow=2"
+#endif /* GCC_STRICT_OVERFLOW */
 void /* PRIVATE */
 png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
     double fp, unsigned int precision)
@@ -2911,7 +2958,9 @@
             double test = png_pow10(exp_b10+1);
 
             if (test <= DBL_MAX)
-               ++exp_b10, base = test;
+            {
+               ++exp_b10; base = test;
+            }
 
             else
                break;
@@ -2925,7 +2974,10 @@
           * test on DBL_MAX above.
           */
          fp /= base;
-         while (fp >= 1) fp /= 10, ++exp_b10;
+         while (fp >= 1)
+         {
+            fp /= 10; ++exp_b10;
+         }
 
          /* Because of the code above fp may, at this point, be
           * less than .1, this is ok because the code below can
@@ -2942,7 +2994,7 @@
              */
             if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
             {
-               czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */
+               czero = 0U-exp_b10; /* PLUS 2 digits: TOTAL 3 */
                exp_b10 = 0;      /* Dot added below before first output. */
             }
             else
@@ -2976,7 +3028,7 @@
                      /* Rounding up to 10, handle that here. */
                      if (czero > 0)
                      {
-                        --czero, d = 1;
+                        --czero; d = 1;
                         if (cdigits == 0) --clead;
                      }
                      else
@@ -2990,7 +3042,7 @@
 
                            else if (ch == 46)
                            {
-                              ch = *--ascii, ++size;
+                              ch = *--ascii; ++size;
                               /* Advance exp_b10 to '1', so that the
                                * decimal point happens after the
                                * previous digit.
@@ -3017,7 +3069,9 @@
                               int ch = *--ascii;
 
                               if (ch == 46)
-                                 ++size, exp_b10 = 1;
+                              {
+                                 ++size; exp_b10 = 1;
+                              }
 
                               /* Else lost a leading zero, so 'exp_b10' is
                                * still ok at (-1)
@@ -3053,21 +3107,26 @@
                       */
                      if (exp_b10 != (-1))
                      {
-                        if (exp_b10 == 0) *ascii++ = 46, --size;
+                        if (exp_b10 == 0)
+                        {
+                           *ascii++ = 46; --size;
+                        }
                         /* PLUS 1: TOTAL 4 */
                         --exp_b10;
                      }
-                     *ascii++ = 48, --czero;
+                     *ascii++ = 48; --czero;
                   }
 
                   if (exp_b10 != (-1))
                   {
                      if (exp_b10 == 0)
-                        *ascii++ = 46, --size; /* counted above */
+                     {
+                        *ascii++ = 46; --size; /* counted above */
+                     }
 
                      --exp_b10;
                   }
-                  *ascii++ = (char)(48 + (int)d), ++cdigits;
+                  *ascii++ = (char)(48 + (int)d); ++cdigits;
                }
             }
             while (cdigits+czero < precision+clead && fp > DBL_MIN);
@@ -3076,7 +3135,7 @@
 
             /* Check for an exponent, if we don't need one we are
              * done and just need to terminate the string.  At
-             * this point exp_b10==(-1) is effectively if flag - it got
+             * this point exp_b10==(-1) is effectively a flag - it got
              * to '-1' because of the decrement after outputting
              * the decimal point above (the exponent required is
              * *not* -1!)
@@ -3090,7 +3149,7 @@
                 * zeros were *not* output, so this doesn't increase
                 * the output count.
                 */
-               while (--exp_b10 >= 0) *ascii++ = 48;
+               while (exp_b10-- > 0) *ascii++ = 48;
 
                *ascii = 0;
 
@@ -3108,7 +3167,7 @@
              */
             size -= cdigits;
 
-            *ascii++ = 69, --size;    /* 'E': PLUS 1 TOTAL 2+precision */
+            *ascii++ = 69; --size;    /* 'E': PLUS 1 TOTAL 2+precision */
 
             /* The following use of an unsigned temporary avoids ambiguities in
              * the signed arithmetic on exp_b10 and permits GCC at least to do
@@ -3119,12 +3178,12 @@
 
                if (exp_b10 < 0)
                {
-                  *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
-                  uexp_b10 = -exp_b10;
+                  *ascii++ = 45; --size; /* '-': PLUS 1 TOTAL 3+precision */
+                  uexp_b10 = 0U-exp_b10;
                }
 
                else
-                  uexp_b10 = exp_b10;
+                  uexp_b10 = 0U+exp_b10;
 
                cdigits = 0;
 
@@ -3167,6 +3226,9 @@
    /* Here on buffer too small. */
    png_error(png_ptr, "ASCII conversion buffer too small");
 }
+#if GCC_STRICT_OVERFLOW
+#pragma GCC diagnostic pop
+#endif /* GCC_STRICT_OVERFLOW */
 
 #  endif /* FLOATING_POINT */
 
@@ -3186,9 +3248,11 @@
 
       /* Avoid overflow here on the minimum integer. */
       if (fp < 0)
-         *ascii++ = 45, num = -fp;
+      {
+         *ascii++ = 45; num = (png_uint_32)(-fp);
+      }
       else
-         num = fp;
+         num = (png_uint_32)fp;
 
       if (num <= 0x80000000) /* else overflowed */
       {
@@ -3224,7 +3288,10 @@
                 * then ndigits digits to first:
                 */
                i = 5;
-               while (ndigits < i) *ascii++ = 48, --i;
+               while (ndigits < i)
+               {
+                  *ascii++ = 48; --i;
+               }
                while (ndigits >= first) *ascii++ = digits[--ndigits];
                /* Don't output the trailing zeros! */
             }
@@ -3275,6 +3342,15 @@
  * the nearest .00001).  Overflow and divide by zero are signalled in
  * the result, a boolean - true on success, false on overflow.
  */
+#if GCC_STRICT_OVERFLOW /* from above */
+/* It is not obvious which comparison below gets optimized in such a way that
+ * signed overflow would change the result; looking through the code does not
+ * reveal any tests which have the form GCC complains about, so presumably the
+ * optimizer is moving an add or subtract into the 'if' somewhere.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic warning "-Wstrict-overflow=2"
+#endif /* GCC_STRICT_OVERFLOW */
 int
 png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
     png_int_32 divisor)
@@ -3389,6 +3465,9 @@
 
    return 0;
 }
+#if GCC_STRICT_OVERFLOW
+#pragma GCC diagnostic pop
+#endif /* GCC_STRICT_OVERFLOW */
 #endif /* READ_GAMMA || INCH_CONVERSIONS */
 
 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
@@ -3682,7 +3761,7 @@
  * of getting this accuracy in practice.
  *
  * To deal with this the following exp() function works out the exponent of the
- * frational part of the logarithm by using an accurate 32-bit value from the
+ * fractional part of the logarithm by using an accurate 32-bit value from the
  * top four fractional bits then multiplying in the remaining bits.
  */
 static const png_uint_32
@@ -3840,25 +3919,25 @@
 {
    if (value > 0 && value < 65535)
    {
-#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-         /* The same (unsigned int)->(double) constraints apply here as above,
-          * however in this case the (unsigned int) to (int) conversion can
-          * overflow on an ANSI-C90 compliant system so the cast needs to ensure
-          * that this is not possible.
-          */
-         double r = floor(65535*pow((png_int_32)value/65535.,
-                     gamma_val*.00001)+.5);
-         return (png_uint_16)r;
-#     else
-         png_int_32 lg2 = png_log16bit(value);
-         png_fixed_point res;
+# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+      /* The same (unsigned int)->(double) constraints apply here as above,
+       * however in this case the (unsigned int) to (int) conversion can
+       * overflow on an ANSI-C90 compliant system so the cast needs to ensure
+       * that this is not possible.
+       */
+      double r = floor(65535*pow((png_int_32)value/65535.,
+          gamma_val*.00001)+.5);
+      return (png_uint_16)r;
+# else
+      png_int_32 lg2 = png_log16bit(value);
+      png_fixed_point res;
 
-         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
-            return png_exp16bit(res);
+      if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
+         return png_exp16bit(res);
 
-         /* Overflow. */
-         value = 0;
-#     endif
+      /* Overflow. */
+      value = 0;
+# endif
    }
 
    return (png_uint_16)value;
@@ -3897,7 +3976,7 @@
  */
 static void
 png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
-   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+    PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
 {
    /* Various values derived from 'shift': */
    PNG_CONST unsigned int num = 1U << (8U - shift);
@@ -3974,7 +4053,7 @@
  */
 static void
 png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
-   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+    PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
 {
    PNG_CONST unsigned int num = 1U << (8U - shift);
    PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
@@ -4042,7 +4121,7 @@
  */
 static void
 png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
-   PNG_CONST png_fixed_point gamma_val)
+    PNG_CONST png_fixed_point gamma_val)
 {
    unsigned int i;
    png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);
@@ -4122,131 +4201,133 @@
 void /* PRIVATE */
 png_build_gamma_table(png_structrp png_ptr, int bit_depth)
 {
-  png_debug(1, "in png_build_gamma_table");
+   png_debug(1, "in png_build_gamma_table");
 
-  /* Remove any existing table; this copes with multiple calls to
-   * png_read_update_info.  The warning is because building the gamma tables
-   * multiple times is a performance hit - it's harmless but the ability to call
-   * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible
-   * to warn if the app introduces such a hit.
-   */
-  if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
-  {
-    png_warning(png_ptr, "gamma table being rebuilt");
-    png_destroy_gamma_table(png_ptr);
-  }
+   /* Remove any existing table; this copes with multiple calls to
+    * png_read_update_info. The warning is because building the gamma tables
+    * multiple times is a performance hit - it's harmless but the ability to
+    * call png_read_update_info() multiple times is new in 1.5.6 so it seems
+    * sensible to warn if the app introduces such a hit.
+    */
+   if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
+   {
+      png_warning(png_ptr, "gamma table being rebuilt");
+      png_destroy_gamma_table(png_ptr);
+   }
 
-  if (bit_depth <= 8)
-  {
-     png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
-         png_ptr->screen_gamma > 0 ?  png_reciprocal2(png_ptr->colorspace.gamma,
-         png_ptr->screen_gamma) : PNG_FP_1);
+   if (bit_depth <= 8)
+   {
+      png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
+          png_ptr->screen_gamma > 0 ?
+          png_reciprocal2(png_ptr->colorspace.gamma,
+          png_ptr->screen_gamma) : PNG_FP_1);
 
 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-     if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
-     {
-        png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
-            png_reciprocal(png_ptr->colorspace.gamma));
+      if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
+      {
+         png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
+             png_reciprocal(png_ptr->colorspace.gamma));
 
-        png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
-            png_ptr->screen_gamma > 0 ?  png_reciprocal(png_ptr->screen_gamma) :
-            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
-     }
+         png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
+             png_ptr->screen_gamma > 0 ?
+             png_reciprocal(png_ptr->screen_gamma) :
+             png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+      }
 #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
-  }
+   }
 #ifdef PNG_16BIT_SUPPORTED
-  else
-  {
-     png_byte shift, sig_bit;
+   else
+   {
+      png_byte shift, sig_bit;
 
-     if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
-     {
-        sig_bit = png_ptr->sig_bit.red;
+      if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+      {
+         sig_bit = png_ptr->sig_bit.red;
 
-        if (png_ptr->sig_bit.green > sig_bit)
-           sig_bit = png_ptr->sig_bit.green;
+         if (png_ptr->sig_bit.green > sig_bit)
+            sig_bit = png_ptr->sig_bit.green;
 
-        if (png_ptr->sig_bit.blue > sig_bit)
-           sig_bit = png_ptr->sig_bit.blue;
-     }
-     else
-        sig_bit = png_ptr->sig_bit.gray;
+         if (png_ptr->sig_bit.blue > sig_bit)
+            sig_bit = png_ptr->sig_bit.blue;
+      }
+      else
+         sig_bit = png_ptr->sig_bit.gray;
 
-     /* 16-bit gamma code uses this equation:
-      *
-      *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
-      *
-      * Where 'iv' is the input color value and 'ov' is the output value -
-      * pow(iv, gamma).
-      *
-      * Thus the gamma table consists of up to 256 256-entry tables.  The table
-      * is selected by the (8-gamma_shift) most significant of the low 8 bits of
-      * the color value then indexed by the upper 8 bits:
-      *
-      *   table[low bits][high 8 bits]
-      *
-      * So the table 'n' corresponds to all those 'iv' of:
-      *
-      *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
-      *
-      */
-     if (sig_bit > 0 && sig_bit < 16U)
-        /* shift == insignificant bits */
-        shift = (png_byte)((16U - sig_bit) & 0xff);
+      /* 16-bit gamma code uses this equation:
+       *
+       *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
+       *
+       * Where 'iv' is the input color value and 'ov' is the output value -
+       * pow(iv, gamma).
+       *
+       * Thus the gamma table consists of up to 256 256-entry tables.  The table
+       * is selected by the (8-gamma_shift) most significant of the low 8 bits
+       * of the color value then indexed by the upper 8 bits:
+       *
+       *   table[low bits][high 8 bits]
+       *
+       * So the table 'n' corresponds to all those 'iv' of:
+       *
+       *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
+       *
+       */
+      if (sig_bit > 0 && sig_bit < 16U)
+         /* shift == insignificant bits */
+         shift = (png_byte)((16U - sig_bit) & 0xff);
 
-     else
-        shift = 0; /* keep all 16 bits */
+      else
+         shift = 0; /* keep all 16 bits */
 
-     if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
-     {
-        /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
-         * the significant bits in the *input* when the output will
-         * eventually be 8 bits.  By default it is 11.
-         */
-        if (shift < (16U - PNG_MAX_GAMMA_8))
-           shift = (16U - PNG_MAX_GAMMA_8);
-     }
+      if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
+      {
+         /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
+          * the significant bits in the *input* when the output will
+          * eventually be 8 bits.  By default it is 11.
+          */
+         if (shift < (16U - PNG_MAX_GAMMA_8))
+            shift = (16U - PNG_MAX_GAMMA_8);
+      }
 
-     if (shift > 8U)
-        shift = 8U; /* Guarantees at least one table! */
+      if (shift > 8U)
+         shift = 8U; /* Guarantees at least one table! */
 
-     png_ptr->gamma_shift = shift;
+      png_ptr->gamma_shift = shift;
 
-     /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
-      * PNG_COMPOSE).  This effectively smashed the background calculation for
-      * 16-bit output because the 8-bit table assumes the result will be reduced
-      * to 8 bits.
-      */
-     if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
-         png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
-         png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
-         png_ptr->screen_gamma) : PNG_FP_1);
+      /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
+       * PNG_COMPOSE).  This effectively smashed the background calculation for
+       * 16-bit output because the 8-bit table assumes the result will be
+       * reduced to 8 bits.
+       */
+      if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
+          png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
+          png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
+          png_ptr->screen_gamma) : PNG_FP_1);
 
-     else
-         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
-         png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
-         png_ptr->screen_gamma) : PNG_FP_1);
+      else
+          png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
+          png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
+          png_ptr->screen_gamma) : PNG_FP_1);
 
 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-     if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
-     {
-        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
-            png_reciprocal(png_ptr->colorspace.gamma));
+      if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
+      {
+         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
+             png_reciprocal(png_ptr->colorspace.gamma));
 
-        /* Notice that the '16 from 1' table should be full precision, however
-         * the lookup on this table still uses gamma_shift, so it can't be.
-         * TODO: fix this.
-         */
-        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
-            png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
-            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
-     }
+         /* Notice that the '16 from 1' table should be full precision, however
+          * the lookup on this table still uses gamma_shift, so it can't be.
+          * TODO: fix this.
+          */
+         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
+             png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
+             png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+      }
 #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
-  }
+   }
 #endif /* 16BIT */
 }
 #endif /* READ_GAMMA */
@@ -4259,13 +4340,13 @@
    if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&
       (option & 1) == 0)
    {
-      int mask = 3 << option;
-      int setting = (2 + (onoff != 0)) << option;
-      int current = png_ptr->options;
+      png_uint_32 mask = 3U << option;
+      png_uint_32 setting = (2U + (onoff != 0)) << option;
+      png_uint_32 current = png_ptr->options;
 
-      png_ptr->options = (png_byte)(((current & ~mask) | setting) & 0xff);
+      png_ptr->options = (png_uint_32)(((current & ~mask) | setting) & 0xff);
 
-      return (current & mask) >> option;
+      return (int)(current & mask) >> option;
    }
 
    return PNG_OPTION_INVALID;
@@ -4277,7 +4358,7 @@
    defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
 /* sRGB conversion tables; these are machine generated with the code in
  * contrib/tools/makesRGB.c.  The actual sRGB transfer curve defined in the
- * specification (see the article at http://en.wikipedia.org/wiki/SRGB)
+ * specification (see the article at https://en.wikipedia.org/wiki/SRGB)
  * is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
  * The sRGB to linear table is exact (to the nearest 16-bit linear fraction).
  * The inverse (linear to sRGB) table has accuracies as follows:
diff --git a/third_party/libpng/png.h b/third_party/libpng/png.h
index 08c039d..4c873f5 100644
--- a/third_party/libpng/png.h
+++ b/third_party/libpng/png.h
@@ -1,9 +1,9 @@
 
 /* png.h - header file for PNG reference library
  *
- * libpng version 1.6.22, May 26, 2016
+ * libpng version 1.6.34, September 29, 2017
  *
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -12,7 +12,7 @@
  * Authors and maintainers:
  *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
  *   libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
- *   libpng versions 0.97, January 1998, through 1.6.22, May 26, 2016:
+ *   libpng versions 0.97, January 1998, through 1.6.34, September 29, 2017:
  *     Glenn Randers-Pehrson.
  *   See also "Contributing Authors", below.
  */
@@ -25,12 +25,8 @@
  *
  * This code is released under the libpng license.
  *
- * Some files in the "contrib" directory and some configure-generated
- * files that are distributed with libpng have other copyright owners and
- * are released under other open source licenses.
- *
- * libpng versions 1.0.7, July 1, 2000 through 1.6.22, May 26, 2016 are
- * Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are
+ * libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are
+ * Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
  * derived from libpng-1.0.6, and are distributed according to the same
  * disclaimer and license as libpng-1.0.6 with the following individuals
  * added to the list of Contributing Authors:
@@ -41,6 +37,9 @@
  *    Cosmin Truta
  *    Gilles Vollant
  *    James Yu
+ *    Mandar Sahastrabuddhe
+ *    Google Inc.
+ *    Vadim Barkov
  *
  * and with the following additions to the disclaimer:
  *
@@ -51,10 +50,10 @@
  *    risk of satisfactory quality, performance, accuracy, and effort is with
  *    the user.
  *
- * Some files in the "contrib" directory have other copyright owners and
+ * Some files in the "contrib" directory and some configure-generated
+ * files that are distributed with libpng have other copyright owners and
  * are released under other open source licenses.
  *
- *
  * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
  * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
  * libpng-0.96, and are distributed according to the same disclaimer and
@@ -65,9 +64,6 @@
  *    Glenn Randers-Pehrson
  *    Willem van Schaik
  *
- * Some files in the "scripts" directory have different copyright owners
- * but are also released under this license.
- *
  * libpng versions 0.89, June 1996, through 0.96, May 1997, are
  * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
  * and are distributed according to the same disclaimer and license as
@@ -213,11 +209,11 @@
  *    ...
  *    1.0.19                  10    10019  10.so.0.19[.0]
  *    ...
- *    1.2.56                  13    10256  12.so.0.56[.0]
+ *    1.2.59                  13    10257  12.so.0.59[.0]
  *    ...
- *    1.5.27                  15    10527  15.so.15.27[.0]
+ *    1.5.30                  15    10527  15.so.15.30[.0]
  *    ...
- *    1.6.22                  16    10622  16.so.16.22[.0]
+ *    1.6.34                  16    10633  16.so.16.34[.0]
  *
  *    Henceforth the source version will match the shared-library major
  *    and minor numbers; the shared-library major version number will be
@@ -238,20 +234,20 @@
  *
  * See libpng.txt or libpng.3 for more information.  The PNG specification
  * is available as a W3C Recommendation and as an ISO Specification,
- * <http://www.w3.org/TR/2003/REC-PNG-20031110/
+ * <https://www.w3.org/TR/2003/REC-PNG-20031110/
  */
 
 /*
  * Y2K compliance in libpng:
  * =========================
  *
- *    May 26, 2016
+ *    September 29, 2017
  *
  *    Since the PNG Development group is an ad-hoc body, we can't make
  *    an official declaration.
  *
  *    This is your unofficial assurance that libpng from version 0.71 and
- *    upward through 1.6.22 are Y2K compliant.  It is my belief that
+ *    upward through 1.6.34 are Y2K compliant.  It is my belief that
  *    earlier versions were also Y2K compliant.
  *
  *    Libpng only has two year fields.  One is a 2-byte unsigned integer
@@ -313,9 +309,8 @@
  */
 
 /* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.22"
-#define PNG_HEADER_VERSION_STRING \
-     " libpng version 1.6.22 - May 26, 2016\n"
+#define PNG_LIBPNG_VER_STRING "1.6.34"
+#define PNG_HEADER_VERSION_STRING " libpng version 1.6.34 - September 29, 2017\n"
 
 #define PNG_LIBPNG_VER_SONUM   16
 #define PNG_LIBPNG_VER_DLLNUM  16
@@ -323,7 +318,7 @@
 /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
 #define PNG_LIBPNG_VER_MAJOR   1
 #define PNG_LIBPNG_VER_MINOR   6
-#define PNG_LIBPNG_VER_RELEASE 22
+#define PNG_LIBPNG_VER_RELEASE 34
 
 /* This should match the numeric part of the final component of
  * PNG_LIBPNG_VER_STRING, omitting any leading zero:
@@ -354,20 +349,20 @@
  * version 1.0.0 was mis-numbered 100 instead of 10000).  From
  * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=release
  */
-#define PNG_LIBPNG_VER 10622 /* 1.6.22 */
+#define PNG_LIBPNG_VER 10634 /* 1.6.34 */
 
 /* Library configuration: these options cannot be changed after
  * the library has been built.
  */
 #ifndef PNGLCONF_H
-    /* If pnglibconf.h is missing, you can
-     * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
-     */
+/* If pnglibconf.h is missing, you can
+ * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
+ */
 #   include "pnglibconf.h"
 #endif
 
 #ifndef PNG_VERSION_INFO_ONLY
-   /* Machine specific configuration. */
+/* Machine specific configuration. */
 #  include "pngconf.h"
 #endif
 
@@ -464,7 +459,7 @@
 /* This triggers a compiler error in png.c, if png.c and png.h
  * do not agree upon the version number.
  */
-typedef char* png_libpng_version_1_6_22;
+typedef char* png_libpng_version_1_6_34;
 
 /* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
  *
@@ -657,17 +652,17 @@
  */
 typedef struct png_unknown_chunk_t
 {
-    png_byte name[5]; /* Textual chunk name with '\0' terminator */
-    png_byte *data;   /* Data, should not be modified on read! */
-    png_size_t size;
+   png_byte name[5]; /* Textual chunk name with '\0' terminator */
+   png_byte *data;   /* Data, should not be modified on read! */
+   png_size_t size;
 
-    /* On write 'location' must be set using the flag values listed below.
-     * Notice that on read it is set by libpng however the values stored have
-     * more bits set than are listed below.  Always treat the value as a
-     * bitmask.  On write set only one bit - setting multiple bits may cause the
-     * chunk to be written in multiple places.
-     */
-    png_byte location; /* mode of operation at read time */
+   /* On write 'location' must be set using the flag values listed below.
+    * Notice that on read it is set by libpng however the values stored have
+    * more bits set than are listed below.  Always treat the value as a
+    * bitmask.  On write set only one bit - setting multiple bits may cause the
+    * chunk to be written in multiple places.
+    */
+   png_byte location; /* mode of operation at read time */
 }
 png_unknown_chunk;
 
@@ -781,6 +776,7 @@
 #define PNG_INFO_sPLT 0x2000U  /* ESR, 1.0.6 */
 #define PNG_INFO_sCAL 0x4000U  /* ESR, 1.0.6 */
 #define PNG_INFO_IDAT 0x8000U  /* ESR, 1.0.6 */
+#define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */
 
 /* This is used for the transformation routines, as some of them
  * change these values for the row.  It also should enable using
@@ -1793,7 +1789,8 @@
 #define PNG_FREE_PLTE 0x1000U
 #define PNG_FREE_TRNS 0x2000U
 #define PNG_FREE_TEXT 0x4000U
-#define PNG_FREE_ALL  0x7fffU
+#define PNG_FREE_EXIF 0x8000U /* Added at libpng-1.6.31 */
+#define PNG_FREE_ALL  0xffffU
 #define PNG_FREE_MUL  0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
 
 #ifdef PNG_USER_MEM_SUPPORTED
@@ -2012,6 +2009,18 @@
     png_fixed_point int_blue_Z))
 #endif
 
+#ifdef PNG_eXIf_SUPPORTED
+PNG_EXPORT(246, png_uint_32, png_get_eXIf, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_bytep *exif));
+PNG_EXPORT(247, void, png_set_eXIf, (png_const_structrp png_ptr,
+    png_inforp info_ptr, const png_bytep exif));
+
+PNG_EXPORT(248, png_uint_32, png_get_eXIf_1, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr, png_uint_32 *num_exif, png_bytep *exif));
+PNG_EXPORT(249, void, png_set_eXIf_1, (png_const_structrp png_ptr,
+    png_inforp info_ptr, const png_uint_32 num_exif, const png_bytep exif));
+#endif
+
 #ifdef PNG_gAMA_SUPPORTED
 PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr,
     png_const_inforp info_ptr, double *file_gamma))
@@ -2030,9 +2039,6 @@
 #ifdef PNG_hIST_SUPPORTED
 PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr,
     png_inforp info_ptr, png_uint_16p *hist));
-#endif
-
-#ifdef PNG_hIST_SUPPORTED
 PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr,
     png_inforp info_ptr, png_const_uint_16p hist));
 #endif
@@ -2300,8 +2306,10 @@
  *    except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to
  *    be processed by libpng.
  */
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
     int keep, png_const_bytep chunk_list, int num_chunks));
+#endif /* HANDLE_AS_UNKNOWN */
 
 /* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned;
  * the result is therefore true (non-zero) if special handling is required,
@@ -2309,7 +2317,7 @@
  */
 PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr,
     png_const_bytep chunk_name));
-#endif
+#endif /* SET_UNKNOWN_CHUNKS */
 
 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
 PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr,
@@ -2530,33 +2538,37 @@
 
  /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
 
-#  define png_composite(composite, fg, alpha, bg)         \
-     { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
-           * (png_uint_16)(alpha)                         \
-           + (png_uint_16)(bg)*(png_uint_16)(255          \
-           - (png_uint_16)(alpha)) + 128);                \
-       (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); }
+#  define png_composite(composite, fg, alpha, bg)        \
+   {                                                     \
+      png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
+          * (png_uint_16)(alpha)                         \
+          + (png_uint_16)(bg)*(png_uint_16)(255          \
+          - (png_uint_16)(alpha)) + 128);                \
+      (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); \
+   }
 
-#  define png_composite_16(composite, fg, alpha, bg)       \
-     { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg)  \
-           * (png_uint_32)(alpha)                          \
-           + (png_uint_32)(bg)*(65535                      \
-           - (png_uint_32)(alpha)) + 32768);               \
-       (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); }
+#  define png_composite_16(composite, fg, alpha, bg)     \
+   {                                                     \
+      png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \
+          * (png_uint_32)(alpha)                         \
+          + (png_uint_32)(bg)*(65535                     \
+          - (png_uint_32)(alpha)) + 32768);              \
+      (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); \
+   }
 
 #else  /* Standard method using integer division */
 
-#  define png_composite(composite, fg, alpha, bg)                        \
-     (composite) =                                                       \
-         (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) +  \
-         (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
-         127) / 255))
+#  define png_composite(composite, fg, alpha, bg)                      \
+   (composite) =                                                       \
+       (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) +  \
+       (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
+       127) / 255))
 
-#  define png_composite_16(composite, fg, alpha, bg)                         \
-     (composite) =                                                           \
-         (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
-         (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) +     \
-         32767) / 65535))
+#  define png_composite_16(composite, fg, alpha, bg)                       \
+   (composite) =                                                           \
+       (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+       (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) +     \
+       32767) / 65535))
 #endif /* READ_COMPOSITE_NODIV */
 
 #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
@@ -2592,38 +2604,38 @@
  * format for negative values, which is almost certainly true.
  */
 #  define PNG_get_uint_32(buf) \
-     (((png_uint_32)(*(buf)) << 24) + \
-      ((png_uint_32)(*((buf) + 1)) << 16) + \
-      ((png_uint_32)(*((buf) + 2)) << 8) + \
-      ((png_uint_32)(*((buf) + 3))))
+   (((png_uint_32)(*(buf)) << 24) + \
+    ((png_uint_32)(*((buf) + 1)) << 16) + \
+    ((png_uint_32)(*((buf) + 2)) << 8) + \
+    ((png_uint_32)(*((buf) + 3))))
 
    /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
     * function) incorrectly returned a value of type png_uint_32.
     */
 #  define PNG_get_uint_16(buf) \
-     ((png_uint_16) \
-      (((unsigned int)(*(buf)) << 8) + \
-       ((unsigned int)(*((buf) + 1)))))
+   ((png_uint_16) \
+    (((unsigned int)(*(buf)) << 8) + \
+    ((unsigned int)(*((buf) + 1)))))
 
 #  define PNG_get_int_32(buf) \
-     ((png_int_32)((*(buf) & 0x80) \
-      ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \
-      : (png_int_32)png_get_uint_32(buf)))
+   ((png_int_32)((*(buf) & 0x80) \
+    ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \
+    : (png_int_32)png_get_uint_32(buf)))
 
-   /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
-    * but defining a macro name prefixed with PNG_PREFIX.
-    */
+/* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
+ * but defining a macro name prefixed with PNG_PREFIX.
+ */
 #  ifndef PNG_PREFIX
-#     define png_get_uint_32(buf) PNG_get_uint_32(buf)
-#     define png_get_uint_16(buf) PNG_get_uint_16(buf)
-#     define png_get_int_32(buf)  PNG_get_int_32(buf)
+#    define png_get_uint_32(buf) PNG_get_uint_32(buf)
+#    define png_get_uint_16(buf) PNG_get_uint_16(buf)
+#    define png_get_int_32(buf)  PNG_get_int_32(buf)
 #  endif
 #else
 #  ifdef PNG_PREFIX
-      /* No macros; revert to the (redefined) function */
-#     define PNG_get_uint_32 (png_get_uint_32)
-#     define PNG_get_uint_16 (png_get_uint_16)
-#     define PNG_get_int_32  (png_get_int_32)
+   /* No macros; revert to the (redefined) function */
+#    define PNG_get_uint_32 (png_get_uint_32)
+#    define PNG_get_uint_16 (png_get_uint_16)
+#    define PNG_get_int_32  (png_get_int_32)
 #  endif
 #endif
 
@@ -2752,7 +2764,7 @@
  *
  * When the simplified API needs to convert between sRGB and linear colorspaces,
  * the actual sRGB transfer curve defined in the sRGB specification (see the
- * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
+ * article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
  * approximation used elsewhere in libpng.
  *
  * When an alpha channel is present it is expected to denote pixel coverage
@@ -2807,6 +2819,8 @@
 #  define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */
 #endif
 
+#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */
+
 /* Commonly used formats have predefined macros.
  *
  * First the single byte (sRGB) formats:
@@ -3171,9 +3185,9 @@
 #define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\
    ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\
     (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\
-     12U+3U*(image).colormap_entries/*PLTE data*/+\
-     (((image).format&PNG_FORMAT_FLAG_ALPHA)?\
-      12U/*tRNS*/+(image).colormap_entries:0U):0U)+\
+    12U+3U*(image).colormap_entries/*PLTE data*/+\
+    (((image).format&PNG_FORMAT_FLAG_ALPHA)?\
+    12U/*tRNS*/+(image).colormap_entries:0U):0U)+\
     12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size))
    /* A helper for the following macro; if your compiler cannot handle the
     * following macro use this one with the result of
@@ -3221,7 +3235,14 @@
 #endif
 #define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */
 #define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */
-#define PNG_OPTION_NEXT  6 /* Next option - numbers must be even */
+#ifdef PNG_MIPS_MSA_API_SUPPORTED
+#  define PNG_MIPS_MSA   6 /* HARDWARE: MIPS Msa SIMD instructions supported */
+#endif
+#define PNG_IGNORE_ADLER32 8
+#ifdef PNG_POWERPC_VSX_API_SUPPORTED
+#  define PNG_POWERPC_VSX   10 /* HARDWARE: PowerPC VSX SIMD instructions supported */
+#endif
+#define PNG_OPTION_NEXT  12 /* Next option - numbers must be even */
 
 /* Return values: NOTE: there are four values and 'off' is *not* zero */
 #define PNG_OPTION_UNSET   0 /* Unset - defaults to off */
@@ -3245,7 +3266,7 @@
  * one to use is one more than this.)
  */
 #ifdef PNG_EXPORT_LAST_ORDINAL
-  PNG_EXPORT_LAST_ORDINAL(245);
+  PNG_EXPORT_LAST_ORDINAL(249);
 #endif
 
 #ifdef __cplusplus
diff --git a/third_party/libpng/pngconf.h b/third_party/libpng/pngconf.h
index 0cabe4b..d13b13e 100644
--- a/third_party/libpng/pngconf.h
+++ b/third_party/libpng/pngconf.h
@@ -1,9 +1,9 @@
 
 /* pngconf.h - machine configurable file for libpng
  *
- * libpng version 1.6.22, May 26, 2016
+ * libpng version 1.6.34, September 29, 2017
  *
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -188,27 +188,27 @@
    * compatible with GCC or Visual C because of different calling conventions.
    */
 #  if PNG_API_RULE == 2
-    /* If this line results in an error, either because __watcall is not
-     * understood or because of a redefine just below you cannot use *this*
-     * build of the library with the compiler you are using.  *This* build was
-     * build using Watcom and applications must also be built using Watcom!
-     */
+   /* If this line results in an error, either because __watcall is not
+    * understood or because of a redefine just below you cannot use *this*
+    * build of the library with the compiler you are using.  *This* build was
+    * build using Watcom and applications must also be built using Watcom!
+    */
 #    define PNGCAPI __watcall
 #  endif
 
 #  if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
 #    define PNGCAPI __cdecl
 #    if PNG_API_RULE == 1
-       /* If this line results in an error __stdcall is not understood and
-        * PNG_API_RULE should not have been set to '1'.
-        */
+   /* If this line results in an error __stdcall is not understood and
+    * PNG_API_RULE should not have been set to '1'.
+    */
 #      define PNGAPI __stdcall
 #    endif
 #  else
-    /* An older compiler, or one not detected (erroneously) above,
-     * if necessary override on the command line to get the correct
-     * variants for the compiler.
-     */
+   /* An older compiler, or one not detected (erroneously) above,
+    * if necessary override on the command line to get the correct
+    * variants for the compiler.
+    */
 #    ifndef PNGCAPI
 #      define PNGCAPI _cdecl
 #    endif
@@ -225,10 +225,10 @@
 
 #  if (defined(_MSC_VER) && _MSC_VER < 800) ||\
       (defined(__BORLANDC__) && __BORLANDC__ < 0x500)
-    /* older Borland and MSC
-     * compilers used '__export' and required this to be after
-     * the type.
-     */
+   /* older Borland and MSC
+    * compilers used '__export' and required this to be after
+    * the type.
+    */
 #    ifndef PNG_EXPORT_TYPE
 #      define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
 #    endif
@@ -244,9 +244,9 @@
 #  if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
 #    define PNGAPI _System
 #  else /* !Windows/x86 && !OS/2 */
-    /* Use the defaults, or define PNG*API on the command line (but
-     * this will have to be done for every compile!)
-     */
+   /* Use the defaults, or define PNG*API on the command line (but
+    * this will have to be done for every compile!)
+    */
 #  endif /* other system, !OS/2 */
 #endif /* !Windows/x86 */
 
@@ -267,7 +267,7 @@
  */
 #ifndef PNG_IMPEXP
 #  if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
-     /* This forces use of a DLL, disallowing static linking */
+   /* This forces use of a DLL, disallowing static linking */
 #    define PNG_IMPEXP PNG_DLL_IMPORT
 #  endif
 
@@ -340,7 +340,7 @@
    * less efficient code.
    */
 #  if defined(__clang__) && defined(__has_attribute)
-     /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
+   /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
 #    if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
 #      define PNG_USE_RESULT __attribute__((__warn_unused_result__))
 #    endif
@@ -507,9 +507,9 @@
 #  error "libpng requires a signed 32-bit (or more) type"
 #endif
 
-#if UINT_MAX > 4294967294
+#if UINT_MAX > 4294967294U
    typedef unsigned int png_uint_32;
-#elif ULONG_MAX > 4294967294
+#elif ULONG_MAX > 4294967294U
    typedef unsigned long int png_uint_32;
 #else
 #  error "libpng requires an unsigned 32-bit (or more) type"
diff --git a/third_party/libpng/pngerror.c b/third_party/libpng/pngerror.c
index 3fc8092..ad48bfb 100644
--- a/third_party/libpng/pngerror.c
+++ b/third_party/libpng/pngerror.c
@@ -1,8 +1,8 @@
 
 /* pngerror.c - stub functions for i/o and memory allocation
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.31 [July 27, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -26,7 +26,7 @@
 #ifdef PNG_WARNINGS_SUPPORTED
 static void /* PRIVATE */
 png_default_warning PNGARG((png_const_structrp png_ptr,
-   png_const_charp warning_message));
+    png_const_charp warning_message));
 #endif /* WARNINGS */
 
 /* This function is called whenever there is a fatal error.  This function
@@ -37,7 +37,7 @@
 #ifdef PNG_ERROR_TEXT_SUPPORTED
 PNG_FUNCTION(void,PNGAPI
 png_error,(png_const_structrp png_ptr, png_const_charp error_message),
-   PNG_NORETURN)
+    PNG_NORETURN)
 {
 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
    char msg[16];
@@ -65,18 +65,18 @@
 
             else
                error_message += offset;
-      }
-
-      else
-      {
-         if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
-         {
-            msg[0] = '0';
-            msg[1] = '\0';
-            error_message = msg;
          }
-       }
-     }
+
+         else
+         {
+            if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
+            {
+               msg[0] = '0';
+               msg[1] = '\0';
+               error_message = msg;
+            }
+         }
+      }
    }
 #endif
    if (png_ptr != NULL && png_ptr->error_fn != NULL)
@@ -110,7 +110,7 @@
  */
 size_t
 png_safecat(png_charp buffer, size_t bufsize, size_t pos,
-   png_const_charp string)
+    png_const_charp string)
 {
    if (buffer != NULL && pos < bufsize)
    {
@@ -131,7 +131,7 @@
  */
 png_charp
 png_format_number(png_const_charp start, png_charp end, int format,
-   png_alloc_size_t number)
+    png_alloc_size_t number)
 {
    int count = 0;    /* number of digits output */
    int mincount = 1; /* minimum number required */
@@ -163,7 +163,7 @@
          case PNG_NUMBER_FORMAT_02u:
             /* Expects at least 2 digits. */
             mincount = 2;
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
 
          case PNG_NUMBER_FORMAT_u:
             *--end = digits[number % 10];
@@ -173,7 +173,7 @@
          case PNG_NUMBER_FORMAT_02x:
             /* This format expects at least two digits */
             mincount = 2;
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
 
          case PNG_NUMBER_FORMAT_x:
             *--end = digits[number & 0xf];
@@ -233,7 +233,7 @@
    }
    if (png_ptr != NULL && png_ptr->warning_fn != NULL)
       (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
-         warning_message + offset);
+          warning_message + offset);
    else
       png_default_warning(png_ptr, warning_message + offset);
 }
@@ -245,7 +245,7 @@
  */
 void
 png_warning_parameter(png_warning_parameters p, int number,
-   png_const_charp string)
+    png_const_charp string)
 {
    if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
       (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
@@ -253,7 +253,7 @@
 
 void
 png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
-   png_alloc_size_t value)
+    png_alloc_size_t value)
 {
    char buffer[PNG_NUMBER_BUFFER_SIZE];
    png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
@@ -261,7 +261,7 @@
 
 void
 png_warning_parameter_signed(png_warning_parameters p, int number, int format,
-   png_int_32 value)
+    png_int_32 value)
 {
    png_alloc_size_t u;
    png_charp str;
@@ -282,7 +282,7 @@
 
 void
 png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
-   png_const_charp message)
+    png_const_charp message)
 {
    /* The internal buffer is just 192 bytes - enough for all our messages,
     * overflow doesn't happen because this code checks!  If someone figures
@@ -391,10 +391,10 @@
 void /* PRIVATE */
 png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
 {
-  if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
-     png_warning(png_ptr, error_message);
-  else
-     png_error(png_ptr, error_message);
+   if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
+      png_warning(png_ptr, error_message);
+   else
+      png_error(png_ptr, error_message);
 
 #  ifndef PNG_ERROR_TEXT_SUPPORTED
       PNG_UNUSED(error_message)
@@ -404,10 +404,10 @@
 void /* PRIVATE */
 png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
 {
-  if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
-     png_warning(png_ptr, error_message);
-  else
-     png_error(png_ptr, error_message);
+   if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
+      png_warning(png_ptr, error_message);
+   else
+      png_error(png_ptr, error_message);
 
 #  ifndef PNG_ERROR_TEXT_SUPPORTED
       PNG_UNUSED(error_message)
@@ -478,7 +478,7 @@
 #if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
 PNG_FUNCTION(void,PNGAPI
 png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
-   PNG_NORETURN)
+    PNG_NORETURN)
 {
    char msg[18+PNG_MAX_ERROR_TEXT];
    if (png_ptr == NULL)
@@ -573,7 +573,7 @@
 {
 #  define fixed_message "fixed point overflow in "
 #  define fixed_message_ln ((sizeof fixed_message)-1)
-   int  iin;
+   unsigned int  iin;
    char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
    memcpy(msg, fixed_message, fixed_message_ln);
    iin = 0;
@@ -620,7 +620,7 @@
       else
       {
          png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
-            png_malloc_warn(png_ptr, jmp_buf_size));
+             png_malloc_warn(png_ptr, jmp_buf_size));
 
          if (png_ptr->jmp_buf_ptr == NULL)
             return NULL; /* new NULL return on OOM */
@@ -709,7 +709,7 @@
  */
 static PNG_FUNCTION(void /* PRIVATE */,
 png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
-   PNG_NORETURN)
+    PNG_NORETURN)
 {
 #ifdef PNG_CONSOLE_IO_SUPPORTED
 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
@@ -883,7 +883,7 @@
     */
 PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
 png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
-   PNG_NORETURN)
+    PNG_NORETURN)
 {
    const png_const_structrp png_ptr = png_nonconst_ptr;
    png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
@@ -906,7 +906,7 @@
       /* Missing longjmp buffer, the following is to help debugging: */
       {
          size_t pos = png_safecat(image->message, (sizeof image->message), 0,
-            "bad longjmp: ");
+             "bad longjmp: ");
          png_safecat(image->message, (sizeof image->message), pos,
              error_message);
       }
diff --git a/third_party/libpng/pngget.c b/third_party/libpng/pngget.c
index 14fc7be..26e9fb1 100644
--- a/third_party/libpng/pngget.c
+++ b/third_party/libpng/pngget.c
@@ -1,8 +1,8 @@
 
 /* pngget.c - retrieval of values from info struct
  *
- * Last changed in libpng 1.6.17 [March 26, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -338,7 +338,7 @@
    png_fixed_point result;
    if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
        5000) != 0)
-      return result;
+      return (png_uint_32)result;
 
    /* Overflow. */
    return 0;
@@ -486,7 +486,7 @@
 #ifdef PNG_bKGD_SUPPORTED
 png_uint_32 PNGAPI
 png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
-   png_color_16p *background)
+    png_color_16p *background)
 {
    if (png_ptr != NULL && info_ptr != NULL &&
        (info_ptr->valid & PNG_INFO_bKGD) != 0 &&
@@ -526,28 +526,28 @@
 
       if (white_x != NULL)
          *white_x = png_float(png_ptr,
-            info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
+             info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
       if (white_y != NULL)
          *white_y = png_float(png_ptr,
-            info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
+             info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
       if (red_x != NULL)
          *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
-            "cHRM red X");
+             "cHRM red X");
       if (red_y != NULL)
          *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
-            "cHRM red Y");
+             "cHRM red Y");
       if (green_x != NULL)
          *green_x = png_float(png_ptr,
-            info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
+             info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
       if (green_y != NULL)
          *green_y = png_float(png_ptr,
-            info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
+             info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
       if (blue_x != NULL)
          *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
-            "cHRM blue X");
+             "cHRM blue X");
       if (blue_y != NULL)
          *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
-            "cHRM blue Y");
+             "cHRM blue Y");
       return (PNG_INFO_cHRM);
    }
 
@@ -556,42 +556,42 @@
 
 png_uint_32 PNGAPI
 png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
-   double *red_X, double *red_Y, double *red_Z, double *green_X,
-   double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
-   double *blue_Z)
+    double *red_X, double *red_Y, double *red_Z, double *green_X,
+    double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
+    double *blue_Z)
 {
    if (png_ptr != NULL && info_ptr != NULL &&
-      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+       (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
    {
       png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
 
       if (red_X != NULL)
          *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
-            "cHRM red X");
+             "cHRM red X");
       if (red_Y != NULL)
          *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
-            "cHRM red Y");
+             "cHRM red Y");
       if (red_Z != NULL)
          *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
-            "cHRM red Z");
+             "cHRM red Z");
       if (green_X != NULL)
          *green_X = png_float(png_ptr,
-            info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
+             info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
       if (green_Y != NULL)
          *green_Y = png_float(png_ptr,
-            info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
+             info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
       if (green_Z != NULL)
          *green_Z = png_float(png_ptr,
-            info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
+             info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
       if (blue_X != NULL)
          *blue_X = png_float(png_ptr,
-            info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
+             info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
       if (blue_Y != NULL)
          *blue_Y = png_float(png_ptr,
-            info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
+             info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
       if (blue_Z != NULL)
          *blue_Z = png_float(png_ptr,
-            info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
+             info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
       return (PNG_INFO_cHRM);
    }
 
@@ -681,8 +681,8 @@
    png_debug1(1, "in %s retrieval function", "gAMA");
 
    if (png_ptr != NULL && info_ptr != NULL &&
-      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
-      file_gamma != NULL)
+       (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
+       file_gamma != NULL)
    {
       *file_gamma = info_ptr->colorspace.gamma;
       return (PNG_INFO_gAMA);
@@ -704,7 +704,7 @@
       file_gamma != NULL)
    {
       *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
-         "png_get_gAMA");
+          "png_get_gAMA");
       return (PNG_INFO_gAMA);
    }
 
@@ -773,6 +773,35 @@
 }
 #endif
 
+#ifdef PNG_eXIf_SUPPORTED
+png_uint_32 PNGAPI
+png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_bytep *exif)
+{
+  png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1");
+  PNG_UNUSED(info_ptr)
+  PNG_UNUSED(exif)
+  return 0;
+}
+
+png_uint_32 PNGAPI
+png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_uint_32 *num_exif, png_bytep *exif)
+{
+   png_debug1(1, "in %s retrieval function", "eXIf");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL)
+   {
+      *num_exif = info_ptr->num_exif;
+      *exif = info_ptr->exif;
+      return (PNG_INFO_eXIf);
+   }
+
+   return (0);
+}
+#endif
+
 #ifdef PNG_hIST_SUPPORTED
 png_uint_32 PNGAPI
 png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
@@ -901,7 +930,7 @@
        */
       *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
       *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
-         "sCAL height");
+          "sCAL height");
       return (PNG_INFO_sCAL);
    }
 
diff --git a/third_party/libpng/pnginfo.h b/third_party/libpng/pnginfo.h
index 361ed8be..d5f6149 100644
--- a/third_party/libpng/pnginfo.h
+++ b/third_party/libpng/pnginfo.h
@@ -185,6 +185,14 @@
    png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
 #endif
 
+#ifdef PNG_eXIf_SUPPORTED
+   int num_exif;  /* Added at libpng-1.6.31 */
+   png_bytep exif;
+# ifdef PNG_READ_eXIf_SUPPORTED
+   png_bytep eXIf_buf;  /* Added at libpng-1.6.32 */
+# endif
+#endif
+
 #ifdef PNG_hIST_SUPPORTED
    /* The hIST chunk contains the relative frequency or importance of the
     * various palette entries, so that a viewer can intelligently select a
diff --git a/third_party/libpng/pngmem.c b/third_party/libpng/pngmem.c
index 7bcfd00..ff3ef7e 100644
--- a/third_party/libpng/pngmem.c
+++ b/third_party/libpng/pngmem.c
@@ -1,8 +1,8 @@
 
 /* pngmem.c - stub functions for memory allocation
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.26 [October 20, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -66,7 +66,7 @@
  */
 PNG_FUNCTION(png_voidp /* PRIVATE */,
 png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
-   PNG_ALLOCATED)
+    PNG_ALLOCATED)
 {
    /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
     * allocators have also been removed in 1.6.0, so any 16-bit system now has
@@ -107,9 +107,9 @@
  */
 static png_voidp
 png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
-   size_t element_size)
+    size_t element_size)
 {
-   png_alloc_size_t req = nelements; /* known to be > 0 */
+   png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */
 
    if (req <= PNG_SIZE_MAX/element_size)
       return png_malloc_base(png_ptr, req * element_size);
@@ -120,7 +120,7 @@
 
 PNG_FUNCTION(png_voidp /* PRIVATE */,
 png_malloc_array,(png_const_structrp png_ptr, int nelements,
-   size_t element_size),PNG_ALLOCATED)
+    size_t element_size),PNG_ALLOCATED)
 {
    if (nelements <= 0 || element_size == 0)
       png_error(png_ptr, "internal error: array alloc");
@@ -130,7 +130,7 @@
 
 PNG_FUNCTION(png_voidp /* PRIVATE */,
 png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
-   int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
+    int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
 {
    /* These are internal errors: */
    if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
@@ -143,7 +143,7 @@
    if (add_elements <= INT_MAX - old_elements)
    {
       png_voidp new_array = png_malloc_array_checked(png_ptr,
-         old_elements+add_elements, element_size);
+          old_elements+add_elements, element_size);
 
       if (new_array != NULL)
       {
@@ -154,7 +154,7 @@
             memcpy(new_array, old_array, element_size*(unsigned)old_elements);
 
          memset((char*)new_array + element_size*(unsigned)old_elements, 0,
-            element_size*(unsigned)add_elements);
+             element_size*(unsigned)add_elements);
 
          return new_array;
       }
@@ -187,7 +187,7 @@
 #ifdef PNG_USER_MEM_SUPPORTED
 PNG_FUNCTION(png_voidp,PNGAPI
 png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
-   PNG_ALLOCATED PNG_DEPRECATED)
+    PNG_ALLOCATED PNG_DEPRECATED)
 {
    png_voidp ret;
 
@@ -210,7 +210,7 @@
  */
 PNG_FUNCTION(png_voidp,PNGAPI
 png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
-   PNG_ALLOCATED)
+    PNG_ALLOCATED)
 {
    if (png_ptr != NULL)
    {
diff --git a/third_party/libpng/pngpread.c b/third_party/libpng/pngpread.c
index a16fcbef..fbe361d 100644
--- a/third_party/libpng/pngpread.c
+++ b/third_party/libpng/pngpread.c
@@ -1,8 +1,8 @@
 
 /* pngpread.c - read a png file in push mode
  *
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -77,11 +77,11 @@
 png_uint_32 PNGAPI
 png_process_data_skip(png_structrp png_ptr)
 {
-  /* TODO: Deprecate and remove this API.
-   * Somewhere the implementation of this seems to have been lost,
-   * or abandoned.  It was only to support some internal back-door access
-   * to png_struct) in libpng-1.4.x.
-   */
+/* TODO: Deprecate and remove this API.
+ * Somewhere the implementation of this seems to have been lost,
+ * or abandoned.  It was only to support some internal back-door access
+ * to png_struct) in libpng-1.4.x.
+ */
    png_app_warning(png_ptr,
 "png_process_data_skip is not implemented in any current version of libpng");
    return 0;
@@ -189,6 +189,7 @@
       png_crc_read(png_ptr, chunk_tag, 4);
       png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
       png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+      png_check_chunk_length(png_ptr, png_ptr->push_length);
       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    }
 
@@ -410,7 +411,7 @@
    {
       PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
-         PNG_HANDLE_CHUNK_AS_DEFAULT);
+          PNG_HANDLE_CHUNK_AS_DEFAULT);
    }
 
    png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
@@ -501,7 +502,10 @@
          png_error(png_ptr, "Insufficient memory for save_buffer");
       }
 
-      memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+      if (old_buffer)
+         memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+      else if (png_ptr->save_buffer_size)
+         png_error(png_ptr, "save_buffer error");
       png_free(png_ptr, old_buffer);
       png_ptr->save_buffer_max = new_max;
    }
@@ -518,7 +522,7 @@
 
 void /* PRIVATE */
 png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
-   png_size_t buffer_length)
+    png_size_t buffer_length)
 {
    png_ptr->current_buffer = buffer;
    png_ptr->current_buffer_size = buffer_length;
@@ -621,7 +625,7 @@
 
 void /* PRIVATE */
 png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
-   png_size_t buffer_length)
+    png_size_t buffer_length)
 {
    /* The caller checks for a non-zero buffer length. */
    if (!(buffer_length > 0) || buffer == NULL)
@@ -681,7 +685,12 @@
             png_warning(png_ptr, "Truncated compressed data in IDAT");
 
          else
-            png_error(png_ptr, "Decompression error in IDAT");
+         {
+            if (ret == Z_DATA_ERROR)
+               png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch");
+            else
+               png_error(png_ptr, "Decompression error in IDAT");
+         }
 
          /* Skip the check on unprocessed input */
          return;
@@ -779,7 +788,7 @@
    {
       if (png_ptr->pass < 6)
          png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
-            png_ptr->transformations);
+             png_ptr->transformations);
 
       switch (png_ptr->pass)
       {
@@ -1041,7 +1050,7 @@
 {
    if (png_ptr->row_fn != NULL)
       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
-         (int)png_ptr->pass);
+          (int)png_ptr->pass);
 }
 
 #ifdef PNG_READ_INTERLACING_SUPPORTED
diff --git a/third_party/libpng/pngprefix.h b/third_party/libpng/pngprefix.h
index 4afeb8f..6fa8461 100644
--- a/third_party/libpng/pngprefix.h
+++ b/third_party/libpng/pngprefix.h
@@ -129,6 +129,8 @@
 #define png_get_copyright cr_png_get_copyright
 #define png_get_current_pass_number cr_png_get_current_pass_number
 #define png_get_current_row_number cr_png_get_current_row_number
+#define png_get_eXIf cr_png_get_eXIf
+#define png_get_eXIf_1 cr_png_get_eXIf_1
 #define png_get_error_ptr cr_png_get_error_ptr
 #define png_get_filter_type cr_png_get_filter_type
 #define png_get_gAMA cr_png_get_gAMA
@@ -335,6 +337,8 @@
 #define png_set_compression_strategy cr_png_set_compression_strategy
 #define png_set_compression_window_bits cr_png_set_compression_window_bits
 #define png_set_crc_action cr_png_set_crc_action
+#define png_set_eXIf cr_png_set_eXIf
+#define png_set_eXIf_1 cr_png_set_eXIf_1
 #define png_set_error_fn cr_png_set_error_fn
 #define png_set_expand cr_png_set_expand
 #define png_set_expand_16 cr_png_set_expand_16
diff --git a/third_party/libpng/pngpriv.h b/third_party/libpng/pngpriv.h
index 63367135..5652525b 100644
--- a/third_party/libpng/pngpriv.h
+++ b/third_party/libpng/pngpriv.h
@@ -1,8 +1,8 @@
 
 /* pngpriv.h - private declarations for use inside libpng
  *
- * Last changed in libpng 1.6.22 [May 26, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -35,7 +35,9 @@
  * Windows/Visual Studio) there is no effect; the OS specific tests below are
  * still required (as of 2011-05-02.)
  */
-#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
+#endif
 
 #ifndef PNG_VERSION_INFO_ONLY
 /* Standard library headers not required by png.h: */
@@ -182,6 +184,22 @@
 #  endif
 #endif /* PNG_ARM_NEON_OPT > 0 */
 
+#ifndef PNG_MIPS_MSA_OPT
+#  if defined(__mips_msa) && (__mips_isa_rev >= 5) && defined(PNG_ALIGNED_MEMORY_SUPPORTED)
+#     define PNG_MIPS_MSA_OPT 2
+#  else
+#     define PNG_MIPS_MSA_OPT 0
+#  endif
+#endif
+
+#ifndef PNG_POWERPC_VSX_OPT
+#  if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__)
+#     define PNG_POWERPC_VSX_OPT 2
+#  else
+#     define PNG_POWERPC_VSX_OPT 0
+#  endif
+#endif
+
 #ifndef PNG_INTEL_SSE_OPT
 #   ifdef PNG_INTEL_SSE
       /* Only check for SSE if the build configuration has been modified to
@@ -218,6 +236,32 @@
 #   endif
 #endif
 
+#if PNG_MIPS_MSA_OPT > 0
+#  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa
+#  ifndef PNG_MIPS_MSA_IMPLEMENTATION
+#     if defined(__mips_msa)
+#        if defined(__clang__)
+#        elif defined(__GNUC__)
+#           if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)
+#              define PNG_MIPS_MSA_IMPLEMENTATION 2
+#           endif /* no GNUC support */
+#        endif /* __GNUC__ */
+#     else /* !defined __mips_msa */
+#        define PNG_MIPS_MSA_IMPLEMENTATION 2
+#     endif /* __mips_msa */
+#  endif /* !PNG_MIPS_MSA_IMPLEMENTATION */
+
+#  ifndef PNG_MIPS_MSA_IMPLEMENTATION
+#     define PNG_MIPS_MSA_IMPLEMENTATION 1
+#  endif
+#endif /* PNG_MIPS_MSA_OPT > 0 */
+
+#if PNG_POWERPC_VSX_OPT > 0
+#  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx
+#  define PNG_POWERPC_VSX_IMPLEMENTATION 1
+#endif
+
+
 /* Is this a build of a DLL where compilation of the object modules requires
  * different preprocessor settings to those required for a simple library?  If
  * so PNG_BUILD_DLL must be set.
@@ -410,25 +454,6 @@
 #  define png_fixed_error(s1,s2) png_err(s1)
 #endif
 
-/* C allows up-casts from (void*) to any pointer and (const void*) to any
- * pointer to a const object.  C++ regards this as a type error and requires an
- * explicit, static, cast and provides the static_cast<> rune to ensure that
- * const is not cast away.
- */
-#ifdef __cplusplus
-#  define png_voidcast(type, value) static_cast<type>(value)
-#  define png_constcast(type, value) const_cast<type>(value)
-#  define png_aligncast(type, value) \
-   static_cast<type>(static_cast<void*>(value))
-#  define png_aligncastconst(type, value) \
-   static_cast<type>(static_cast<const void*>(value))
-#else
-#  define png_voidcast(type, value) (value)
-#  define png_constcast(type, value) ((type)(value))
-#  define png_aligncast(type, value) ((void*)(value))
-#  define png_aligncastconst(type, value) ((const void*)(value))
-#endif /* __cplusplus */
-
 /* Some fixed point APIs are still required even if not exported because
  * they get used by the corresponding floating point APIs.  This magic
  * deals with this:
@@ -443,6 +468,35 @@
 /* Other defines specific to compilers can go here.  Try to keep
  * them inside an appropriate ifdef/endif pair for portability.
  */
+
+/* C allows up-casts from (void*) to any pointer and (const void*) to any
+ * pointer to a const object.  C++ regards this as a type error and requires an
+ * explicit, static, cast and provides the static_cast<> rune to ensure that
+ * const is not cast away.
+ */
+#ifdef __cplusplus
+#  define png_voidcast(type, value) static_cast<type>(value)
+#  define png_constcast(type, value) const_cast<type>(value)
+#  define png_aligncast(type, value) \
+   static_cast<type>(static_cast<void*>(value))
+#  define png_aligncastconst(type, value) \
+   static_cast<type>(static_cast<const void*>(value))
+#else
+#  define png_voidcast(type, value) (value)
+#  ifdef _WIN64
+#     ifdef __GNUC__
+         typedef unsigned long long png_ptruint;
+#     else
+         typedef unsigned __int64 png_ptruint;
+#     endif
+#  else
+      typedef unsigned long png_ptruint;
+#  endif
+#  define png_constcast(type, value) ((type)(png_ptruint)(const void*)(value))
+#  define png_aligncast(type, value) ((void*)(value))
+#  define png_aligncastconst(type, value) ((const void*)(value))
+#endif /* __cplusplus */
+
 #if defined(PNG_FLOATING_POINT_SUPPORTED) ||\
     defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
    /* png.c requires the following ANSI-C constants if the conversion of
@@ -456,10 +510,10 @@
 
 #  if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
     defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
-     /* We need to check that <math.h> hasn't already been included earlier
-      * as it seems it doesn't agree with <fp.h>, yet we should really use
-      * <fp.h> if possible.
-      */
+   /* We need to check that <math.h> hasn't already been included earlier
+    * as it seems it doesn't agree with <fp.h>, yet we should really use
+    * <fp.h> if possible.
+    */
 #    if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
 #      include <fp.h>
 #    endif
@@ -467,9 +521,9 @@
 #    include <math.h>
 #  endif
 #  if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
-     /* Amiga SAS/C: We must include builtin FPU functions when compiling using
-      * MATH=68881
-      */
+   /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+    * MATH=68881
+    */
 #    include <m68881.h>
 #  endif
 #endif
@@ -540,7 +594,8 @@
 /* This implicitly assumes alignment is always to a power of 2. */
 #ifdef png_alignof
 #  define png_isaligned(ptr, type)\
-   ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0)
+   (((type)((const char*)ptr-(const char*)0) & \
+   (type)(png_alignof(type)-1)) == 0)
 #else
 #  define png_isaligned(ptr, type) 0
 #endif
@@ -557,92 +612,92 @@
  * are defined in png.h because they need to be visible to applications
  * that call png_set_unknown_chunk().
  */
-/* #define PNG_HAVE_IHDR            0x01 (defined in png.h) */
-/* #define PNG_HAVE_PLTE            0x02 (defined in png.h) */
-#define PNG_HAVE_IDAT               0x04
-/* #define PNG_AFTER_IDAT           0x08 (defined in png.h) */
-#define PNG_HAVE_IEND               0x10
-                   /*               0x20 (unused) */
-                   /*               0x40 (unused) */
-                   /*               0x80 (unused) */
-#define PNG_HAVE_CHUNK_HEADER      0x100
-#define PNG_WROTE_tIME             0x200
-#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
-#define PNG_BACKGROUND_IS_GRAY     0x800
-#define PNG_HAVE_PNG_SIGNATURE    0x1000
-#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
-                   /*             0x4000 (unused) */
-#define PNG_IS_READ_STRUCT        0x8000 /* Else is a write struct */
+/* #define PNG_HAVE_IHDR            0x01U (defined in png.h) */
+/* #define PNG_HAVE_PLTE            0x02U (defined in png.h) */
+#define PNG_HAVE_IDAT               0x04U
+/* #define PNG_AFTER_IDAT           0x08U (defined in png.h) */
+#define PNG_HAVE_IEND               0x10U
+                   /*               0x20U (unused) */
+                   /*               0x40U (unused) */
+                   /*               0x80U (unused) */
+#define PNG_HAVE_CHUNK_HEADER      0x100U
+#define PNG_WROTE_tIME             0x200U
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400U
+#define PNG_BACKGROUND_IS_GRAY     0x800U
+#define PNG_HAVE_PNG_SIGNATURE    0x1000U
+#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
+                   /*             0x4000U (unused) */
+#define PNG_IS_READ_STRUCT        0x8000U /* Else is a write struct */
 
 /* Flags for the transformations the PNG library does on the image data */
-#define PNG_BGR                 0x0001
-#define PNG_INTERLACE           0x0002
-#define PNG_PACK                0x0004
-#define PNG_SHIFT               0x0008
-#define PNG_SWAP_BYTES          0x0010
-#define PNG_INVERT_MONO         0x0020
-#define PNG_QUANTIZE            0x0040
-#define PNG_COMPOSE             0x0080     /* Was PNG_BACKGROUND */
-#define PNG_BACKGROUND_EXPAND   0x0100
-#define PNG_EXPAND_16           0x0200     /* Added to libpng 1.5.2 */
-#define PNG_16_TO_8             0x0400     /* Becomes 'chop' in 1.5.4 */
-#define PNG_RGBA                0x0800
-#define PNG_EXPAND              0x1000
-#define PNG_GAMMA               0x2000
-#define PNG_GRAY_TO_RGB         0x4000
-#define PNG_FILLER              0x8000
-#define PNG_PACKSWAP           0x10000
-#define PNG_SWAP_ALPHA         0x20000
-#define PNG_STRIP_ALPHA        0x40000
-#define PNG_INVERT_ALPHA       0x80000
-#define PNG_USER_TRANSFORM    0x100000
-#define PNG_RGB_TO_GRAY_ERR   0x200000
-#define PNG_RGB_TO_GRAY_WARN  0x400000
-#define PNG_RGB_TO_GRAY       0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */
-#define PNG_ENCODE_ALPHA      0x800000 /* Added to libpng-1.5.4 */
-#define PNG_ADD_ALPHA        0x1000000 /* Added to libpng-1.2.7 */
-#define PNG_EXPAND_tRNS      0x2000000 /* Added to libpng-1.2.9 */
-#define PNG_SCALE_16_TO_8    0x4000000 /* Added to libpng-1.5.4 */
-                       /*    0x8000000 unused */
-                       /*   0x10000000 unused */
-                       /*   0x20000000 unused */
-                       /*   0x40000000 unused */
+#define PNG_BGR                 0x0001U
+#define PNG_INTERLACE           0x0002U
+#define PNG_PACK                0x0004U
+#define PNG_SHIFT               0x0008U
+#define PNG_SWAP_BYTES          0x0010U
+#define PNG_INVERT_MONO         0x0020U
+#define PNG_QUANTIZE            0x0040U
+#define PNG_COMPOSE             0x0080U    /* Was PNG_BACKGROUND */
+#define PNG_BACKGROUND_EXPAND   0x0100U
+#define PNG_EXPAND_16           0x0200U    /* Added to libpng 1.5.2 */
+#define PNG_16_TO_8             0x0400U    /* Becomes 'chop' in 1.5.4 */
+#define PNG_RGBA                0x0800U
+#define PNG_EXPAND              0x1000U
+#define PNG_GAMMA               0x2000U
+#define PNG_GRAY_TO_RGB         0x4000U
+#define PNG_FILLER              0x8000U
+#define PNG_PACKSWAP           0x10000U
+#define PNG_SWAP_ALPHA         0x20000U
+#define PNG_STRIP_ALPHA        0x40000U
+#define PNG_INVERT_ALPHA       0x80000U
+#define PNG_USER_TRANSFORM    0x100000U
+#define PNG_RGB_TO_GRAY_ERR   0x200000U
+#define PNG_RGB_TO_GRAY_WARN  0x400000U
+#define PNG_RGB_TO_GRAY       0x600000U /* two bits, RGB_TO_GRAY_ERR|WARN */
+#define PNG_ENCODE_ALPHA      0x800000U /* Added to libpng-1.5.4 */
+#define PNG_ADD_ALPHA        0x1000000U /* Added to libpng-1.2.7 */
+#define PNG_EXPAND_tRNS      0x2000000U /* Added to libpng-1.2.9 */
+#define PNG_SCALE_16_TO_8    0x4000000U /* Added to libpng-1.5.4 */
+                       /*    0x8000000U unused */
+                       /*   0x10000000U unused */
+                       /*   0x20000000U unused */
+                       /*   0x40000000U unused */
 /* Flags for png_create_struct */
-#define PNG_STRUCT_PNG   0x0001
-#define PNG_STRUCT_INFO  0x0002
+#define PNG_STRUCT_PNG   0x0001U
+#define PNG_STRUCT_INFO  0x0002U
 
 /* Flags for the png_ptr->flags rather than declaring a byte for each one */
-#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001
-#define PNG_FLAG_ZSTREAM_INITIALIZED      0x0002 /* Added to libpng-1.6.0 */
-                                  /*      0x0004    unused */
-#define PNG_FLAG_ZSTREAM_ENDED            0x0008 /* Added to libpng-1.6.0 */
-                                  /*      0x0010    unused */
-                                  /*      0x0020    unused */
-#define PNG_FLAG_ROW_INIT                 0x0040
-#define PNG_FLAG_FILLER_AFTER             0x0080
-#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100
-#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200
-#define PNG_FLAG_CRC_CRITICAL_USE         0x0400
-#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800
-#define PNG_FLAG_ASSUME_sRGB              0x1000 /* Added to libpng-1.5.4 */
-#define PNG_FLAG_OPTIMIZE_ALPHA           0x2000 /* Added to libpng-1.5.4 */
-#define PNG_FLAG_DETECT_UNINITIALIZED     0x4000 /* Added to libpng-1.5.4 */
-/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000 */
-/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS      0x10000 */
-#define PNG_FLAG_LIBRARY_MISMATCH        0x20000
-#define PNG_FLAG_STRIP_ERROR_NUMBERS     0x40000
-#define PNG_FLAG_STRIP_ERROR_TEXT        0x80000
-#define PNG_FLAG_BENIGN_ERRORS_WARN     0x100000 /* Added to libpng-1.4.0 */
-#define PNG_FLAG_APP_WARNINGS_WARN      0x200000 /* Added to libpng-1.6.0 */
-#define PNG_FLAG_APP_ERRORS_WARN        0x400000 /* Added to libpng-1.6.0 */
-                                  /*    0x800000    unused */
-                                  /*   0x1000000    unused */
-                                  /*   0x2000000    unused */
-                                  /*   0x4000000    unused */
-                                  /*   0x8000000    unused */
-                                  /*  0x10000000    unused */
-                                  /*  0x20000000    unused */
-                                  /*  0x40000000    unused */
+#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001U
+#define PNG_FLAG_ZSTREAM_INITIALIZED      0x0002U /* Added to libpng-1.6.0 */
+                                  /*      0x0004U    unused */
+#define PNG_FLAG_ZSTREAM_ENDED            0x0008U /* Added to libpng-1.6.0 */
+                                  /*      0x0010U    unused */
+                                  /*      0x0020U    unused */
+#define PNG_FLAG_ROW_INIT                 0x0040U
+#define PNG_FLAG_FILLER_AFTER             0x0080U
+#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100U
+#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200U
+#define PNG_FLAG_CRC_CRITICAL_USE         0x0400U
+#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800U
+#define PNG_FLAG_ASSUME_sRGB              0x1000U /* Added to libpng-1.5.4 */
+#define PNG_FLAG_OPTIMIZE_ALPHA           0x2000U /* Added to libpng-1.5.4 */
+#define PNG_FLAG_DETECT_UNINITIALIZED     0x4000U /* Added to libpng-1.5.4 */
+/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000U */
+/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS      0x10000U */
+#define PNG_FLAG_LIBRARY_MISMATCH        0x20000U
+#define PNG_FLAG_STRIP_ERROR_NUMBERS     0x40000U
+#define PNG_FLAG_STRIP_ERROR_TEXT        0x80000U
+#define PNG_FLAG_BENIGN_ERRORS_WARN     0x100000U /* Added to libpng-1.4.0 */
+#define PNG_FLAG_APP_WARNINGS_WARN      0x200000U /* Added to libpng-1.6.0 */
+#define PNG_FLAG_APP_ERRORS_WARN        0x400000U /* Added to libpng-1.6.0 */
+                                  /*    0x800000U    unused */
+                                  /*   0x1000000U    unused */
+                                  /*   0x2000000U    unused */
+                                  /*   0x4000000U    unused */
+                                  /*   0x8000000U    unused */
+                                  /*  0x10000000U    unused */
+                                  /*  0x20000000U    unused */
+                                  /*  0x40000000U    unused */
 
 #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
                                      PNG_FLAG_CRC_ANCILLARY_NOWARN)
@@ -676,6 +731,24 @@
     ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \
     (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )
 
+/* This returns the number of trailing bits in the last byte of a row, 0 if the
+ * last byte is completely full of pixels.  It is, in principle, (pixel_bits x
+ * width) % 8, but that would overflow for large 'width'.  The second macro is
+ * the same except that it returns the number of unused bits in the last byte;
+ * (8-TRAILBITS), but 0 when TRAILBITS is 0.
+ *
+ * NOTE: these macros are intended to be self-evidently correct and never
+ * overflow on the assumption that pixel_bits is in the range 0..255.  The
+ * arguments are evaluated only once and they can be signed (e.g. as a result of
+ * the integral promotions).  The result of the expression always has type
+ * (png_uint_32), however the compiler always knows it is in the range 0..7.
+ */
+#define PNG_TRAILBITS(pixel_bits, width) \
+    (((pixel_bits) * ((width) % (png_uint_32)8)) % 8)
+
+#define PNG_PADBITS(pixel_bits, width) \
+    ((8 - PNG_TRAILBITS(pixel_bits, width)) % 8)
+
 /* PNG_OUT_OF_RANGE returns true if value is outside the range
  * ideal-delta..ideal+delta.  Each argument is evaluated twice.
  * "ideal" and "delta" should be constants, normally simple
@@ -769,6 +842,7 @@
 #define png_PLTE PNG_U32( 80,  76,  84,  69)
 #define png_bKGD PNG_U32( 98,  75,  71,  68)
 #define png_cHRM PNG_U32( 99,  72,  82,  77)
+#define png_eXIf PNG_U32(101,  88,  73, 102) /* registered July 2017 */
 #define png_fRAc PNG_U32(102,  82,  65,  99) /* registered, not defined */
 #define png_gAMA PNG_U32(103,  65,  77,  65)
 #define png_gIFg PNG_U32(103,  73,  70, 103)
@@ -1061,7 +1135,7 @@
 #ifdef PNG_WRITE_cHRM_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,
     const png_xy *xy), PNG_EMPTY);
-    /* The xy value must have been previously validated */
+   /* The xy value must have been previously validated */
 #endif
 
 #ifdef PNG_WRITE_sRGB_SUPPORTED
@@ -1069,6 +1143,11 @@
     int intent),PNG_EMPTY);
 #endif
 
+#ifdef PNG_WRITE_eXIf_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_eXIf,(png_structrp png_ptr,
+    png_bytep exif, int num_exif),PNG_EMPTY);
+#endif
+
 #ifdef PNG_WRITE_iCCP_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
    png_const_charp name, png_const_bytep profile), PNG_EMPTY);
@@ -1210,6 +1289,7 @@
 PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop
     row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY);
 
+#if PNG_ARM_NEON_OPT > 0
 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info,
     png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop
@@ -1224,7 +1304,43 @@
     row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
     row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
 
+#if PNG_MIPS_MSA_OPT > 0
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info,
+    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
+
+#if PNG_POWERPC_VSX_OPT > 0
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info,
+    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_vsx,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_vsx,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_vsx,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_vsx,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_vsx,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_vsx,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
+
+#if PNG_INTEL_SSE_IMPLEMENTATION > 0
 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop
     row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop
@@ -1237,6 +1353,7 @@
     row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop
     row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
 
 /* Choose the best filter to use and filter the row data */
 PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
@@ -1264,7 +1381,7 @@
 /* Initialize the row buffers, etc. */
 PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
 
-#if PNG_ZLIB_VERNUM >= 0x1240
+#if ZLIB_VERNUM >= 0x1240
 PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush),
       PNG_EMPTY);
 #  define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush)
@@ -1330,6 +1447,11 @@
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
 #endif
 
+#ifdef PNG_READ_eXIf_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_eXIf,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
 #ifdef PNG_READ_gAMA_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
@@ -1405,8 +1527,11 @@
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
 #endif
 
-PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr,
-    png_uint_32 chunk_name),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr,
+    const png_uint_32 chunk_name),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr,
+    const png_uint_32 chunk_length),PNG_EMPTY);
 
 PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
@@ -1462,7 +1587,7 @@
 PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,
    png_inforp info_ptr),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr,
-     png_bytep row),PNG_EMPTY);
+    png_bytep row),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr,
     png_inforp info_ptr),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,
@@ -1501,13 +1626,13 @@
 
 PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr,
     png_inforp info_ptr), PNG_EMPTY);
-    /* Synchronize the info 'valid' flags with the colorspace */
+   /* Synchronize the info 'valid' flags with the colorspace */
 
 PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr,
     png_inforp info_ptr), PNG_EMPTY);
-    /* Copy the png_struct colorspace to the info_struct and call the above to
-     * synchronize the flags.  Checks for NULL info_ptr and does nothing.
-     */
+   /* Copy the png_struct colorspace to the info_struct and call the above to
+    * synchronize the flags.  Checks for NULL info_ptr and does nothing.
+    */
 #endif
 
 /* Added at libpng version 1.4.0 */
@@ -1964,15 +2089,48 @@
     * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in
     * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing.
     */
+#  if PNG_ARM_NEON_OPT > 0
 PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
    (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+#endif
+
+#if PNG_MIPS_MSA_OPT > 0
+PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa,
+   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+#endif
+
+#  if PNG_INTEL_SSE_IMPLEMENTATION > 0
 PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,
    (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+#  endif
 #endif
 
 PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
    png_const_charp key, png_bytep new_key), PNG_EMPTY);
 
+#if PNG_ARM_NEON_IMPLEMENTATION == 1
+PNG_INTERNAL_FUNCTION(void,
+                      png_riffle_palette_rgba,
+                      (png_structrp, png_row_infop),
+                      PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,
+                      png_do_expand_palette_neon_rgba,
+                      (png_structrp,
+                       png_row_infop,
+                       png_const_bytep,
+                       const png_bytepp,
+                       const png_bytepp),
+                      PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,
+                      png_do_expand_palette_neon_rgb,
+                      (png_structrp,
+                       png_row_infop,
+                       png_const_bytep,
+                       const png_bytepp,
+                       const png_bytepp),
+                      PNG_EMPTY);
+#endif
+
 /* Maintainer: Put new private prototypes here ^ */
 
 #include "pngdebug.h"
diff --git a/third_party/libpng/pngread.c b/third_party/libpng/pngread.c
index 0572c20..da32e9ad 100644
--- a/third_party/libpng/pngread.c
+++ b/third_party/libpng/pngread.c
@@ -1,8 +1,8 @@
 
 /* pngread.c - read a PNG file
  *
- * Last changed in libpng 1.6.17 [March 26, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -28,10 +28,10 @@
 {
 #ifndef PNG_USER_MEM_SUPPORTED
    png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
-      error_fn, warn_fn, NULL, NULL, NULL);
+        error_fn, warn_fn, NULL, NULL, NULL);
 #else
    return png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
-       warn_fn, NULL, NULL, NULL);
+        warn_fn, NULL, NULL, NULL);
 }
 
 /* Alternate create PNG structure for reading, and allocate any memory
@@ -43,7 +43,7 @@
     png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
 {
    png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
-      error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
+       error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
 #endif /* USER_MEM */
 
    if (png_ptr != NULL)
@@ -175,6 +175,11 @@
          png_handle_cHRM(png_ptr, info_ptr, length);
 #endif
 
+#ifdef PNG_READ_eXIf_SUPPORTED
+      else if (chunk_name == png_eXIf)
+         png_handle_eXIf(png_ptr, info_ptr, length);
+#endif
+
 #ifdef PNG_READ_gAMA_SUPPORTED
       else if (chunk_name == png_gAMA)
          png_handle_gAMA(png_ptr, info_ptr, length);
@@ -252,7 +257,7 @@
 
       else
          png_handle_unknown(png_ptr, info_ptr, length,
-            PNG_HANDLE_CHUNK_AS_DEFAULT);
+             PNG_HANDLE_CHUNK_AS_DEFAULT);
    }
 }
 #endif /* SEQUENTIAL_READ */
@@ -279,7 +284,7 @@
       /* New in 1.6.0 this avoids the bug of doing the initializations twice */
       else
          png_app_error(png_ptr,
-            "png_read_update_info/png_start_read_image: duplicate call");
+             "png_read_update_info/png_start_read_image: duplicate call");
    }
 }
 
@@ -302,7 +307,7 @@
       /* New in 1.6.0 this avoids the bug of doing the initializations twice */
       else
          png_app_error(png_ptr,
-            "png_start_read_image/png_read_update_info: duplicate call");
+             "png_start_read_image/png_read_update_info: duplicate call");
    }
 }
 #endif /* SEQUENTIAL_READ */
@@ -359,9 +364,9 @@
 
          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
          {
-            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
-            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
-            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
+            png_uint_32 s0   = (png_uint_32)(*(rp    ) << 8) | *(rp + 1);
+            png_uint_32 s1   = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3);
+            png_uint_32 s2   = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5);
             png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;
             png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
             *(rp    ) = (png_byte)((red >> 8) & 0xff);
@@ -534,13 +539,14 @@
       png_error(png_ptr, "Invalid attempt to read row data");
 
    /* Fill the row with IDAT data: */
+   png_ptr->row_buf[0]=255; /* to force error if no data was found */
    png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1);
 
    if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
    {
       if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
          png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
-            png_ptr->prev_row + 1, png_ptr->row_buf[0]);
+             png_ptr->prev_row + 1, png_ptr->row_buf[0]);
       else
          png_error(png_ptr, "bad adaptive filter value");
    }
@@ -584,7 +590,7 @@
    {
       if (png_ptr->pass < 6)
          png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
-            png_ptr->transformations);
+             png_ptr->transformations);
 
       if (dsp_row != NULL)
          png_combine_row(png_ptr, dsp_row, 1/*display*/);
@@ -719,7 +725,7 @@
           * but the caller should do it!
           */
          png_warning(png_ptr, "Interlace handling should be turned on when "
-            "using png_read_image");
+             "using png_read_image");
          /* Make sure this is set correctly */
          png_ptr->num_rows = png_ptr->height;
       }
@@ -779,8 +785,8 @@
 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
    /* Report invalid palette index; added at libng-1.5.10 */
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
-      png_ptr->num_palette_max > png_ptr->num_palette)
-     png_benign_error(png_ptr, "Read palette index exceeding num_palette");
+       png_ptr->num_palette_max > png_ptr->num_palette)
+      png_benign_error(png_ptr, "Read palette index exceeding num_palette");
 #endif
 
    do
@@ -842,6 +848,11 @@
          png_handle_cHRM(png_ptr, info_ptr, length);
 #endif
 
+#ifdef PNG_READ_eXIf_SUPPORTED
+      else if (chunk_name == png_eXIf)
+         png_handle_eXIf(png_ptr, info_ptr, length);
+#endif
+
 #ifdef PNG_READ_gAMA_SUPPORTED
       else if (chunk_name == png_gAMA)
          png_handle_gAMA(png_ptr, info_ptr, length);
@@ -919,7 +930,7 @@
 
       else
          png_handle_unknown(png_ptr, info_ptr, length,
-            PNG_HANDLE_CHUNK_AS_DEFAULT);
+             PNG_HANDLE_CHUNK_AS_DEFAULT);
    } while ((png_ptr->mode & PNG_HAVE_IEND) == 0);
 }
 #endif /* SEQUENTIAL_READ */
@@ -1030,8 +1041,7 @@
 #ifdef PNG_INFO_IMAGE_SUPPORTED
 void PNGAPI
 png_read_png(png_structrp png_ptr, png_inforp info_ptr,
-                           int transforms,
-                           voidp params)
+    int transforms, voidp params)
 {
    if (png_ptr == NULL || info_ptr == NULL)
       return;
@@ -1307,7 +1317,7 @@
          if (info_ptr != NULL)
          {
             png_controlp control = png_voidcast(png_controlp,
-               png_malloc_warn(png_ptr, (sizeof *control)));
+                png_malloc_warn(png_ptr, (sizeof *control)));
 
             if (control != NULL)
             {
@@ -1394,7 +1404,9 @@
    png_structrp png_ptr = image->opaque->png_ptr;
    png_inforp info_ptr = image->opaque->info_ptr;
 
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
    png_set_benign_errors(png_ptr, 1/*warn*/);
+#endif
    png_read_info(png_ptr, info_ptr);
 
    /* Do this the fast way; just read directly out of png_struct. */
@@ -1432,7 +1444,7 @@
             break;
 
          case PNG_COLOR_TYPE_PALETTE:
-            cmap_entries = png_ptr->num_palette;
+            cmap_entries = (png_uint_32)png_ptr->num_palette;
             break;
 
          default:
@@ -1470,12 +1482,12 @@
 
       else
          return png_image_error(image,
-            "png_image_begin_read_from_stdio: invalid argument");
+             "png_image_begin_read_from_stdio: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
+          "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
 
    return 0;
 }
@@ -1508,12 +1520,12 @@
 
       else
          return png_image_error(image,
-            "png_image_begin_read_from_file: invalid argument");
+             "png_image_begin_read_from_file: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
+          "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
 
    return 0;
 }
@@ -1550,7 +1562,7 @@
 }
 
 int PNGAPI png_image_begin_read_from_memory(png_imagep image,
-   png_const_voidp memory, png_size_t size)
+    png_const_voidp memory, png_size_t size)
 {
    if (image != NULL && image->version == PNG_IMAGE_VERSION)
    {
@@ -1573,12 +1585,12 @@
 
       else
          return png_image_error(image,
-            "png_image_begin_read_from_memory: invalid argument");
+             "png_image_begin_read_from_memory: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
+          "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
 
    return 0;
 }
@@ -1624,12 +1636,12 @@
         * IHDR, PLTE, tRNS, IDAT, and IEND chunks.
         */
        png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,
-         NULL, -1);
+           NULL, -1);
 
        /* But do not ignore image data handling chunks */
        png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT,
-         chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);
-    }
+           chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);
+   }
 }
 
 #  define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p)
@@ -1696,7 +1708,7 @@
 #ifdef __GNUC__
       default:
          png_error(display->image->opaque->png_ptr,
-            "unexpected encoding (internal error)");
+             "unexpected encoding (internal error)");
 #endif
    }
 
@@ -1705,8 +1717,8 @@
 
 static png_uint_32
 png_colormap_compose(png_image_read_control *display,
-   png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
-   png_uint_32 background, int encoding)
+    png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
+    png_uint_32 background, int encoding)
 {
    /* The file value is composed on the background, the background has the given
     * encoding and so does the result, the file is encoded with P_FILE and the
@@ -1742,14 +1754,14 @@
  */
 static void
 png_create_colormap_entry(png_image_read_control *display,
-   png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
-   png_uint_32 alpha, int encoding)
+    png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
+    png_uint_32 alpha, int encoding)
 {
    png_imagep image = display->image;
    const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
-      P_LINEAR : P_sRGB;
+       P_LINEAR : P_sRGB;
    const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
-      (red != green || green != blue);
+       (red != green || green != blue);
 
    if (ip > 255)
       png_error(image->opaque->png_ptr, "color-map index out of range");
@@ -1882,7 +1894,7 @@
          {
             case 4:
                entry[afirst ? 0 : 3] = (png_uint_16)alpha;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
             case 3:
                if (alpha < 65535)
@@ -1904,7 +1916,7 @@
 
             case 2:
                entry[1 ^ afirst] = (png_uint_16)alpha;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
             case 1:
                if (alpha < 65535)
@@ -1933,6 +1945,7 @@
          {
             case 4:
                entry[afirst ? 0 : 3] = (png_byte)alpha;
+               /* FALLTHROUGH */
             case 3:
                entry[afirst + (2 ^ bgr)] = (png_byte)blue;
                entry[afirst + 1] = (png_byte)green;
@@ -1941,6 +1954,7 @@
 
             case 2:
                entry[1 ^ afirst] = (png_byte)alpha;
+               /* FALLTHROUGH */
             case 1:
                entry[afirst] = (png_byte)green;
                break;
@@ -1967,7 +1981,7 @@
    for (i=0; i<256; ++i)
       png_create_colormap_entry(display, i, i, i, i, 255, P_FILE);
 
-   return i;
+   return (int)i;
 }
 
 static int
@@ -1978,7 +1992,7 @@
    for (i=0; i<256; ++i)
       png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB);
 
-   return i;
+   return (int)i;
 }
 #define PNG_GRAY_COLORMAP_ENTRIES 256
 
@@ -2029,10 +2043,10 @@
 
       for (g=0; g<6; ++g)
          png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,
-            P_sRGB);
+             P_sRGB);
    }
 
-   return i;
+   return (int)i;
 }
 
 #define PNG_GA_COLORMAP_ENTRIES 256
@@ -2053,11 +2067,11 @@
 
          for (b=0; b<6; ++b)
             png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,
-               P_sRGB);
+                P_sRGB);
       }
    }
 
-   return i;
+   return (int)i;
 }
 
 #define PNG_RGB_COLORMAP_ENTRIES 216
@@ -2105,7 +2119,7 @@
 
       else if (display->background == NULL /* no way to remove it */)
          png_error(png_ptr,
-            "a background color must be supplied to remove alpha/transparency");
+             "background color must be supplied to remove alpha/transparency");
 
       /* Get a copy of the background color (this avoids repeating the checks
        * below.)  The encoding is 8-bit sRGB or 16-bit linear, depending on the
@@ -2200,7 +2214,7 @@
                 */
                if (i != trans)
                   png_create_colormap_entry(display, i, val, val, val, 255,
-                     P_FILE/*8-bit with file gamma*/);
+                      P_FILE/*8-bit with file gamma*/);
 
                /* Else this entry is transparent.  The colors don't matter if
                 * there is an alpha channel (back_alpha == 0), but it does no
@@ -2212,7 +2226,7 @@
                 */
                else
                   png_create_colormap_entry(display, i, back_r, back_g, back_b,
-                     back_alpha, output_encoding);
+                      back_alpha, output_encoding);
             }
 
             /* We need libpng to preserve the original encoding. */
@@ -2250,7 +2264,7 @@
             if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
                png_error(png_ptr, "gray[16] color-map: too few entries");
 
-            cmap_entries = make_gray_colormap(display);
+            cmap_entries = (unsigned int)make_gray_colormap(display);
 
             if (png_ptr->num_trans > 0)
             {
@@ -2277,7 +2291,7 @@
                          * matches.
                          */
                         png_create_colormap_entry(display, gray, back_g, back_g,
-                           back_g, 65535, P_LINEAR);
+                            back_g, 65535, P_LINEAR);
                      }
 
                      /* The background passed to libpng, however, must be the
@@ -2291,8 +2305,8 @@
                       * doesn't.
                       */
                      png_set_background_fixed(png_ptr, &c,
-                        PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                        0/*gamma: not used*/);
+                         PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                         0/*gamma: not used*/);
 
                      output_processing = PNG_CMAP_NONE;
                      break;
@@ -2322,7 +2336,7 @@
                 * background color at full precision.
                 */
                png_create_colormap_entry(display, 254, back_r, back_g, back_b,
-                  back_alpha, output_encoding);
+                   back_alpha, output_encoding);
             }
 
             else
@@ -2348,7 +2362,7 @@
             if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
                png_error(png_ptr, "gray+alpha color-map: too few entries");
 
-            cmap_entries = make_ga_colormap(display);
+            cmap_entries = (unsigned int)make_ga_colormap(display);
 
             background_index = PNG_CMAP_GA_BACKGROUND;
             output_processing = PNG_CMAP_GA;
@@ -2382,7 +2396,7 @@
                if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
                   png_error(png_ptr, "gray-alpha color-map: too few entries");
 
-               cmap_entries = make_gray_colormap(display);
+               cmap_entries = (unsigned int)make_gray_colormap(display);
 
                if (output_encoding == P_LINEAR)
                {
@@ -2390,7 +2404,7 @@
 
                   /* And make sure the corresponding palette entry matches. */
                   png_create_colormap_entry(display, gray, back_g, back_g,
-                     back_g, 65535, P_LINEAR);
+                      back_g, 65535, P_LINEAR);
                }
 
                /* The background passed to libpng, however, must be the sRGB
@@ -2400,8 +2414,8 @@
                c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
 
                png_set_background_fixed(png_ptr, &c,
-                  PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                  0/*gamma: not used*/);
+                   PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                   0/*gamma: not used*/);
 
                output_processing = PNG_CMAP_NONE;
             }
@@ -2421,7 +2435,7 @@
                {
                   png_uint_32 gray = (i * 256 + 115) / 231;
                   png_create_colormap_entry(display, i++, gray, gray, gray,
-                     255, P_sRGB);
+                      255, P_sRGB);
                }
 
                /* NOTE: this preserves the full precision of the application
@@ -2430,13 +2444,13 @@
                background_index = i;
                png_create_colormap_entry(display, i++, back_r, back_g, back_b,
 #ifdef __COVERITY__
-                 /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)
-                  * here.
-                  */ 255U,
+                   /* Coverity claims that output_encoding
+                    * cannot be 2 (P_LINEAR) here.
+                    */ 255U,
 #else
-                  output_encoding == P_LINEAR ? 65535U : 255U,
+                    output_encoding == P_LINEAR ? 65535U : 255U,
 #endif
-                  output_encoding);
+                    output_encoding);
 
                /* For non-opaque input composite on the sRGB background - this
                 * requires inverting the encoding for each component.  The input
@@ -2474,9 +2488,9 @@
                      png_uint_32 gray = png_sRGB_table[g*51] * alpha;
 
                      png_create_colormap_entry(display, i++,
-                        PNG_sRGB_FROM_LINEAR(gray + back_rx),
-                        PNG_sRGB_FROM_LINEAR(gray + back_gx),
-                        PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
+                         PNG_sRGB_FROM_LINEAR(gray + back_rx),
+                         PNG_sRGB_FROM_LINEAR(gray + back_gx),
+                         PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
                   }
                }
 
@@ -2502,7 +2516,7 @@
              * png_set_tRNS_to_alpha before png_set_background_fixed.
              */
             png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,
-               -1);
+                -1);
             data_encoding = P_sRGB;
 
             /* The output will now be one or two 8-bit gray or gray+alpha
@@ -2521,7 +2535,7 @@
                if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
                   png_error(png_ptr, "rgb[ga] color-map: too few entries");
 
-               cmap_entries = make_ga_colormap(display);
+               cmap_entries = (unsigned int)make_ga_colormap(display);
                background_index = PNG_CMAP_GA_BACKGROUND;
                output_processing = PNG_CMAP_GA;
             }
@@ -2547,12 +2561,12 @@
                   png_ptr->num_trans > 0) &&
                   png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0)
                {
-                  cmap_entries = make_gray_file_colormap(display);
+                  cmap_entries = (unsigned int)make_gray_file_colormap(display);
                   data_encoding = P_FILE;
                }
 
                else
-                  cmap_entries = make_gray_colormap(display);
+                  cmap_entries = (unsigned int)make_gray_colormap(display);
 
                /* But if the input has alpha or transparency it must be removed
                 */
@@ -2578,13 +2592,13 @@
                         gray = png_sRGB_table[gray]; /* now P_LINEAR */
 
                      gray = PNG_DIV257(png_gamma_16bit_correct(gray,
-                        png_ptr->colorspace.gamma)); /* now P_FILE */
+                         png_ptr->colorspace.gamma)); /* now P_FILE */
 
                      /* And make sure the corresponding palette entry contains
                       * exactly the required sRGB value.
                       */
                      png_create_colormap_entry(display, gray, back_g, back_g,
-                        back_g, 0/*unused*/, output_encoding);
+                         back_g, 0/*unused*/, output_encoding);
                   }
 
                   else if (output_encoding == P_LINEAR)
@@ -2609,8 +2623,8 @@
                    */
                   expand_tRNS = 1;
                   png_set_background_fixed(png_ptr, &c,
-                     PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                     0/*gamma: not used*/);
+                      PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                      0/*gamma: not used*/);
                }
 
                output_processing = PNG_CMAP_NONE;
@@ -2640,11 +2654,11 @@
                   if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
                      png_error(png_ptr, "rgb+alpha color-map: too few entries");
 
-                  cmap_entries = make_rgb_colormap(display);
+                  cmap_entries = (unsigned int)make_rgb_colormap(display);
 
                   /* Add a transparent entry. */
                   png_create_colormap_entry(display, cmap_entries, 255, 255,
-                     255, 0, P_sRGB);
+                      255, 0, P_sRGB);
 
                   /* This is stored as the background index for the processing
                    * algorithm.
@@ -2665,7 +2679,7 @@
                          */
                         for (b=0; b<256; b = (b << 1) | 0x7f)
                            png_create_colormap_entry(display, cmap_entries++,
-                              r, g, b, 128, P_sRGB);
+                               r, g, b, 128, P_sRGB);
                      }
                   }
 
@@ -2689,10 +2703,10 @@
                   if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
                      png_error(png_ptr, "rgb-alpha color-map: too few entries");
 
-                  cmap_entries = make_rgb_colormap(display);
+                  cmap_entries = (unsigned int)make_rgb_colormap(display);
 
                   png_create_colormap_entry(display, cmap_entries, back_r,
-                        back_g, back_b, 0/*unused*/, output_encoding);
+                      back_g, back_b, 0/*unused*/, output_encoding);
 
                   if (output_encoding == P_LINEAR)
                   {
@@ -2714,9 +2728,9 @@
                    * index.
                    */
                   if (memcmp((png_const_bytep)display->colormap +
-                        sample_size * cmap_entries,
-                     (png_const_bytep)display->colormap +
-                        sample_size * PNG_RGB_INDEX(r,g,b),
+                      sample_size * cmap_entries,
+                      (png_const_bytep)display->colormap +
+                          sample_size * PNG_RGB_INDEX(r,g,b),
                      sample_size) != 0)
                   {
                      /* The background color must be added. */
@@ -2734,13 +2748,13 @@
                             */
                            for (b=0; b<256; b = (b << 1) | 0x7f)
                               png_create_colormap_entry(display, cmap_entries++,
-                                 png_colormap_compose(display, r, P_sRGB, 128,
-                                    back_r, output_encoding),
-                                 png_colormap_compose(display, g, P_sRGB, 128,
-                                    back_g, output_encoding),
-                                 png_colormap_compose(display, b, P_sRGB, 128,
-                                    back_b, output_encoding),
-                                 0/*unused*/, output_encoding);
+                                  png_colormap_compose(display, r, P_sRGB, 128,
+                                      back_r, output_encoding),
+                                  png_colormap_compose(display, g, P_sRGB, 128,
+                                      back_g, output_encoding),
+                                  png_colormap_compose(display, b, P_sRGB, 128,
+                                      back_b, output_encoding),
+                                  0/*unused*/, output_encoding);
                         }
                      }
 
@@ -2758,8 +2772,8 @@
                      c.blue = (png_uint_16)back_b;
 
                      png_set_background_fixed(png_ptr, &c,
-                        PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                        0/*gamma: not used*/);
+                         PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                         0/*gamma: not used*/);
 
                      output_processing = PNG_CMAP_RGB;
                   }
@@ -2774,7 +2788,7 @@
                if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries)
                   png_error(png_ptr, "rgb color-map: too few entries");
 
-               cmap_entries = make_rgb_colormap(display);
+               cmap_entries = (unsigned int)make_rgb_colormap(display);
                output_processing = PNG_CMAP_RGB;
             }
          }
@@ -2798,11 +2812,11 @@
 
             output_processing = PNG_CMAP_NONE;
             data_encoding = P_FILE; /* Don't change from color-map indices */
-            cmap_entries = png_ptr->num_palette;
+            cmap_entries = (unsigned int)png_ptr->num_palette;
             if (cmap_entries > 256)
                cmap_entries = 256;
 
-            if (cmap_entries > image->colormap_entries)
+            if (cmap_entries > (unsigned int)image->colormap_entries)
                png_error(png_ptr, "palette color-map: too few entries");
 
             for (i=0; i < cmap_entries; ++i)
@@ -2811,7 +2825,7 @@
                {
                   if (trans[i] == 0)
                      png_create_colormap_entry(display, i, back_r, back_g,
-                        back_b, 0, output_encoding);
+                         back_b, 0, output_encoding);
 
                   else
                   {
@@ -2819,22 +2833,22 @@
                       * on the sRGB color in 'back'.
                       */
                      png_create_colormap_entry(display, i,
-                        png_colormap_compose(display, colormap[i].red, P_FILE,
-                           trans[i], back_r, output_encoding),
-                        png_colormap_compose(display, colormap[i].green, P_FILE,
-                           trans[i], back_g, output_encoding),
-                        png_colormap_compose(display, colormap[i].blue, P_FILE,
-                           trans[i], back_b, output_encoding),
-                        output_encoding == P_LINEAR ? trans[i] * 257U :
-                           trans[i],
-                        output_encoding);
+                         png_colormap_compose(display, colormap[i].red,
+                             P_FILE, trans[i], back_r, output_encoding),
+                         png_colormap_compose(display, colormap[i].green,
+                             P_FILE, trans[i], back_g, output_encoding),
+                         png_colormap_compose(display, colormap[i].blue,
+                             P_FILE, trans[i], back_b, output_encoding),
+                         output_encoding == P_LINEAR ? trans[i] * 257U :
+                             trans[i],
+                         output_encoding);
                   }
                }
 
                else
                   png_create_colormap_entry(display, i, colormap[i].red,
-                     colormap[i].green, colormap[i].blue,
-                     i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
+                      colormap[i].green, colormap[i].blue,
+                      i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
             }
 
             /* The PNG data may have indices packed in fewer than 8 bits, it
@@ -2860,7 +2874,7 @@
       case P_sRGB:
          /* Change to 8-bit sRGB */
          png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);
-         /* FALL THROUGH */
+         /* FALLTHROUGH */
 
       case P_FILE:
          if (png_ptr->bit_depth > 8)
@@ -2914,7 +2928,7 @@
          png_error(png_ptr, "bad background index (internal error)");
    }
 
-   display->colormap_processing = output_processing;
+   display->colormap_processing = (int)output_processing;
 
    return 1/*ok*/;
 }
@@ -2924,7 +2938,7 @@
 png_image_read_and_map(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    int passes;
@@ -3061,7 +3075,7 @@
 
                      if (alpha >= 196)
                         *outrow = PNG_RGB_INDEX(inrow[0], inrow[1],
-                           inrow[2]);
+                            inrow[2]);
 
                      else if (alpha < 64)
                         *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND;
@@ -3113,7 +3127,7 @@
 png_image_read_colormapped(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_controlp control = image->opaque;
    png_structrp png_ptr = control->png_ptr;
@@ -3178,8 +3192,7 @@
             image->colormap_entries == 244 /* 216 + 1 + 27 */)
             break;
 
-         /* goto bad_output; */
-         /* FALL THROUGH */
+         goto bad_output;
 
       default:
       bad_output:
@@ -3223,14 +3236,14 @@
 
    else
    {
-      png_alloc_size_t row_bytes = display->row_bytes;
+      png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes;
 
       while (--passes >= 0)
       {
          png_uint_32      y = image->height;
          png_bytep        row = png_voidcast(png_bytep, display->first_row);
 
-         while (y-- > 0)
+         for (; y > 0; --y)
          {
             png_read_row(png_ptr, row, NULL);
             row += row_bytes;
@@ -3246,7 +3259,7 @@
 png_image_read_composite(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    int passes;
@@ -3373,7 +3386,7 @@
 png_image_read_background(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    png_inforp info_ptr = image->opaque->info_ptr;
@@ -3433,8 +3446,7 @@
 
             for (pass = 0; pass < passes; ++pass)
             {
-               png_bytep        row = png_voidcast(png_bytep,
-                                                   display->first_row);
+               png_bytep row = png_voidcast(png_bytep, display->first_row);
                unsigned int     startx, stepx, stepy;
                png_uint_32      y;
 
@@ -3462,7 +3474,7 @@
                   for (; y<height; y += stepy)
                   {
                      png_bytep inrow = png_voidcast(png_bytep,
-                        display->local_row);
+                         display->local_row);
                      png_bytep outrow = first_row + y * step_row;
                      png_const_bytep end_row = outrow + width;
 
@@ -3507,7 +3519,7 @@
                   for (; y<height; y += stepy)
                   {
                      png_bytep inrow = png_voidcast(png_bytep,
-                        display->local_row);
+                         display->local_row);
                      png_bytep outrow = first_row + y * step_row;
                      png_const_bytep end_row = outrow + width;
 
@@ -3554,13 +3566,14 @@
           */
          {
             png_uint_16p first_row = png_voidcast(png_uint_16p,
-               display->first_row);
+                display->first_row);
             /* The division by two is safe because the caller passed in a
              * stride which was multiplied by 2 (below) to get row_bytes.
              */
             ptrdiff_t    step_row = display->row_bytes / 2;
-            int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
-            unsigned int outchannels = 1+preserve_alpha;
+            unsigned int preserve_alpha = (image->format &
+                PNG_FORMAT_FLAG_ALPHA) != 0;
+            unsigned int outchannels = 1U+preserve_alpha;
             int swap_alpha = 0;
 
 #           ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
@@ -3604,7 +3617,7 @@
 
                   /* Read the row, which is packed: */
                   png_read_row(png_ptr, png_voidcast(png_bytep,
-                     display->local_row), NULL);
+                      display->local_row), NULL);
                   inrow = png_voidcast(png_const_uint_16p, display->local_row);
 
                   /* Now do the pre-multiplication on each pixel in this row.
@@ -3653,7 +3666,7 @@
 png_image_read_direct(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    png_inforp info_ptr = image->opaque->info_ptr;
@@ -3704,7 +3717,7 @@
                do_local_background = 1/*maybe*/;
 
             png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE,
-               PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
+                PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
          }
 
          change &= ~PNG_FORMAT_FLAG_COLOR;
@@ -3746,7 +3759,13 @@
          mode = PNG_ALPHA_PNG;
          output_gamma = PNG_DEFAULT_sRGB;
       }
-
+      
+      if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0)
+      {
+         mode = PNG_ALPHA_OPTIMIZED;
+         change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
+      }
+      
       /* If 'do_local_background' is set check for the presence of gamma
        * correction; this is part of the work-round for the libpng bug
        * described above.
@@ -3763,7 +3782,7 @@
           * final value.
           */
          if (png_muldiv(&gtest, output_gamma, png_ptr->colorspace.gamma,
-               PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0)
+             PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0)
             do_local_background = 0;
 
          else if (mode == PNG_ALPHA_STANDARD)
@@ -3826,8 +3845,8 @@
                 * pixels.
                 */
                png_set_background_fixed(png_ptr, &c,
-                  PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                  0/*gamma: not used*/);
+                   PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                   0/*gamma: not used*/);
             }
 
             else /* compose on row: implemented below. */
@@ -3972,6 +3991,10 @@
       else if (do_local_compose != 0) /* internal error */
          png_error(png_ptr, "png_image_read: alpha channel lost");
 
+      if ((format & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) {
+         info_format |= PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
+      }
+
       if (info_ptr->bit_depth == 16)
          info_format |= PNG_FORMAT_FLAG_LINEAR;
 
@@ -4057,14 +4080,14 @@
 
    else
    {
-      png_alloc_size_t row_bytes = display->row_bytes;
+      png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes;
 
       while (--passes >= 0)
       {
          png_uint_32      y = image->height;
          png_bytep        row = png_voidcast(png_bytep, display->first_row);
 
-         while (y-- > 0)
+         for (; y > 0; --y)
          {
             png_read_row(png_ptr, row, NULL);
             row += row_bytes;
@@ -4077,7 +4100,7 @@
 
 int PNGAPI
 png_image_finish_read(png_imagep image, png_const_colorp background,
-   void *buffer, png_int_32 row_stride, void *colormap)
+    void *buffer, png_int_32 row_stride, void *colormap)
 {
    if (image != NULL && image->version == PNG_IMAGE_VERSION)
    {
@@ -4087,7 +4110,13 @@
        */
       const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
 
-      if (image->width <= 0x7FFFFFFFU/channels) /* no overflow */
+      /* The following checks just the 'row_stride' calculation to ensure it
+       * fits in a signed 32-bit value.  Because channels/components can be
+       * either 1 or 2 bytes in size the length of a row can still overflow 32
+       * bits; this is just to verify that the 'row_stride' argument can be
+       * represented.
+       */
+      if (image->width <= 0x7fffffffU/channels) /* no overflow */
       {
          png_uint_32 check;
          const png_uint_32 png_row_stride = image->width * channels;
@@ -4096,18 +4125,35 @@
             row_stride = (png_int_32)/*SAFE*/png_row_stride;
 
          if (row_stride < 0)
-            check = -row_stride;
+            check = (png_uint_32)(-row_stride);
 
          else
-            check = row_stride;
+            check = (png_uint_32)row_stride;
 
+         /* This verifies 'check', the absolute value of the actual stride
+          * passed in and detects overflow in the application calculation (i.e.
+          * if the app did actually pass in a non-zero 'row_stride'.
+          */
          if (image->opaque != NULL && buffer != NULL && check >= png_row_stride)
          {
             /* Now check for overflow of the image buffer calculation; this
              * limits the whole image size to 32 bits for API compatibility with
              * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
+             *
+             * The PNG_IMAGE_BUFFER_SIZE macro is:
+             *
+             *    (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride))
+             *
+             * And the component size is always 1 or 2, so make sure that the
+             * number of *bytes* that the application is saying are available
+             * does actually fit into a 32-bit number.
+             *
+             * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE
+             * will be changed to use png_alloc_size_t; bigger images can be
+             * accomodated on 64-bit systems.
              */
-            if (image->height <= 0xFFFFFFFF/png_row_stride)
+            if (image->height <=
+                0xffffffffU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check)
             {
                if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
                   (image->colormap_entries > 0 && colormap != NULL))
@@ -4127,15 +4173,16 @@
                    * all the setup has already been done.
                    */
                   if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
-                     result = png_safe_execute(image,
-                                    png_image_read_colormap, &display) &&
-                              png_safe_execute(image,
-                                    png_image_read_colormapped, &display);
+                     result =
+                         png_safe_execute(image,
+                             png_image_read_colormap, &display) &&
+                             png_safe_execute(image,
+                             png_image_read_colormapped, &display);
 
                   else
                      result =
                         png_safe_execute(image,
-                              png_image_read_direct, &display);
+                            png_image_read_direct, &display);
 
                   png_image_free(image);
                   return result;
@@ -4143,27 +4190,27 @@
 
                else
                   return png_image_error(image,
-                     "png_image_finish_read[color-map]: no color-map");
+                      "png_image_finish_read[color-map]: no color-map");
             }
 
             else
                return png_image_error(image,
-                  "png_image_finish_read: image too large");
+                   "png_image_finish_read: image too large");
          }
 
          else
             return png_image_error(image,
-               "png_image_finish_read: invalid argument");
+                "png_image_finish_read: invalid argument");
       }
 
       else
          return png_image_error(image,
-            "png_image_finish_read: row_stride too large");
+             "png_image_finish_read: row_stride too large");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_finish_read: damaged PNG_IMAGE_VERSION");
+          "png_image_finish_read: damaged PNG_IMAGE_VERSION");
 
    return 0;
 }
diff --git a/third_party/libpng/pngrio.c b/third_party/libpng/pngrio.c
index 5101d54..7e26e855 100644
--- a/third_party/libpng/pngrio.c
+++ b/third_party/libpng/pngrio.c
@@ -1,8 +1,8 @@
 
 /* pngrio.c - functions for data input
  *
- * Last changed in libpng 1.6.17 [March 26, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -85,7 +85,7 @@
  */
 void PNGAPI
 png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
-   png_rw_ptr read_data_fn)
+    png_rw_ptr read_data_fn)
 {
    if (png_ptr == NULL)
       return;
diff --git a/third_party/libpng/pngrtran.c b/third_party/libpng/pngrtran.c
index 3138147..9dd82c9 100644
--- a/third_party/libpng/pngrtran.c
+++ b/third_party/libpng/pngrtran.c
@@ -1,8 +1,8 @@
 
 /* pngrtran.c - transforms the data in a row for PNG readers
  *
- * Last changed in libpng 1.6.22 [May 26, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -18,6 +18,13 @@
 
 #include "pngpriv.h"
 
+#ifdef PNG_ARM_NEON_IMPLEMENTATION
+#if PNG_ARM_NEON_IMPLEMENTATION == 1
+#define PNG_ARM_NEON_INTRINSICS_AVAILABLE
+#include <arm_neon.h>
+#endif
+#endif
+
 #ifdef PNG_READ_SUPPORTED
 
 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
@@ -48,7 +55,8 @@
 
       case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */
          png_warning(png_ptr,
-            "Can't discard critical data on CRC error");
+             "Can't discard critical data on CRC error");
+         /* FALLTHROUGH */
       case PNG_CRC_ERROR_QUIT:                                /* Error/quit */
 
       case PNG_CRC_DEFAULT:
@@ -101,7 +109,7 @@
    {
       if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
          png_app_error(png_ptr,
-            "invalid after png_start_read_image or png_read_update_info");
+             "invalid after png_start_read_image or png_read_update_info");
 
       else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)
          png_app_error(png_ptr, "invalid before the PNG header has been read");
@@ -209,7 +217,7 @@
 #if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
 static png_fixed_point
 translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
-   int is_screen)
+    int is_screen)
 {
    /* Check for flag values.  The main reason for having the old Mac value as a
     * flag is that it is pretty near impossible to work out what the correct
@@ -273,7 +281,7 @@
 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
 void PNGFAPI
 png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
-   png_fixed_point output_gamma)
+    png_fixed_point output_gamma)
 {
    int compose = 0;
    png_fixed_point file_gamma;
@@ -377,7 +385,7 @@
 
       if ((png_ptr->transformations & PNG_COMPOSE) != 0)
          png_error(png_ptr,
-            "conflicting calls to set alpha mode and background");
+             "conflicting calls to set alpha mode and background");
 
       png_ptr->transformations |= PNG_COMPOSE;
    }
@@ -388,7 +396,7 @@
 png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
 {
    png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
-      output_gamma));
+       output_gamma));
 }
 #  endif
 #endif
@@ -429,7 +437,7 @@
       int i;
 
       png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
-          (png_uint_32)(num_palette * (sizeof (png_byte))));
+          (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
       for (i = 0; i < num_palette; i++)
          png_ptr->quantize_index[i] = (png_byte)i;
    }
@@ -446,7 +454,7 @@
 
          /* Initialize an array to sort colors */
          png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)(num_palette * (sizeof (png_byte))));
+             (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
 
          /* Initialize the quantize_sort array */
          for (i = 0; i < num_palette; i++)
@@ -580,9 +588,11 @@
 
          /* Initialize palette index arrays */
          png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)(num_palette * (sizeof (png_byte))));
+             (png_alloc_size_t)((png_uint_32)num_palette *
+             (sizeof (png_byte))));
          png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)(num_palette * (sizeof (png_byte))));
+             (png_alloc_size_t)((png_uint_32)num_palette *
+             (sizeof (png_byte))));
 
          /* Initialize the sort array */
          for (i = 0; i < num_palette; i++)
@@ -591,7 +601,7 @@
             png_ptr->palette_to_index[i] = (png_byte)i;
          }
 
-         hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
+         hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 *
              (sizeof (png_dsortp))));
 
          num_new_palette = num_palette;
@@ -622,7 +632,7 @@
                   {
 
                      t = (png_dsortp)png_malloc_warn(png_ptr,
-                         (png_uint_32)(sizeof (png_dsort)));
+                         (png_alloc_size_t)(sizeof (png_dsort)));
 
                      if (t == NULL)
                          break;
@@ -747,9 +757,9 @@
       png_size_t num_entries = ((png_size_t)1 << total_bits);
 
       png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
-          (png_uint_32)(num_entries * (sizeof (png_byte))));
+          (png_alloc_size_t)(num_entries * (sizeof (png_byte))));
 
-      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
+      distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries *
           (sizeof (png_byte))));
 
       memset(distance, 0xff, num_entries * (sizeof (png_byte)));
@@ -802,7 +812,7 @@
 #ifdef PNG_READ_GAMMA_SUPPORTED
 void PNGFAPI
 png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
-   png_fixed_point file_gamma)
+    png_fixed_point file_gamma)
 {
    png_debug(1, "in png_set_gamma_fixed");
 
@@ -844,7 +854,7 @@
 png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
 {
    png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
-      convert_gamma_value(png_ptr, file_gamma));
+       convert_gamma_value(png_ptr, file_gamma));
 }
 #  endif /* FLOATING_POINT */
 #endif /* READ_GAMMA */
@@ -990,7 +1000,7 @@
        * that it just worked and get a memory overwrite.
        */
       png_error(png_ptr,
-        "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
+          "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
 
       /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */
    }
@@ -1017,7 +1027,7 @@
       {
          if (red >= 0 && green >= 0)
             png_app_warning(png_ptr,
-               "ignoring out of range rgb_to_gray coefficients");
+                "ignoring out of range rgb_to_gray coefficients");
 
          /* Use the defaults, from the cHRM chunk if set, else the historical
           * values which are close to the sRGB/HDTV/ITU-Rec 709 values.  See
@@ -1026,7 +1036,7 @@
           * something has already provided a default.
           */
          if (png_ptr->rgb_to_gray_red_coeff == 0 &&
-            png_ptr->rgb_to_gray_green_coeff == 0)
+             png_ptr->rgb_to_gray_green_coeff == 0)
          {
             png_ptr->rgb_to_gray_red_coeff   = 6968;
             png_ptr->rgb_to_gray_green_coeff = 23434;
@@ -1043,10 +1053,10 @@
 
 void PNGAPI
 png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
-   double green)
+    double green)
 {
    png_set_rgb_to_gray_fixed(png_ptr, error_action,
-      png_fixed(png_ptr, red, "rgb to gray red coefficient"),
+       png_fixed(png_ptr, red, "rgb to gray red coefficient"),
       png_fixed(png_ptr, green, "rgb to gray green coefficient"));
 }
 #endif /* FLOATING POINT */
@@ -1253,7 +1263,7 @@
             default:
 
             case 8:
-               /* FALL THROUGH (Already 8 bits) */
+               /* FALLTHROUGH */ /*  (Already 8 bits) */
 
             case 16:
                /* Already a full 16 bits */
@@ -1303,7 +1313,7 @@
       {
          if (png_ptr->screen_gamma != 0) /* screen set too */
             gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
-               png_ptr->screen_gamma);
+                png_ptr->screen_gamma);
 
          else
             /* Assume the output matches the input; a long time default behavior
@@ -1584,7 +1594,7 @@
           */
          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
             png_warning(png_ptr,
-               "libpng does not support gamma+background+rgb_to_gray");
+                "libpng does not support gamma+background+rgb_to_gray");
 
          if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0)
          {
@@ -1620,13 +1630,13 @@
                   case PNG_BACKGROUND_GAMMA_FILE:
                      g = png_reciprocal(png_ptr->colorspace.gamma);
                      gs = png_reciprocal2(png_ptr->colorspace.gamma,
-                        png_ptr->screen_gamma);
+                         png_ptr->screen_gamma);
                      break;
 
                   case PNG_BACKGROUND_GAMMA_UNIQUE:
                      g = png_reciprocal(png_ptr->background_gamma);
                      gs = png_reciprocal2(png_ptr->background_gamma,
-                        png_ptr->screen_gamma);
+                         png_ptr->screen_gamma);
                      break;
                   default:
                      g = PNG_FP_1;    /* back_1 */
@@ -1654,11 +1664,11 @@
                if (png_gamma_significant(g) != 0)
                {
                   back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
-                     g);
+                      g);
                   back_1.green = png_gamma_8bit_correct(
-                     png_ptr->background.green, g);
+                      png_ptr->background.green, g);
                   back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
-                     g);
+                      g);
                }
 
                else
@@ -1729,7 +1739,7 @@
                case PNG_BACKGROUND_GAMMA_FILE:
                   g = png_reciprocal(png_ptr->colorspace.gamma);
                   gs = png_reciprocal2(png_ptr->colorspace.gamma,
-                     png_ptr->screen_gamma);
+                      png_ptr->screen_gamma);
                   break;
 
                case PNG_BACKGROUND_GAMMA_UNIQUE:
@@ -2150,7 +2160,7 @@
          {
             png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
             png_bytep dp = row + (png_size_t)row_width - 1;
-            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
+            png_uint_32 shift = 7U - ((row_width + 7U) & 0x07);
             for (i = 0; i < row_width; i++)
             {
                *dp = (png_byte)((*sp >> shift) & 0x01);
@@ -2174,7 +2184,7 @@
 
             png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
             png_bytep dp = row + (png_size_t)row_width - 1;
-            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+            png_uint_32 shift = ((3U - ((row_width + 3U) & 0x03)) << 1);
             for (i = 0; i < row_width; i++)
             {
                *dp = (png_byte)((*sp >> shift) & 0x03);
@@ -2197,7 +2207,7 @@
          {
             png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
             png_bytep dp = row + (png_size_t)row_width - 1;
-            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+            png_uint_32 shift = ((1U - ((row_width + 1U) & 0x01)) << 2);
             for (i = 0; i < row_width; i++)
             {
                *dp = (png_byte)((*sp >> shift) & 0x0f);
@@ -2934,7 +2944,7 @@
  * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
  * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008 but
  * versions dated 1998 through November 2002 have been archived at
- * http://web.archive.org/web/20000816232553/http://www.inforamp.net/
+ * https://web.archive.org/web/20000816232553/www.inforamp.net/
  * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
  * Charles Poynton poynton at poynton.com
  *
@@ -3223,7 +3233,8 @@
                         == png_ptr->trans_color.gray)
                      {
                         unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
-                        tmp |= png_ptr->background.gray << shift;
+                        tmp |=
+                            (unsigned int)(png_ptr->background.gray << shift);
                         *sp = (png_byte)(tmp & 0xff);
                      }
 
@@ -3252,7 +3263,8 @@
                             == png_ptr->trans_color.gray)
                         {
                            unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
-                           tmp |= png_ptr->background.gray << shift;
+                           tmp |=
+                              (unsigned int)png_ptr->background.gray << shift;
                            *sp = (png_byte)(tmp & 0xff);
                         }
 
@@ -3262,7 +3274,7 @@
                            unsigned int g = (gamma_table [p | (p << 2) |
                                (p << 4) | (p << 6)] >> 6) & 0x03;
                            unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
-                           tmp |= g << shift;
+                           tmp |= (unsigned int)(g << shift);
                            *sp = (png_byte)(tmp & 0xff);
                         }
 
@@ -3288,7 +3300,8 @@
                             == png_ptr->trans_color.gray)
                         {
                            unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
-                           tmp |= png_ptr->background.gray << shift;
+                           tmp |=
+                               (unsigned int)png_ptr->background.gray << shift;
                            *sp = (png_byte)(tmp & 0xff);
                         }
 
@@ -3318,7 +3331,8 @@
                             == png_ptr->trans_color.gray)
                         {
                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
-                           tmp |= png_ptr->background.gray << shift;
+                           tmp |=
+                              (unsigned int)(png_ptr->background.gray << shift);
                            *sp = (png_byte)(tmp & 0xff);
                         }
 
@@ -3328,7 +3342,7 @@
                            unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
                               0x0f;
                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
-                           tmp |= g << shift;
+                           tmp |= (unsigned int)(g << shift);
                            *sp = (png_byte)(tmp & 0xff);
                         }
 
@@ -3354,7 +3368,8 @@
                             == png_ptr->trans_color.gray)
                         {
                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
-                           tmp |= png_ptr->background.gray << shift;
+                           tmp |=
+                              (unsigned int)(png_ptr->background.gray << shift);
                            *sp = (png_byte)(tmp & 0xff);
                         }
 
@@ -4194,8 +4209,9 @@
  * upon whether you supply trans and num_trans.
  */
 static void
-png_do_expand_palette(png_row_infop row_info, png_bytep row,
-   png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
+png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
+   png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha,
+   int num_trans)
 {
    int shift, value;
    png_bytep sp, dp;
@@ -4297,16 +4313,24 @@
             if (num_trans > 0)
             {
                sp = row + (png_size_t)row_width - 1;
-               dp = row + (png_size_t)(row_width << 2) - 1;
+               dp = row + ((png_size_t)row_width << 2) - 1;
 
-               for (i = 0; i < row_width; i++)
+               i = 0;
+#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
+               if (png_ptr->riffled_palette != NULL) {
+                  /* The RGBA optimization works with png_ptr->bit_depth == 8
+                     but sometimes row_info->bit_depth has been changed to 8.
+                     In these cases, the palette hasn't been riffled. */
+                  i = png_do_expand_palette_neon_rgba(png_ptr, row_info, row, &sp, &dp);
+               }
+#endif
+
+               for (; i < row_width; i++)
                {
                   if ((int)(*sp) >= num_trans)
                      *dp-- = 0xff;
-
                   else
                      *dp-- = trans_alpha[*sp];
-
                   *dp-- = palette[*sp].blue;
                   *dp-- = palette[*sp].green;
                   *dp-- = palette[*sp].red;
@@ -4323,8 +4347,12 @@
             {
                sp = row + (png_size_t)row_width - 1;
                dp = row + (png_size_t)(row_width * 3) - 1;
+               i = 0;
+#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
+               i = png_do_expand_palette_neon_rgb(png_ptr, row_info, row, &sp, &dp);
+#endif
 
-               for (i = 0; i < row_width; i++)
+               for (; i < row_width; i++)
                {
                   *dp-- = palette[*sp].blue;
                   *dp-- = palette[*sp].green;
@@ -4458,7 +4486,7 @@
             {
                gray = gray & 0xff;
                sp = row + (png_size_t)row_width - 1;
-               dp = row + (png_size_t)(row_width << 1) - 1;
+               dp = row + ((png_size_t)row_width << 1) - 1;
 
                for (i = 0; i < row_width; i++)
                {
@@ -4502,7 +4530,7 @@
             row_info->channels = 2;
             row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
             row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
-               row_width);
+                row_width);
          }
       }
       else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
@@ -4514,7 +4542,7 @@
             png_byte green = (png_byte)(trans_color->green & 0xff);
             png_byte blue = (png_byte)(trans_color->blue & 0xff);
             sp = row + (png_size_t)row_info->rowbytes - 1;
-            dp = row + (png_size_t)(row_width << 2) - 1;
+            dp = row + ((png_size_t)row_width << 2) - 1;
             for (i = 0; i < row_width; i++)
             {
                if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
@@ -4537,7 +4565,7 @@
             png_byte green_low = (png_byte)(trans_color->green & 0xff);
             png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
             sp = row + row_info->rowbytes - 1;
-            dp = row + (png_size_t)(row_width << 3) - 1;
+            dp = row + ((png_size_t)row_width << 3) - 1;
             for (i = 0; i < row_width; i++)
             {
                if (*(sp - 5) == red_high &&
@@ -4596,7 +4624,9 @@
       png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
       png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */
       while (dp > sp)
-         dp[-2] = dp[-1] = *--sp, dp -= 2;
+      {
+         dp[-2] = dp[-1] = *--sp; dp -= 2;
+      }
 
       row_info->rowbytes *= 2;
       row_info->bit_depth = 16;
@@ -4738,8 +4768,21 @@
    {
       if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
       {
-         png_do_expand_palette(row_info, png_ptr->row_buf + 1,
-             png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
+#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
+       if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8)) {
+          /* Allocate space for the decompressed full palette. */
+          if (png_ptr->riffled_palette == NULL) {
+              png_ptr->riffled_palette = png_malloc(png_ptr, 256*4);
+              if (png_ptr->riffled_palette == NULL) {
+                  png_error(png_ptr, "NULL row buffer");
+              }
+              /* Build the RGBA palette. */
+              png_riffle_palette_rgba(png_ptr, row_info);
+          }
+       }
+#endif
+         png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1,
+            png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
       }
 
       else
@@ -4762,7 +4805,7 @@
        (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
        row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
       png_do_strip_channel(row_info, png_ptr->row_buf + 1,
-         0 /* at_start == false, because SWAP_ALPHA happens later */);
+          0 /* at_start == false, because SWAP_ALPHA happens later */);
 #endif
 
 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
diff --git a/third_party/libpng/pngrutil.c b/third_party/libpng/pngrutil.c
index c9747fc..8692933 100644
--- a/third_party/libpng/pngrutil.c
+++ b/third_party/libpng/pngrutil.c
@@ -1,8 +1,8 @@
 
 /* pngrutil.c - utilities to read a PNG file
  *
- * Last changed in libpng 1.6.20 [December 3, 2014]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -86,11 +86,11 @@
 {
    png_uint_32 uval = png_get_uint_32(buf);
    if ((uval & 0x80000000) == 0) /* non-negative */
-      return uval;
+      return (png_int_32)uval;
 
    uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
    if ((uval & 0x80000000) == 0) /* no overflow */
-       return -(png_int_32)uval;
+      return -(png_int_32)uval;
    /* The following has to be safe; this function only gets called on PNG data
     * and if we get here that data is invalid.  0 is the most safe value and
     * if not then an attacker would surely just generate a PNG with 0 instead.
@@ -181,6 +181,9 @@
    /* Check to see if chunk name is valid. */
    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
 
+   /* Check for too-large chunk length */
+   png_check_chunk_length(png_ptr, length);
+
 #ifdef PNG_IO_STATE_SUPPORTED
    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
 #endif
@@ -311,6 +314,7 @@
 
       if (buffer != NULL)
       {
+         memset(buffer, 0, new_size); /* just in case */
          png_ptr->read_buffer = buffer;
          png_ptr->read_buffer_size = new_size;
       }
@@ -370,11 +374,10 @@
     */
    {
       int ret; /* zlib return code */
-#if PNG_ZLIB_VERNUM >= 0x1240
+#if ZLIB_VERNUM >= 0x1240
+      int window_bits = 0;
 
 # if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW)
-      int window_bits;
-
       if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) ==
           PNG_OPTION_ON)
       {
@@ -384,13 +387,11 @@
 
       else
       {
-         window_bits = 0;
          png_ptr->zstream_start = 1;
       }
-# else
-#   define window_bits 0
 # endif
-#endif
+
+#endif /* ZLIB_VERNUM >= 0x1240 */
 
       /* Set this for safety, just in case the previous owner left pointers to
        * memory allocations.
@@ -402,25 +403,32 @@
 
       if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
       {
-#if PNG_ZLIB_VERNUM < 0x1240
-         ret = inflateReset(&png_ptr->zstream);
-#else
+#if ZLIB_VERNUM >= 0x1240
          ret = inflateReset2(&png_ptr->zstream, window_bits);
+#else
+         ret = inflateReset(&png_ptr->zstream);
 #endif
       }
 
       else
       {
-#if PNG_ZLIB_VERNUM < 0x1240
-         ret = inflateInit(&png_ptr->zstream);
-#else
+#if ZLIB_VERNUM >= 0x1240
          ret = inflateInit2(&png_ptr->zstream, window_bits);
+#else
+         ret = inflateInit(&png_ptr->zstream);
 #endif
 
          if (ret == Z_OK)
             png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
       }
 
+#if ZLIB_VERNUM >= 0x1290 && \
+   defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32)
+      if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON)
+         /* Turn off validation of the ADLER32 checksum in IDAT chunks */
+         ret = inflateValidate(&png_ptr->zstream, 0);
+#endif
+
       if (ret == Z_OK)
          png_ptr->zowner = owner;
 
@@ -435,7 +443,7 @@
 #endif
 }
 
-#if PNG_ZLIB_VERNUM >= 0x1240
+#if ZLIB_VERNUM >= 0x1240
 /* Handle the start of the inflate stream if we called inflateInit2(strm,0);
  * in this case some zlib versions skip validation of the CINFO field and, in
  * certain circumstances, libpng may end up displaying an invalid image, in
@@ -461,6 +469,7 @@
 #endif /* Zlib >= 1.2.4 */
 
 #ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
+#if defined(PNG_READ_zTXt_SUPPORTED) || defined (PNG_READ_iTXt_SUPPORTED)
 /* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to
  * allow the caller to do multiple calls if required.  If the 'finish' flag is
  * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must
@@ -599,9 +608,9 @@
  */
 static int
 png_decompress_chunk(png_structrp png_ptr,
-   png_uint_32 chunklength, png_uint_32 prefix_size,
-   png_alloc_size_t *newlength /* must be initialized to the maximum! */,
-   int terminate /*add a '\0' to the end of the uncompressed data*/)
+    png_uint_32 chunklength, png_uint_32 prefix_size,
+    png_alloc_size_t *newlength /* must be initialized to the maximum! */,
+    int terminate /*add a '\0' to the end of the uncompressed data*/)
 {
    /* TODO: implement different limits for different types of chunk.
     *
@@ -638,8 +647,8 @@
          png_uint_32 lzsize = chunklength - prefix_size;
 
          ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
-            /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,
-            /* output: */ NULL, newlength);
+             /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,
+             /* output: */ NULL, newlength);
 
          if (ret == Z_STREAM_END)
          {
@@ -659,15 +668,17 @@
                 */
                png_alloc_size_t new_size = *newlength;
                png_alloc_size_t buffer_size = prefix_size + new_size +
-                  (terminate != 0);
+                   (terminate != 0);
                png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr,
-                  buffer_size));
+                   buffer_size));
 
                if (text != NULL)
                {
+                  memset(text, 0, buffer_size);
+
                   ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
-                     png_ptr->read_buffer + prefix_size, &lzsize,
-                     text + prefix_size, newlength);
+                      png_ptr->read_buffer + prefix_size, &lzsize,
+                      text + prefix_size, newlength);
 
                   if (ret == Z_STREAM_END)
                   {
@@ -712,7 +723,7 @@
                    * the extra space may otherwise be used as a Trojan Horse.
                    */
                   if (ret == Z_STREAM_END &&
-                     chunklength - prefix_size != lzsize)
+                      chunklength - prefix_size != lzsize)
                      png_chunk_benign_error(png_ptr, "extra compressed data");
                }
 
@@ -728,9 +739,7 @@
             {
                /* inflateReset failed, store the error message */
                png_zstream_error(png_ptr, ret);
-
-               if (ret == Z_STREAM_END)
-                  ret = PNG_UNEXPECTED_ZLIB_RETURN;
+               ret = PNG_UNEXPECTED_ZLIB_RETURN;
             }
          }
 
@@ -754,6 +763,7 @@
       return Z_MEM_ERROR;
    }
 }
+#endif /* READ_zTXt || READ_iTXt */
 #endif /* READ_COMPRESSED_TEXT */
 
 #ifdef PNG_READ_iCCP_SUPPORTED
@@ -762,8 +772,8 @@
  */
 static int
 png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
-   png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,
-   int finish)
+    png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,
+    int finish)
 {
    if (png_ptr->zowner == png_ptr->chunk_name)
    {
@@ -802,8 +812,8 @@
           * the available output is produced; this allows reading of truncated
           * streams.
           */
-         ret = PNG_INFLATE(png_ptr,
-            *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
+         ret = PNG_INFLATE(png_ptr, *chunk_bytes > 0 ?
+             Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
       }
       while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0));
 
@@ -821,7 +831,7 @@
       return Z_STREAM_ERROR;
    }
 }
-#endif
+#endif /* READ_iCCP */
 
 /* Read and check the IDHR chunk */
 
@@ -1009,7 +1019,7 @@
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 #endif
    {
-      png_crc_finish(png_ptr, (int) length - num * 3);
+      png_crc_finish(png_ptr, (png_uint_32) (length - (unsigned int)num * 3));
    }
 
 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
@@ -1292,7 +1302,7 @@
 
    png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
    (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy,
-      1/*prefer cHRM values*/);
+       1/*prefer cHRM values*/);
    png_colorspace_sync(png_ptr, info_ptr);
 }
 #endif
@@ -1371,11 +1381,13 @@
     * chunk is just ignored, so does not invalidate the color space.  An
     * alternative is to set the 'invalid' flags at the start of this routine
     * and only clear them in they were not set before and all the tests pass.
-    * The minimum 'deflate' stream is assumed to be just the 2 byte header and
-    * 4 byte checksum.  The keyword must be at least one character and there is
-    * a terminator (0) byte and the compression method.
     */
-   if (length < 9)
+
+   /* The keyword must be at least one character and there is a
+    * terminator (0) byte and the compression method byte, and the
+    * 'zlib' datastream is at least 11 bytes.
+    */
+   if (length < 14)
    {
       png_crc_finish(png_ptr, length);
       png_chunk_benign_error(png_ptr, "too short");
@@ -1407,6 +1419,16 @@
       png_crc_read(png_ptr, (png_bytep)keyword, read_length);
       length -= read_length;
 
+      /* The minimum 'zlib' stream is assumed to be just the 2 byte header,
+       * 5 bytes minimum 'deflate' stream, and the 4 byte checksum.
+       */
+      if (length < 11)
+      {
+         png_crc_finish(png_ptr, length);
+         png_chunk_benign_error(png_ptr, "too short");
+         return;
+      }
+
       keyword_length = 0;
       while (keyword_length < 80 && keyword_length < read_length &&
          keyword[keyword_length] != 0)
@@ -1425,15 +1447,15 @@
 
             if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK)
             {
-               Byte profile_header[132];
+               Byte profile_header[132]={0};
                Byte local_buffer[PNG_INFLATE_BUF_SIZE];
                png_alloc_size_t size = (sizeof profile_header);
 
                png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);
                png_ptr->zstream.avail_in = read_length;
                (void)png_inflate_read(png_ptr, local_buffer,
-                  (sizeof local_buffer), &length, profile_header, &size,
-                  0/*finish: don't, because the output is too small*/);
+                   (sizeof local_buffer), &length, profile_header, &size,
+                   0/*finish: don't, because the output is too small*/);
 
                if (size == 0)
                {
@@ -1443,35 +1465,35 @@
                      png_get_uint_32(profile_header);
 
                   if (png_icc_check_length(png_ptr, &png_ptr->colorspace,
-                     keyword, profile_length) != 0)
+                      keyword, profile_length) != 0)
                   {
                      /* The length is apparently ok, so we can check the 132
                       * byte header.
                       */
                      if (png_icc_check_header(png_ptr, &png_ptr->colorspace,
-                        keyword, profile_length, profile_header,
-                        png_ptr->color_type) != 0)
+                         keyword, profile_length, profile_header,
+                         png_ptr->color_type) != 0)
                      {
                         /* Now read the tag table; a variable size buffer is
                          * needed at this point, allocate one for the whole
                          * profile.  The header check has already validated
-                         * that none of these stuff will overflow.
+                         * that none of this stuff will overflow.
                          */
                         const png_uint_32 tag_count = png_get_uint_32(
-                           profile_header+128);
+                            profile_header+128);
                         png_bytep profile = png_read_buffer(png_ptr,
-                           profile_length, 2/*silent*/);
+                            profile_length, 2/*silent*/);
 
                         if (profile != NULL)
                         {
                            memcpy(profile, profile_header,
-                              (sizeof profile_header));
+                               (sizeof profile_header));
 
                            size = 12 * tag_count;
 
                            (void)png_inflate_read(png_ptr, local_buffer,
-                              (sizeof local_buffer), &length,
-                              profile + (sizeof profile_header), &size, 0);
+                               (sizeof local_buffer), &length,
+                               profile + (sizeof profile_header), &size, 0);
 
                            /* Still expect a buffer error because we expect
                             * there to be some tag data!
@@ -1479,22 +1501,22 @@
                            if (size == 0)
                            {
                               if (png_icc_check_tag_table(png_ptr,
-                                 &png_ptr->colorspace, keyword, profile_length,
-                                 profile) != 0)
+                                  &png_ptr->colorspace, keyword, profile_length,
+                                  profile) != 0)
                               {
                                  /* The profile has been validated for basic
                                   * security issues, so read the whole thing in.
                                   */
                                  size = profile_length - (sizeof profile_header)
-                                    - 12 * tag_count;
+                                     - 12 * tag_count;
 
                                  (void)png_inflate_read(png_ptr, local_buffer,
-                                    (sizeof local_buffer), &length,
-                                    profile + (sizeof profile_header) +
-                                    12 * tag_count, &size, 1/*finish*/);
+                                     (sizeof local_buffer), &length,
+                                     profile + (sizeof profile_header) +
+                                     12 * tag_count, &size, 1/*finish*/);
 
                                  if (length > 0 && !(png_ptr->flags &
-                                       PNG_FLAG_BENIGN_ERRORS_WARN))
+                                     PNG_FLAG_BENIGN_ERRORS_WARN))
                                     errmsg = "extra compressed data";
 
                                  /* But otherwise allow extra data: */
@@ -1506,34 +1528,34 @@
                                         * keep going.
                                         */
                                        png_chunk_warning(png_ptr,
-                                          "extra compressed data");
+                                           "extra compressed data");
                                     }
 
                                     png_crc_finish(png_ptr, length);
                                     finished = 1;
 
-#                                   ifdef PNG_sRGB_SUPPORTED
+# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
                                     /* Check for a match against sRGB */
                                     png_icc_set_sRGB(png_ptr,
-                                       &png_ptr->colorspace, profile,
-                                       png_ptr->zstream.adler);
-#                                   endif
+                                        &png_ptr->colorspace, profile,
+                                        png_ptr->zstream.adler);
+# endif
 
                                     /* Steal the profile for info_ptr. */
                                     if (info_ptr != NULL)
                                     {
                                        png_free_data(png_ptr, info_ptr,
-                                          PNG_FREE_ICCP, 0);
+                                           PNG_FREE_ICCP, 0);
 
                                        info_ptr->iccp_name = png_voidcast(char*,
-                                          png_malloc_base(png_ptr,
-                                          keyword_length+1));
+                                           png_malloc_base(png_ptr,
+                                           keyword_length+1));
                                        if (info_ptr->iccp_name != NULL)
                                        {
                                           memcpy(info_ptr->iccp_name, keyword,
-                                             keyword_length+1);
+                                              keyword_length+1);
                                           info_ptr->iccp_proflen =
-                                             profile_length;
+                                              profile_length;
                                           info_ptr->iccp_profile = profile;
                                           png_ptr->read_buffer = NULL; /*steal*/
                                           info_ptr->free_me |= PNG_FREE_ICCP;
@@ -1562,19 +1584,11 @@
                                        return;
                                     }
                                  }
-
-                                 else if (size > 0)
-                                    errmsg = "truncated";
-
-#ifndef __COVERITY__
-                                 else
+                                 if (errmsg == NULL)
                                     errmsg = png_ptr->zstream.msg;
-#endif
                               }
-
                               /* else png_icc_check_tag_table output an error */
                            }
-
                            else /* profile truncated */
                               errmsg = png_ptr->zstream.msg;
                         }
@@ -1715,13 +1729,13 @@
    data_length = length - (png_uint_32)(entry_start - buffer);
 
    /* Integrity-check the data length */
-   if ((data_length % entry_size) != 0)
+   if ((data_length % (unsigned int)entry_size) != 0)
    {
       png_warning(png_ptr, "sPLT chunk has bad length");
       return;
    }
 
-   dl = (png_int_32)(data_length / entry_size);
+   dl = (png_uint_32)(data_length / (unsigned int)entry_size);
    max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry));
 
    if (dl > max_dl)
@@ -1730,10 +1744,10 @@
       return;
    }
 
-   new_palette.nentries = (png_int_32)(data_length / entry_size);
+   new_palette.nentries = (png_int_32)(data_length / (unsigned int)entry_size);
 
-   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
-       png_ptr, new_palette.nentries * (sizeof (png_sPLT_entry)));
+   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
+       (png_alloc_size_t) new_palette.nentries * (sizeof (png_sPLT_entry)));
 
    if (new_palette.entries == NULL)
    {
@@ -2003,6 +2017,69 @@
 }
 #endif
 
+#ifdef PNG_READ_eXIf_SUPPORTED
+void /* PRIVATE */
+png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   unsigned int i;
+
+   png_debug(1, "in png_handle_eXIf");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   if (length < 2)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "too short");
+      return;
+   }
+
+   else if (info_ptr == NULL || (info_ptr->valid & PNG_INFO_eXIf) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "duplicate");
+      return;
+   }
+
+   info_ptr->free_me |= PNG_FREE_EXIF;
+
+   info_ptr->eXIf_buf = png_voidcast(png_bytep,
+             png_malloc_warn(png_ptr, length));
+
+   if (info_ptr->eXIf_buf == NULL)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of memory");
+      return;
+   }
+
+   for (i = 0; i < length; i++)
+   {
+      png_byte buf[1];
+      png_crc_read(png_ptr, buf, 1);
+      info_ptr->eXIf_buf[i] = buf[0];
+      if (i == 1 && buf[0] != 'M' && buf[0] != 'I'
+                 && info_ptr->eXIf_buf[0] != buf[0])
+      {
+         png_crc_finish(png_ptr, length);
+         png_chunk_benign_error(png_ptr, "incorrect byte-order specifier");
+         png_free(png_ptr, info_ptr->eXIf_buf);
+         info_ptr->eXIf_buf = NULL;
+         return;
+      }
+   }
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf);
+
+   png_free(png_ptr, info_ptr->eXIf_buf);
+   info_ptr->eXIf_buf = NULL;
+}
+#endif
+
 #ifdef PNG_READ_hIST_SUPPORTED
 void /* PRIVATE */
 png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
@@ -2270,7 +2347,7 @@
    }
 
    png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams,
-      (png_charp)units, params);
+       (png_charp)units, params);
 
    png_free(png_ptr, params);
 }
@@ -2313,7 +2390,7 @@
    }
 
    png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
-      length + 1);
+       length + 1);
 
    buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
 
@@ -2365,7 +2442,7 @@
       else
          /* This is the (only) success case. */
          png_set_sCAL_s(png_ptr, info_ptr, buffer[0],
-            (png_charp)buffer+1, (png_charp)buffer+heighti);
+             (png_charp)buffer+1, (png_charp)buffer+heighti);
    }
 }
 #endif
@@ -2465,8 +2542,8 @@
 
    if (buffer == NULL)
    {
-     png_chunk_benign_error(png_ptr, "out of memory");
-     return;
+      png_chunk_benign_error(png_ptr, "out of memory");
+      return;
    }
 
    png_crc_read(png_ptr, buffer, length);
@@ -2531,6 +2608,9 @@
    if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
       png_ptr->mode |= PNG_AFTER_IDAT;
 
+   /* Note, "length" is sufficient here; we won't be adding
+    * a null terminator later.
+    */
    buffer = png_read_buffer(png_ptr, length, 2/*silent*/);
 
    if (buffer == NULL)
@@ -2573,27 +2653,32 @@
        * and text chunks.
        */
       if (png_decompress_chunk(png_ptr, length, keyword_length+2,
-         &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+          &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
       {
          png_text text;
 
-         /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except
-          * for the extra compression type byte and the fact that it isn't
-          * necessarily '\0' terminated.
-          */
-         buffer = png_ptr->read_buffer;
-         buffer[uncompressed_length+(keyword_length+2)] = 0;
+         if (png_ptr->read_buffer == NULL)
+           errmsg="Read failure in png_handle_zTXt";
+         else
+         {
+            /* It worked; png_ptr->read_buffer now looks like a tEXt chunk
+             * except for the extra compression type byte and the fact that
+             * it isn't necessarily '\0' terminated.
+             */
+            buffer = png_ptr->read_buffer;
+            buffer[uncompressed_length+(keyword_length+2)] = 0;
 
-         text.compression = PNG_TEXT_COMPRESSION_zTXt;
-         text.key = (png_charp)buffer;
-         text.text = (png_charp)(buffer + keyword_length+2);
-         text.text_length = uncompressed_length;
-         text.itxt_length = 0;
-         text.lang = NULL;
-         text.lang_key = NULL;
+            text.compression = PNG_TEXT_COMPRESSION_zTXt;
+            text.key = (png_charp)buffer;
+            text.text = (png_charp)(buffer + keyword_length+2);
+            text.text_length = uncompressed_length;
+            text.itxt_length = 0;
+            text.lang = NULL;
+            text.lang_key = NULL;
 
-         if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)
-            errmsg = "insufficient memory";
+            if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)
+               errmsg = "insufficient memory";
+         }
       }
 
       else
@@ -2713,7 +2798,7 @@
           * iCCP and text chunks.
           */
          if (png_decompress_chunk(png_ptr, length, prefix_length,
-            &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+             &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
             buffer = png_ptr->read_buffer;
 
          else
@@ -2793,7 +2878,7 @@
       {
          /* Do a 'warn' here - it is handled below. */
          png_ptr->unknown_chunk.data = png_voidcast(png_bytep,
-            png_malloc_warn(png_ptr, length));
+             png_malloc_warn(png_ptr, length));
       }
    }
 
@@ -2818,7 +2903,7 @@
 /* Handle an unknown, or known but disabled, chunk */
 void /* PRIVATE */
 png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
-   png_uint_32 length, int keep)
+    png_uint_32 length, int keep)
 {
    int handled = 0; /* the chunk was handled */
 
@@ -2856,7 +2941,7 @@
       {
          /* Callback to user unknown chunk handler */
          int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr,
-            &png_ptr->unknown_chunk);
+             &png_ptr->unknown_chunk);
 
          /* ret is:
           * negative: An error occurred; png_chunk_error will be called.
@@ -2890,9 +2975,9 @@
                {
                   png_chunk_warning(png_ptr, "Saving unknown chunk:");
                   png_app_warning(png_ptr,
-                     "forcing save of an unhandled chunk;"
-                     " please call png_set_keep_unknown_chunks");
-                     /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */
+                      "forcing save of an unhandled chunk;"
+                      " please call png_set_keep_unknown_chunks");
+                      /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */
                }
 #              endif
                keep = PNG_HANDLE_CHUNK_IF_SAFE;
@@ -2969,7 +3054,7 @@
          case 2:
             png_ptr->user_chunk_cache_max = 1;
             png_chunk_benign_error(png_ptr, "no space in chunk cache");
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
          case 1:
             /* NOTE: prior to 1.6.0 this case resulted in an unknown critical
              * chunk being skipped, now there will be a hard error below.
@@ -2978,14 +3063,14 @@
 
          default: /* not at limit */
             --(png_ptr->user_chunk_cache_max);
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
          case 0: /* no limit */
 #  endif /* USER_LIMITS */
             /* Here when the limit isn't reached or when limits are compiled
              * out; store the chunk.
              */
             png_set_unknown_chunks(png_ptr, info_ptr,
-               &png_ptr->unknown_chunk, 1);
+                &png_ptr->unknown_chunk, 1);
             handled = 1;
 #  ifdef PNG_USER_LIMITS_SUPPORTED
             break;
@@ -3029,20 +3114,58 @@
  */
 
 void /* PRIVATE */
-png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name)
+png_check_chunk_name(png_const_structrp png_ptr, const png_uint_32 chunk_name)
 {
    int i;
+   png_uint_32 cn=chunk_name;
 
    png_debug(1, "in png_check_chunk_name");
 
    for (i=1; i<=4; ++i)
    {
-      int c = chunk_name & 0xff;
+      int c = cn & 0xff;
 
       if (c < 65 || c > 122 || (c > 90 && c < 97))
          png_chunk_error(png_ptr, "invalid chunk type");
 
-      chunk_name >>= 8;
+      cn >>= 8;
+   }
+}
+
+void /* PRIVATE */
+png_check_chunk_length(png_const_structrp png_ptr, const png_uint_32 length)
+{
+   png_alloc_size_t limit = PNG_UINT_31_MAX;
+
+# ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_malloc_max > 0 &&
+       png_ptr->user_chunk_malloc_max < limit)
+      limit = png_ptr->user_chunk_malloc_max;
+# elif PNG_USER_CHUNK_MALLOC_MAX > 0
+   if (PNG_USER_CHUNK_MALLOC_MAX < limit)
+      limit = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
+   if (png_ptr->chunk_name == png_IDAT)
+   {
+      png_alloc_size_t idat_limit = PNG_UINT_31_MAX;
+      size_t row_factor =
+         (png_ptr->width * png_ptr->channels * (png_ptr->bit_depth > 8? 2: 1)
+          + 1 + (png_ptr->interlaced? 6: 0));
+      if (png_ptr->height > PNG_UINT_32_MAX/row_factor)
+         idat_limit=PNG_UINT_31_MAX;
+      else
+         idat_limit = png_ptr->height * row_factor;
+      row_factor = row_factor > 32566? 32566 : row_factor;
+      idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */
+      idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX;
+      limit = limit < idat_limit? idat_limit : limit;
+   }
+
+   if (length > limit)
+   {
+      png_debug2(0," length = %lu, limit = %lu",
+         (unsigned long)length,(unsigned long)limit);
+      png_chunk_error(png_ptr, "chunk data is too large");
    }
 }
 
@@ -3097,7 +3220,7 @@
 #     ifdef PNG_READ_PACKSWAP_SUPPORTED
       if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
          /* little-endian byte */
-         end_mask = 0xff << end_mask;
+         end_mask = (unsigned int)(0xff << end_mask);
 
       else /* big-endian byte */
 #     endif
@@ -3371,7 +3494,7 @@
                 */
                do
                {
-                  dp[0] = sp[0], dp[1] = sp[1];
+                  dp[0] = sp[0]; dp[1] = sp[1];
 
                   if (row_width <= bytes_to_jump)
                      return;
@@ -3392,7 +3515,7 @@
                 */
                for (;;)
                {
-                  dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];
+                  dp[0] = sp[0]; dp[1] = sp[1]; dp[2] = sp[2];
 
                   if (row_width <= bytes_to_jump)
                      return;
@@ -3418,8 +3541,8 @@
                   /* Everything is aligned for png_uint_16 copies, but try for
                    * png_uint_32 first.
                    */
-                  if (png_isaligned(dp, png_uint_32) != 0 &&
-                      png_isaligned(sp, png_uint_32) != 0 &&
+                  if (png_isaligned(dp, png_uint_32) &&
+                      png_isaligned(sp, png_uint_32) &&
                       bytes_to_copy % (sizeof (png_uint_32)) == 0 &&
                       bytes_to_jump % (sizeof (png_uint_32)) == 0)
                   {
@@ -3539,11 +3662,11 @@
 #ifdef PNG_READ_INTERLACING_SUPPORTED
 void /* PRIVATE */
 png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
-   png_uint_32 transformations /* Because these may affect the byte layout */)
+    png_uint_32 transformations /* Because these may affect the byte layout */)
 {
    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
    /* Offset to next interlace block */
-   static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+   static PNG_CONST unsigned int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
 
    png_debug(1, "in png_do_read_interlace");
    if (row != NULL && row_info != NULL)
@@ -3558,9 +3681,10 @@
          {
             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
             png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
-            int sshift, dshift;
-            int s_start, s_end, s_inc;
-            int jstop = png_pass_inc[pass];
+            unsigned int sshift, dshift;
+            unsigned int s_start, s_end;
+            int s_inc;
+            int jstop = (int)png_pass_inc[pass];
             png_byte v;
             png_uint_32 i;
             int j;
@@ -3568,8 +3692,8 @@
 #ifdef PNG_READ_PACKSWAP_SUPPORTED
             if ((transformations & PNG_PACKSWAP) != 0)
             {
-                sshift = (int)((row_info->width + 7) & 0x07);
-                dshift = (int)((final_width + 7) & 0x07);
+                sshift = ((row_info->width + 7) & 0x07);
+                dshift = ((final_width + 7) & 0x07);
                 s_start = 7;
                 s_end = 0;
                 s_inc = -1;
@@ -3578,8 +3702,8 @@
             else
 #endif
             {
-                sshift = 7 - (int)((row_info->width + 7) & 0x07);
-                dshift = 7 - (int)((final_width + 7) & 0x07);
+                sshift = 7 - ((row_info->width + 7) & 0x07);
+                dshift = 7 - ((final_width + 7) & 0x07);
                 s_start = 0;
                 s_end = 7;
                 s_inc = 1;
@@ -3591,7 +3715,7 @@
                for (j = 0; j < jstop; j++)
                {
                   unsigned int tmp = *dp & (0x7f7f >> (7 - dshift));
-                  tmp |= v << dshift;
+                  tmp |= (unsigned int)(v << dshift);
                   *dp = (png_byte)(tmp & 0xff);
 
                   if (dshift == s_end)
@@ -3601,7 +3725,7 @@
                   }
 
                   else
-                     dshift += s_inc;
+                     dshift = (unsigned int)((int)dshift + s_inc);
                }
 
                if (sshift == s_end)
@@ -3611,7 +3735,7 @@
                }
 
                else
-                  sshift += s_inc;
+                  sshift = (unsigned int)((int)sshift + s_inc);
             }
             break;
          }
@@ -3620,16 +3744,17 @@
          {
             png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
             png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
-            int sshift, dshift;
-            int s_start, s_end, s_inc;
-            int jstop = png_pass_inc[pass];
+            unsigned int sshift, dshift;
+            unsigned int s_start, s_end;
+            int s_inc;
+            int jstop = (int)png_pass_inc[pass];
             png_uint_32 i;
 
 #ifdef PNG_READ_PACKSWAP_SUPPORTED
             if ((transformations & PNG_PACKSWAP) != 0)
             {
-               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
-               dshift = (int)(((final_width + 3) & 0x03) << 1);
+               sshift = (((row_info->width + 3) & 0x03) << 1);
+               dshift = (((final_width + 3) & 0x03) << 1);
                s_start = 6;
                s_end = 0;
                s_inc = -2;
@@ -3638,8 +3763,8 @@
             else
 #endif
             {
-               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
-               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
+               sshift = ((3 - ((row_info->width + 3) & 0x03)) << 1);
+               dshift = ((3 - ((final_width + 3) & 0x03)) << 1);
                s_start = 0;
                s_end = 6;
                s_inc = 2;
@@ -3654,7 +3779,7 @@
                for (j = 0; j < jstop; j++)
                {
                   unsigned int tmp = *dp & (0x3f3f >> (6 - dshift));
-                  tmp |= v << dshift;
+                  tmp |= (unsigned int)(v << dshift);
                   *dp = (png_byte)(tmp & 0xff);
 
                   if (dshift == s_end)
@@ -3664,7 +3789,7 @@
                   }
 
                   else
-                     dshift += s_inc;
+                     dshift = (unsigned int)((int)dshift + s_inc);
                }
 
                if (sshift == s_end)
@@ -3674,7 +3799,7 @@
                }
 
                else
-                  sshift += s_inc;
+                  sshift = (unsigned int)((int)sshift + s_inc);
             }
             break;
          }
@@ -3683,16 +3808,17 @@
          {
             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
             png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
-            int sshift, dshift;
-            int s_start, s_end, s_inc;
+            unsigned int sshift, dshift;
+            unsigned int s_start, s_end;
+            int s_inc;
             png_uint_32 i;
-            int jstop = png_pass_inc[pass];
+            int jstop = (int)png_pass_inc[pass];
 
 #ifdef PNG_READ_PACKSWAP_SUPPORTED
             if ((transformations & PNG_PACKSWAP) != 0)
             {
-               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
-               dshift = (int)(((final_width + 1) & 0x01) << 2);
+               sshift = (((row_info->width + 1) & 0x01) << 2);
+               dshift = (((final_width + 1) & 0x01) << 2);
                s_start = 4;
                s_end = 0;
                s_inc = -4;
@@ -3701,8 +3827,8 @@
             else
 #endif
             {
-               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
-               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
+               sshift = ((1 - ((row_info->width + 1) & 0x01)) << 2);
+               dshift = ((1 - ((final_width + 1) & 0x01)) << 2);
                s_start = 0;
                s_end = 4;
                s_inc = 4;
@@ -3716,7 +3842,7 @@
                for (j = 0; j < jstop; j++)
                {
                   unsigned int tmp = *dp & (0xf0f >> (4 - dshift));
-                  tmp |= v << dshift;
+                  tmp |= (unsigned int)(v << dshift);
                   *dp = (png_byte)(tmp & 0xff);
 
                   if (dshift == s_end)
@@ -3726,7 +3852,7 @@
                   }
 
                   else
-                     dshift += s_inc;
+                     dshift = (unsigned int)((int)dshift + s_inc);
                }
 
                if (sshift == s_end)
@@ -3736,7 +3862,7 @@
                }
 
                else
-                  sshift += s_inc;
+                  sshift = (unsigned int)((int)sshift + s_inc);
             }
             break;
          }
@@ -3750,7 +3876,7 @@
 
             png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
 
-            int jstop = png_pass_inc[pass];
+            int jstop = (int)png_pass_inc[pass];
             png_uint_32 i;
 
             for (i = 0; i < row_info->width; i++)
@@ -3783,7 +3909,7 @@
 
 static void
 png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
+    png_const_bytep prev_row)
 {
    png_size_t i;
    png_size_t istop = row_info->rowbytes;
@@ -3801,7 +3927,7 @@
 
 static void
 png_read_filter_row_up(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
+    png_const_bytep prev_row)
 {
    png_size_t i;
    png_size_t istop = row_info->rowbytes;
@@ -3817,7 +3943,7 @@
 
 static void
 png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
+    png_const_bytep prev_row)
 {
    png_size_t i;
    png_bytep rp = row;
@@ -3844,7 +3970,7 @@
 
 static void
 png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
+    png_const_bytep prev_row)
 {
    png_bytep rp_end = row + row_info->rowbytes;
    int a, c;
@@ -3878,7 +4004,10 @@
       /* Find the best predictor, the least of pa, pb, pc favoring the earlier
        * ones in the case of a tie.
        */
-      if (pb < pa) pa = pb, a = b;
+      if (pb < pa)
+      {
+         pa = pb; a = b;
+      }
       if (pc < pa) a = c;
 
       /* Calculate the current pixel in a, and move the previous row pixel to c
@@ -3892,9 +4021,9 @@
 
 static void
 png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
+    png_const_bytep prev_row)
 {
-   int bpp = (row_info->pixel_depth + 7) >> 3;
+   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
    png_bytep rp_end = row + bpp;
 
    /* Process the first pixel in the row completely (this is the same as 'up'
@@ -3907,7 +4036,7 @@
    }
 
    /* Remainder */
-   rp_end += row_info->rowbytes - bpp;
+   rp_end = rp_end + (row_info->rowbytes - bpp);
 
    while (row < rp_end)
    {
@@ -3930,7 +4059,10 @@
       pc = (p + pc) < 0 ? -(p + pc) : p + pc;
 #endif
 
-      if (pb < pa) pa = pb, a = b;
+      if (pb < pa)
+      {
+         pa = pb; a = b;
+      }
       if (pc < pa) a = c;
 
       a += *row;
@@ -3977,7 +4109,7 @@
 
 void /* PRIVATE */
 png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row, int filter)
+    png_const_bytep prev_row, int filter)
 {
    /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define
     * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic
@@ -3995,7 +4127,7 @@
 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 void /* PRIVATE */
 png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
-   png_alloc_size_t avail_out)
+    png_alloc_size_t avail_out)
 {
    /* Loop reading IDATs and decompressing the result into output[avail_out] */
    png_ptr->zstream.next_out = output;
@@ -4252,7 +4384,7 @@
    /* Offset to next interlace block in the y direction */
    static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
 
-   int max_pixel_depth;
+   unsigned int max_pixel_depth;
    png_size_t row_bytes;
 
    png_debug(1, "in png_read_start_row");
@@ -4281,7 +4413,7 @@
       png_ptr->iwidth = png_ptr->width;
    }
 
-   max_pixel_depth = png_ptr->pixel_depth;
+   max_pixel_depth = (unsigned int)png_ptr->pixel_depth;
 
    /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of
     * calculations to calculate the final pixel depth, then
@@ -4416,7 +4548,7 @@
 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
    if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
    {
-      int user_pixel_depth = png_ptr->user_transform_depth *
+      unsigned int user_pixel_depth = png_ptr->user_transform_depth *
          png_ptr->user_transform_channels;
 
       if (user_pixel_depth > max_pixel_depth)
@@ -4438,7 +4570,7 @@
     * for safety's sake
     */
    row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
-       1 + ((max_pixel_depth + 7) >> 3);
+       1 + ((max_pixel_depth + 7) >> 3U);
 
 #ifdef PNG_MAX_MALLOC_64K
    if (row_bytes > (png_uint_32)65536L)
@@ -4447,42 +4579,42 @@
 
    if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
    {
-     png_free(png_ptr, png_ptr->big_row_buf);
-     png_free(png_ptr, png_ptr->big_prev_row);
+      png_free(png_ptr, png_ptr->big_row_buf);
+      png_free(png_ptr, png_ptr->big_prev_row);
 
-     if (png_ptr->interlaced != 0)
-        png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
-            row_bytes + 48);
+      if (png_ptr->interlaced != 0)
+         png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
+             row_bytes + 48);
 
-     else
-        png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+      else
+         png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
 
-     png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+      png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
 
 #ifdef PNG_ALIGNED_MEMORY_SUPPORTED
-     /* Use 16-byte aligned memory for row_buf with at least 16 bytes
-      * of padding before and after row_buf; treat prev_row similarly.
-      * NOTE: the alignment is to the start of the pixels, one beyond the start
-      * of the buffer, because of the filter byte.  Prior to libpng 1.5.6 this
-      * was incorrect; the filter byte was aligned, which had the exact
-      * opposite effect of that intended.
-      */
-     {
-        png_bytep temp = png_ptr->big_row_buf + 32;
-        int extra = (int)((temp - (png_bytep)0) & 0x0f);
-        png_ptr->row_buf = temp - extra - 1/*filter byte*/;
+      /* Use 16-byte aligned memory for row_buf with at least 16 bytes
+       * of padding before and after row_buf; treat prev_row similarly.
+       * NOTE: the alignment is to the start of the pixels, one beyond the start
+       * of the buffer, because of the filter byte.  Prior to libpng 1.5.6 this
+       * was incorrect; the filter byte was aligned, which had the exact
+       * opposite effect of that intended.
+       */
+      {
+         png_bytep temp = png_ptr->big_row_buf + 32;
+         int extra = (int)((temp - (png_bytep)0) & 0x0f);
+         png_ptr->row_buf = temp - extra - 1/*filter byte*/;
 
-        temp = png_ptr->big_prev_row + 32;
-        extra = (int)((temp - (png_bytep)0) & 0x0f);
-        png_ptr->prev_row = temp - extra - 1/*filter byte*/;
-     }
+         temp = png_ptr->big_prev_row + 32;
+         extra = (int)((temp - (png_bytep)0) & 0x0f);
+         png_ptr->prev_row = temp - extra - 1/*filter byte*/;
+      }
 
 #else
-     /* Use 31 bytes of padding before and 17 bytes after row_buf. */
-     png_ptr->row_buf = png_ptr->big_row_buf + 31;
-     png_ptr->prev_row = png_ptr->big_prev_row + 31;
+      /* Use 31 bytes of padding before and 17 bytes after row_buf. */
+      png_ptr->row_buf = png_ptr->big_row_buf + 31;
+      png_ptr->prev_row = png_ptr->big_prev_row + 31;
 #endif
-     png_ptr->old_big_row_buf_size = row_bytes + 48;
+      png_ptr->old_big_row_buf_size = row_bytes + 48;
    }
 
 #ifdef PNG_MAX_MALLOC_64K
@@ -4507,7 +4639,7 @@
     * does not, so free the read buffer now regardless; the sequential reader
     * reallocates it on demand.
     */
-   if (png_ptr->read_buffer != 0)
+   if (png_ptr->read_buffer != NULL)
    {
       png_bytep buffer = png_ptr->read_buffer;
 
diff --git a/third_party/libpng/pngset.c b/third_party/libpng/pngset.c
index 1c51270..6f3a1ee 100644
--- a/third_party/libpng/pngset.c
+++ b/third_party/libpng/pngset.c
@@ -1,8 +1,8 @@
 
 /* pngset.c - storage of image information into info struct
  *
- * Last changed in libpng 1.6.21 [January 15, 2016]
- * Copyright (c) 1998-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -104,14 +104,14 @@
     double green_x, double green_y, double blue_x, double blue_y)
 {
    png_set_cHRM_fixed(png_ptr, info_ptr,
-      png_fixed(png_ptr, white_x, "cHRM White X"),
-      png_fixed(png_ptr, white_y, "cHRM White Y"),
-      png_fixed(png_ptr, red_x, "cHRM Red X"),
-      png_fixed(png_ptr, red_y, "cHRM Red Y"),
-      png_fixed(png_ptr, green_x, "cHRM Green X"),
-      png_fixed(png_ptr, green_y, "cHRM Green Y"),
-      png_fixed(png_ptr, blue_x, "cHRM Blue X"),
-      png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
+       png_fixed(png_ptr, white_x, "cHRM White X"),
+       png_fixed(png_ptr, white_y, "cHRM White Y"),
+       png_fixed(png_ptr, red_x, "cHRM Red X"),
+       png_fixed(png_ptr, red_y, "cHRM Red Y"),
+       png_fixed(png_ptr, green_x, "cHRM Green X"),
+       png_fixed(png_ptr, green_y, "cHRM Green Y"),
+       png_fixed(png_ptr, blue_x, "cHRM Blue X"),
+       png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
 }
 
 void PNGAPI
@@ -120,20 +120,67 @@
     double blue_X, double blue_Y, double blue_Z)
 {
    png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
-      png_fixed(png_ptr, red_X, "cHRM Red X"),
-      png_fixed(png_ptr, red_Y, "cHRM Red Y"),
-      png_fixed(png_ptr, red_Z, "cHRM Red Z"),
-      png_fixed(png_ptr, green_X, "cHRM Green X"),
-      png_fixed(png_ptr, green_Y, "cHRM Green Y"),
-      png_fixed(png_ptr, green_Z, "cHRM Green Z"),
-      png_fixed(png_ptr, blue_X, "cHRM Blue X"),
-      png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
-      png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
+       png_fixed(png_ptr, red_X, "cHRM Red X"),
+       png_fixed(png_ptr, red_Y, "cHRM Red Y"),
+       png_fixed(png_ptr, red_Z, "cHRM Red Z"),
+       png_fixed(png_ptr, green_X, "cHRM Green X"),
+       png_fixed(png_ptr, green_Y, "cHRM Green Y"),
+       png_fixed(png_ptr, green_Z, "cHRM Green Z"),
+       png_fixed(png_ptr, blue_X, "cHRM Blue X"),
+       png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
+       png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
 }
 #  endif /* FLOATING_POINT */
 
 #endif /* cHRM */
 
+#ifdef PNG_eXIf_SUPPORTED
+void PNGAPI
+png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
+    const png_bytep eXIf_buf)
+{
+  png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1");
+  PNG_UNUSED(info_ptr)
+  PNG_UNUSED(eXIf_buf)
+}
+
+void PNGAPI
+png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr,
+    const png_uint_32 num_exif, const png_bytep eXIf_buf)
+{
+   int i;
+
+   png_debug1(1, "in %s storage function", "eXIf");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (info_ptr->exif)
+   {
+      png_free(png_ptr, info_ptr->exif);
+      info_ptr->exif = NULL;
+   }
+
+   info_ptr->num_exif = num_exif;
+
+   info_ptr->exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr,
+       info_ptr->num_exif));
+
+   if (info_ptr->exif == NULL)
+   {
+      png_warning(png_ptr, "Insufficient memory for eXIf chunk data");
+      return;
+   }
+
+   info_ptr->free_me |= PNG_FREE_EXIF;
+
+   for (i = 0; i < (int) info_ptr->num_exif; i++)
+      info_ptr->exif[i] = eXIf_buf[i];
+
+   info_ptr->valid |= PNG_INFO_eXIf;
+}
+#endif /* eXIf */
+
 #ifdef PNG_gAMA_SUPPORTED
 void PNGFAPI
 png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
@@ -328,10 +375,10 @@
 
    length = strlen(units) + 1;
    png_debug1(3, "allocating units for info (%lu bytes)",
-     (unsigned long)length);
+       (unsigned long)length);
 
    info_ptr->pcal_units = png_voidcast(png_charp,
-      png_malloc_warn(png_ptr, length));
+       png_malloc_warn(png_ptr, length));
 
    if (info_ptr->pcal_units == NULL)
    {
@@ -343,7 +390,7 @@
    memcpy(info_ptr->pcal_units, units, length);
 
    info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
-       (png_size_t)((nparams + 1) * (sizeof (png_charp)))));
+       (png_size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp)))));
 
    if (info_ptr->pcal_params == NULL)
    {
@@ -352,7 +399,8 @@
       return;
    }
 
-   memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp)));
+   memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) *
+       (sizeof (png_charp)));
 
    for (i = 0; i < nparams; i++)
    {
@@ -410,7 +458,7 @@
    png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
 
    info_ptr->scal_s_width = png_voidcast(png_charp,
-      png_malloc_warn(png_ptr, lengthw));
+       png_malloc_warn(png_ptr, lengthw));
 
    if (info_ptr->scal_s_width == NULL)
    {
@@ -426,7 +474,7 @@
    png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
 
    info_ptr->scal_s_height = png_voidcast(png_charp,
-      png_malloc_warn(png_ptr, lengthh));
+       png_malloc_warn(png_ptr, lengthh));
 
    if (info_ptr->scal_s_height == NULL)
    {
@@ -465,9 +513,9 @@
       char sheight[PNG_sCAL_MAX_DIGITS+1];
 
       png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width,
-         PNG_sCAL_PRECISION);
+          PNG_sCAL_PRECISION);
       png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
-         PNG_sCAL_PRECISION);
+          PNG_sCAL_PRECISION);
 
       png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
    }
@@ -575,7 +623,8 @@
        PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
 
    if (num_palette > 0)
-      memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color)));
+      memcpy(png_ptr->palette, palette, (unsigned int)num_palette *
+          (sizeof (png_color)));
    info_ptr->palette = png_ptr->palette;
    info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
 
@@ -660,7 +709,7 @@
     */
    {
       int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
-         proflen, profile, info_ptr->color_type);
+          proflen, profile, info_ptr->color_type);
 
       png_colorspace_sync_info(png_ptr, info_ptr);
 
@@ -685,7 +734,7 @@
 
    memcpy(new_iccp_name, name, length);
    new_iccp_profile = png_voidcast(png_bytep,
-      png_malloc_warn(png_ptr, proflen));
+       png_malloc_warn(png_ptr, proflen));
 
    if (new_iccp_profile == NULL)
    {
@@ -760,14 +809,14 @@
           * the overflow checks.
           */
          new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
-            info_ptr->text, old_num_text, max_text-old_num_text,
-            sizeof *new_text));
+             info_ptr->text, old_num_text, max_text-old_num_text,
+             sizeof *new_text));
       }
 
       if (new_text == NULL)
       {
          png_chunk_report(png_ptr, "too many text chunks",
-            PNG_CHUNK_WRITE_ERROR);
+             PNG_CHUNK_WRITE_ERROR);
 
          return 1;
       }
@@ -795,7 +844,7 @@
           text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
       {
          png_chunk_report(png_ptr, "text compression mode is out of range",
-            PNG_CHUNK_WRITE_ERROR);
+             PNG_CHUNK_WRITE_ERROR);
          continue;
       }
 
@@ -827,7 +876,7 @@
 #  else /* iTXt */
       {
          png_chunk_report(png_ptr, "iTXt chunk not supported",
-            PNG_CHUNK_WRITE_ERROR);
+             PNG_CHUNK_WRITE_ERROR);
          continue;
       }
 #  endif
@@ -856,7 +905,7 @@
       if (textp->key == NULL)
       {
          png_chunk_report(png_ptr, "text chunk: out of memory",
-               PNG_CHUNK_WRITE_ERROR);
+             PNG_CHUNK_WRITE_ERROR);
 
          return 1;
       }
@@ -968,8 +1017,7 @@
        {
          /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
           info_ptr->trans_alpha = png_voidcast(png_bytep,
-             png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
-
+              png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
           memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
        }
        png_ptr->trans_alpha = info_ptr->trans_alpha;
@@ -989,7 +1037,7 @@
              trans_color->green > sample_max ||
              trans_color->blue > sample_max)))
             png_warning(png_ptr,
-               "tRNS chunk has out-of-range samples for bit_depth");
+                "tRNS chunk has out-of-range samples for bit_depth");
       }
 #endif
 
@@ -1031,8 +1079,8 @@
     * overflows.  Notice that the parameters are (int) and (size_t)
     */
    np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
-      info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
-      sizeof *np));
+       info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
+       sizeof *np));
 
    if (np == NULL)
    {
@@ -1093,7 +1141,7 @@
        * checked it when doing the allocation.
        */
       memcpy(np->entries, entries->entries,
-         entries->nentries * sizeof (png_sPLT_entry));
+          (unsigned int)entries->nentries * sizeof (png_sPLT_entry));
 
       /* Note that 'continue' skips the advance of the out pointer and out
        * count, so an invalid entry is not added.
@@ -1101,8 +1149,9 @@
       info_ptr->valid |= PNG_INFO_sPLT;
       ++(info_ptr->splt_palettes_num);
       ++np;
+      ++entries;
    }
-   while (++entries, --nentries);
+   while (--nentries);
 
    if (nentries > 0)
       png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
@@ -1123,10 +1172,10 @@
    {
       /* Write struct, so unknown chunks come from the app */
       png_app_warning(png_ptr,
-         "png_set_unknown_chunks now expects a valid location");
+          "png_set_unknown_chunks now expects a valid location");
       /* Use the old behavior */
       location = (png_byte)(png_ptr->mode &
-         (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
+          (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
    }
 
    /* This need not be an internal error - if the app calls
@@ -1149,7 +1198,7 @@
 
 void PNGAPI
 png_set_unknown_chunks(png_const_structrp png_ptr,
-   png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
+    png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
 {
    png_unknown_chunkp np;
 
@@ -1188,13 +1237,13 @@
     * appropriate to read or write.
     */
    np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
-         info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
-         sizeof *np));
+       info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
+       sizeof *np));
 
    if (np == NULL)
    {
       png_chunk_report(png_ptr, "too many unknown chunks",
-         PNG_CHUNK_WRITE_ERROR);
+          PNG_CHUNK_WRITE_ERROR);
 
       return;
    }
@@ -1223,12 +1272,12 @@
       else
       {
          np->data = png_voidcast(png_bytep,
-            png_malloc_base(png_ptr, unknowns->size));
+             png_malloc_base(png_ptr, unknowns->size));
 
          if (np->data == NULL)
          {
             png_chunk_report(png_ptr, "unknown chunk: out of memory",
-               PNG_CHUNK_WRITE_ERROR);
+                PNG_CHUNK_WRITE_ERROR);
             /* But just skip storing the unknown chunk */
             continue;
          }
@@ -1262,7 +1311,7 @@
       {
          png_app_error(png_ptr, "invalid unknown chunk location");
          /* Fake out the pre 1.6.0 behavior: */
-         if ((location & PNG_HAVE_IDAT) != 0) /* undocumented! */
+         if (((unsigned int)location & PNG_HAVE_IDAT) != 0) /* undocumented! */
             location = PNG_AFTER_IDAT;
 
          else
@@ -1353,6 +1402,7 @@
       static PNG_CONST png_byte chunks_to_ignore[] = {
          98,  75,  71,  68, '\0',  /* bKGD */
          99,  72,  82,  77, '\0',  /* cHRM */
+        101,  88,  73, 102, '\0',  /* eXIf */
         103,  65,  77,  65, '\0',  /* gAMA */
         104,  73,  83,  84, '\0',  /* hIST */
         105,  67,  67,  80, '\0',  /* iCCP */
@@ -1386,7 +1436,7 @@
          return;
       }
 
-      num_chunks = num_chunks_in;
+      num_chunks = (unsigned int)num_chunks_in;
    }
 
    old_num_chunks = png_ptr->num_chunk_list;
@@ -1435,7 +1485,7 @@
       for (i=0; i<num_chunks; ++i)
       {
          old_num_chunks = add_one_chunk(new_list, old_num_chunks,
-            chunk_list+5*i, keep);
+             chunk_list+5*i, keep);
       }
 
       /* Now remove any spurious 'default' entries. */
@@ -1515,60 +1565,60 @@
 void PNGAPI
 png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size)
 {
-    if (png_ptr == NULL)
-       return;
+   if (png_ptr == NULL)
+      return;
 
-    if (size == 0 || size > PNG_UINT_31_MAX)
-       png_error(png_ptr, "invalid compression buffer size");
+   if (size == 0 || size > PNG_UINT_31_MAX)
+      png_error(png_ptr, "invalid compression buffer size");
 
 #  ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
-      {
-         png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
-         return;
-      }
+   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+   {
+      png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
+      return;
+   }
 #  endif
 
 #  ifdef PNG_WRITE_SUPPORTED
-      if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+   if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+   {
+      if (png_ptr->zowner != 0)
       {
-         if (png_ptr->zowner != 0)
-         {
-            png_warning(png_ptr,
-              "Compression buffer size cannot be changed because it is in use");
+         png_warning(png_ptr,
+             "Compression buffer size cannot be changed because it is in use");
 
-            return;
-         }
+         return;
+      }
 
 #ifndef __COVERITY__
-         /* Some compilers complain that this is always false.  However, it
-          * can be true when integer overflow happens.
-          */
-         if (size > ZLIB_IO_MAX)
-         {
-            png_warning(png_ptr,
-               "Compression buffer size limited to system maximum");
-            size = ZLIB_IO_MAX; /* must fit */
-         }
+      /* Some compilers complain that this is always false.  However, it
+       * can be true when integer overflow happens.
+       */
+      if (size > ZLIB_IO_MAX)
+      {
+         png_warning(png_ptr,
+             "Compression buffer size limited to system maximum");
+         size = ZLIB_IO_MAX; /* must fit */
+      }
 #endif
 
-         if (size < 6)
-         {
-            /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
-             * if this is permitted.
-             */
-            png_warning(png_ptr,
-               "Compression buffer size cannot be reduced below 6");
+      if (size < 6)
+      {
+         /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
+          * if this is permitted.
+          */
+         png_warning(png_ptr,
+             "Compression buffer size cannot be reduced below 6");
 
-            return;
-         }
-
-         if (png_ptr->zbuffer_size != size)
-         {
-            png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
-            png_ptr->zbuffer_size = (uInt)size;
-         }
+         return;
       }
+
+      if (png_ptr->zbuffer_size != size)
+      {
+         png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
+         png_ptr->zbuffer_size = (uInt)size;
+      }
+   }
 #  endif
 }
 
@@ -1576,7 +1626,7 @@
 png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask)
 {
    if (png_ptr != NULL && info_ptr != NULL)
-      info_ptr->valid &= ~mask;
+      info_ptr->valid &= (unsigned int)(~mask);
 }
 
 
@@ -1675,7 +1725,9 @@
 png_uint_32 /* PRIVATE */
 png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
 {
+#ifdef PNG_WARNINGS_SUPPORTED
    png_const_charp orig_key = key;
+#endif
    png_uint_32 key_len = 0;
    int bad_character = 0;
    int space = 1;
@@ -1693,14 +1745,16 @@
       png_byte ch = (png_byte)*key++;
 
       if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
-         *new_key++ = ch, ++key_len, space = 0;
+      {
+         *new_key++ = ch; ++key_len; space = 0;
+      }
 
       else if (space == 0)
       {
          /* A space or an invalid character when one wasn't seen immediately
           * before; output just a space.
           */
-         *new_key++ = 32, ++key_len, space = 1;
+         *new_key++ = 32; ++key_len; space = 1;
 
          /* If the character was not a space then it is invalid. */
          if (ch != 32)
@@ -1713,7 +1767,7 @@
 
    if (key_len > 0 && space != 0) /* trailing space */
    {
-      --key_len, --new_key;
+      --key_len; --new_key;
       if (bad_character == 0)
          bad_character = 32;
    }
@@ -1738,7 +1792,9 @@
 
       png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
    }
-#endif /* WARNINGS */
+#else /* !WARNINGS */
+   PNG_UNUSED(png_ptr)
+#endif /* !WARNINGS */
 
    return key_len;
 }
diff --git a/third_party/libpng/pngstruct.h b/third_party/libpng/pngstruct.h
index c1f35ede..aac88df 100644
--- a/third_party/libpng/pngstruct.h
+++ b/third_party/libpng/pngstruct.h
@@ -1,8 +1,8 @@
 
 /* pngstruct.h - header file for PNG reference library
  *
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -228,6 +228,10 @@
                                * big_row_buf; while writing it is separately
                                * allocated.
                                */
+#ifdef PNG_READ_EXPAND_SUPPORTED
+   /* Buffer to accelerate palette transformations. */
+   png_bytep riffled_palette;
+#endif
 #ifdef PNG_WRITE_FILTER_SUPPORTED
    png_bytep try_row;    /* buffer to save trial row when filtering */
    png_bytep tst_row;    /* buffer to save best trial row when filtering */
@@ -249,7 +253,7 @@
    png_byte filter;           /* file filter type (always 0) */
    png_byte interlaced;       /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
    png_byte pass;             /* current interlace pass (0 - 6) */
-   png_byte do_filter;        /* row filter flags (see PNG_FILTER_ below ) */
+   png_byte do_filter;        /* row filter flags (see PNG_FILTER_ in png.h ) */
    png_byte color_type;       /* color type of file */
    png_byte bit_depth;        /* bit depth of file */
    png_byte usr_bit_depth;    /* bit depth of users row: write only */
@@ -263,7 +267,7 @@
                               /* pixel depth used for the row buffers */
    png_byte transformed_pixel_depth;
                               /* pixel depth after read/write transforms */
-#if PNG_ZLIB_VERNUM >= 0x1240
+#if ZLIB_VERNUM >= 0x1240
    png_byte zstream_start;    /* at start of an input zlib stream */
 #endif /* Zlib >= 1.2.4 */
 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
@@ -353,7 +357,7 @@
 
 /* Options */
 #ifdef PNG_SET_OPTION_SUPPORTED
-   png_byte options;           /* On/off state (up to 4 options) */
+   png_uint_32 options;           /* On/off state (up to 16 options) */
 #endif
 
 #if PNG_LIBPNG_VER < 10700
diff --git a/third_party/libpng/pngtest.c b/third_party/libpng/pngtest.c
index 3515265..9d50757 100644
--- a/third_party/libpng/pngtest.c
+++ b/third_party/libpng/pngtest.c
@@ -1,8 +1,8 @@
 
 /* pngtest.c - a simple test program to test libpng
  *
- * Last changed in libpng 1.5.25 [December 3, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -43,15 +43,6 @@
 
 #include "png.h"
 
-/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
- * a skipped test, in earlier versions we need to succeed on a skipped test, so:
- */
-#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
-#  define SKIP 77
-#else
-#  define SKIP 0
-#endif
-
 /* Known chunks that exist in pngtest.png must be supported or pngtest will fail
  * simply as a result of re-ordering them.  This may be fixed in 1.7
  *
@@ -139,13 +130,13 @@
 static int
 tIME_to_str(png_structp png_ptr, png_charp ts, png_const_timep t)
 {
-    png_const_charp str = png_convert_to_rfc1123(png_ptr, t);
+   png_const_charp str = png_convert_to_rfc1123(png_ptr, t);
 
-    if (str == NULL)
-        return 0;
+   if (str == NULL)
+       return 0;
 
-    strcpy(ts, str);
-    return 1;
+   strcpy(ts, str);
+   return 1;
 }
 #endif /* older libpng */
 #endif
@@ -153,6 +144,7 @@
 static int verbose = 0;
 static int strict = 0;
 static int relaxed = 0;
+static int xfail = 0;
 static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */
 static int error_count = 0; /* count calls to png_error */
 static int warning_count = 0; /* count calls to png_warning */
@@ -249,95 +241,95 @@
     *  png_byte pixel_depth   bits per pixel (depth*channels)
     */
 
-    /* Counts the number of zero samples (or zero pixels if color_type is 3 */
+   /* Counts the number of zero samples (or zero pixels if color_type is 3 */
 
-    if (row_info->color_type == 0 || row_info->color_type == 3)
-    {
-       int pos = 0;
-       png_uint_32 n, nstop;
+   if (row_info->color_type == 0 || row_info->color_type == 3)
+   {
+      int pos = 0;
+      png_uint_32 n, nstop;
 
-       for (n = 0, nstop=row_info->width; n<nstop; n++)
-       {
-          if (row_info->bit_depth == 1)
-          {
-             if (((*dp << pos++ ) & 0x80) == 0)
-                zero_samples++;
+      for (n = 0, nstop=row_info->width; n<nstop; n++)
+      {
+         if (row_info->bit_depth == 1)
+         {
+            if (((*dp << pos++ ) & 0x80) == 0)
+               zero_samples++;
 
-             if (pos == 8)
-             {
-                pos = 0;
-                dp++;
-             }
-          }
+            if (pos == 8)
+            {
+               pos = 0;
+               dp++;
+            }
+         }
 
-          if (row_info->bit_depth == 2)
-          {
-             if (((*dp << (pos+=2)) & 0xc0) == 0)
-                zero_samples++;
+         if (row_info->bit_depth == 2)
+         {
+            if (((*dp << (pos+=2)) & 0xc0) == 0)
+               zero_samples++;
 
-             if (pos == 8)
-             {
-                pos = 0;
-                dp++;
-             }
-          }
+            if (pos == 8)
+            {
+               pos = 0;
+               dp++;
+            }
+         }
 
-          if (row_info->bit_depth == 4)
-          {
-             if (((*dp << (pos+=4)) & 0xf0) == 0)
-                zero_samples++;
+         if (row_info->bit_depth == 4)
+         {
+            if (((*dp << (pos+=4)) & 0xf0) == 0)
+               zero_samples++;
 
-             if (pos == 8)
-             {
-                pos = 0;
-                dp++;
-             }
-          }
+            if (pos == 8)
+            {
+               pos = 0;
+               dp++;
+            }
+         }
 
-          if (row_info->bit_depth == 8)
-             if (*dp++ == 0)
-                zero_samples++;
+         if (row_info->bit_depth == 8)
+            if (*dp++ == 0)
+               zero_samples++;
 
-          if (row_info->bit_depth == 16)
-          {
-             if ((*dp | *(dp+1)) == 0)
-                zero_samples++;
-             dp+=2;
-          }
-       }
-    }
-    else /* Other color types */
-    {
-       png_uint_32 n, nstop;
-       int channel;
-       int color_channels = row_info->channels;
-       if (row_info->color_type > 3)
-          color_channels--;
+         if (row_info->bit_depth == 16)
+         {
+            if ((*dp | *(dp+1)) == 0)
+               zero_samples++;
+            dp+=2;
+         }
+      }
+   }
+   else /* Other color types */
+   {
+      png_uint_32 n, nstop;
+      int channel;
+      int color_channels = row_info->channels;
+      if (row_info->color_type > 3)
+         color_channels--;
 
-       for (n = 0, nstop=row_info->width; n<nstop; n++)
-       {
-          for (channel = 0; channel < color_channels; channel++)
-          {
-             if (row_info->bit_depth == 8)
-                if (*dp++ == 0)
-                   zero_samples++;
+      for (n = 0, nstop=row_info->width; n<nstop; n++)
+      {
+         for (channel = 0; channel < color_channels; channel++)
+         {
+            if (row_info->bit_depth == 8)
+               if (*dp++ == 0)
+                  zero_samples++;
 
-             if (row_info->bit_depth == 16)
-             {
-                if ((*dp | *(dp+1)) == 0)
-                   zero_samples++;
+            if (row_info->bit_depth == 16)
+            {
+               if ((*dp | *(dp+1)) == 0)
+                  zero_samples++;
 
-                dp+=2;
-             }
-          }
-          if (row_info->color_type > 3)
-          {
-             dp++;
-             if (row_info->bit_depth == 16)
-                dp++;
-          }
-       }
-    }
+               dp+=2;
+            }
+         }
+         if (row_info->color_type > 3)
+         {
+            dp++;
+            if (row_info->bit_depth == 16)
+               dp++;
+         }
+      }
+   }
 }
 #endif /* WRITE_USER_TRANSFORM */
 
@@ -354,10 +346,10 @@
 #ifdef PNG_IO_STATE_SUPPORTED
 void
 pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
-   png_uint_32 io_op);
+    png_uint_32 io_op);
 void
 pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
-   png_uint_32 io_op)
+    png_uint_32 io_op)
 {
    png_uint_32 io_state = png_get_io_state(png_ptr);
    int err = 0;
@@ -472,7 +464,7 @@
    if (test != NULL && test->file_name != NULL)
       name = test->file_name;
 
-   fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
+   fprintf(STDERR, "\n%s: libpng warning: %s\n", name, message);
 }
 
 /* This is the default error handling function.  Note that replacements for
@@ -514,10 +506,10 @@
 typedef memory_information *memory_infop;
 
 static memory_infop pinformation = NULL;
-static png_alloc_size_t current_allocation = 0;
-static png_alloc_size_t maximum_allocation = 0;
-static png_alloc_size_t total_allocation = 0;
-static png_alloc_size_t num_allocations = 0;
+static int current_allocation = 0;
+static int maximum_allocation = 0;
+static int total_allocation = 0;
+static int num_allocations = 0;
 
 png_voidp PNGCBAPI png_debug_malloc PNGARG((png_structp png_ptr,
     png_alloc_size_t size));
@@ -541,7 +533,7 @@
       memory_infop pinfo;
       png_set_mem_fn(png_ptr, NULL, NULL, NULL);
       pinfo = (memory_infop)png_malloc(png_ptr,
-         (sizeof *pinfo));
+          (sizeof *pinfo));
       pinfo->size = size;
       current_allocation += size;
       total_allocation += size;
@@ -571,7 +563,7 @@
 
       if (verbose != 0)
          printf("png_malloc %lu bytes at %p\n", (unsigned long)size,
-            pinfo->pointer);
+             pinfo->pointer);
 
       return (png_voidp)(pinfo->pointer);
    }
@@ -604,10 +596,9 @@
          if (pinfo->pointer == ptr)
          {
             *ppinfo = pinfo->next;
-            if (current_allocation < pinfo->size)
+            current_allocation -= pinfo->size;
+            if (current_allocation < 0)
                fprintf(STDERR, "Duplicate free of memory\n");
-            else
-               current_allocation -= pinfo->size;
             /* We must free the list element too, but first kill
                the memory that is to be freed. */
             memset(ptr, 0x55, pinfo->size);
@@ -779,9 +770,9 @@
 
    if (verbose != 0)
       fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n",
-        (unsigned long)user_chunk_data.vpAg_width,
-        (unsigned long)user_chunk_data.vpAg_height,
-        user_chunk_data.vpAg_units);
+          (unsigned long)user_chunk_data.vpAg_width,
+          (unsigned long)user_chunk_data.vpAg_height,
+          user_chunk_data.vpAg_units);
 
    png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width);
    png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height);
@@ -822,7 +813,7 @@
 #ifdef PNG_TEXT_SUPPORTED
 static void
 pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr,
-   int num_text)
+    int num_text)
 {
    while (num_text > 0)
    {
@@ -904,26 +895,26 @@
    pngtest_debug("Allocating read and write structures");
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
    read_ptr =
-      png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL,
-      NULL, NULL, NULL, png_debug_malloc, png_debug_free);
+       png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL,
+       NULL, NULL, NULL, png_debug_malloc, png_debug_free);
 #else
    read_ptr =
-      png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+       png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 #endif
    png_set_error_fn(read_ptr, &error_parameters, pngtest_error,
-      pngtest_warning);
+       pngtest_warning);
 
 #ifdef PNG_WRITE_SUPPORTED
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
    write_ptr =
-      png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL,
-      NULL, NULL, NULL, png_debug_malloc, png_debug_free);
+       png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL,
+       NULL, NULL, NULL, png_debug_malloc, png_debug_free);
 #else
    write_ptr =
-      png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+       png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 #endif
    png_set_error_fn(write_ptr, &error_parameters, pngtest_error,
-      pngtest_warning);
+       pngtest_warning);
 #endif
    pngtest_debug("Allocating read_info, write_info and end_info structures");
    read_info_ptr = png_create_info_struct(read_ptr);
@@ -936,13 +927,7 @@
 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
    init_callback_info(read_info_ptr);
    png_set_read_user_chunk_fn(read_ptr, &user_chunk_data,
-     read_user_chunk_callback);
-#endif
-
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
-#  ifdef CHUNK_LIMIT /* from the build, for testing */
-      png_set_chunk_malloc_max(read_ptr, CHUNK_LIMIT);
-#  endif /* CHUNK_LIMIT */
+       read_user_chunk_callback);
 #endif
 
 #ifdef PNG_SETJMP_SUPPORTED
@@ -952,8 +937,12 @@
       fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
       png_free(read_ptr, row_buf);
       row_buf = NULL;
+      if (verbose != 0)
+        fprintf(STDERR, "   destroy read structs\n");
       png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
 #ifdef PNG_WRITE_SUPPORTED
+      if (verbose != 0)
+        fprintf(STDERR, "   destroy write structs\n");
       png_destroy_info_struct(write_ptr, &write_end_info_ptr);
       png_destroy_write_struct(&write_ptr, &write_info_ptr);
 #endif
@@ -968,11 +957,13 @@
    if (setjmp(png_jmpbuf(write_ptr)))
    {
       fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
+      if (verbose != 0)
+        fprintf(STDERR, "   destroying read structs\n");
       png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+      if (verbose != 0)
+        fprintf(STDERR, "   destroying write structs\n");
       png_destroy_info_struct(write_ptr, &write_end_info_ptr);
-#ifdef PNG_WRITE_SUPPORTED
       png_destroy_write_struct(&write_ptr, &write_info_ptr);
-#endif
       FCLOSE(fpin);
       FCLOSE(fpout);
       return (1);
@@ -980,15 +971,16 @@
 #endif
 #endif
 
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
    if (strict != 0)
    {
       /* Treat png_benign_error() as errors on read */
       png_set_benign_errors(read_ptr, 0);
 
-#ifdef PNG_WRITE_SUPPORTED
+# ifdef PNG_WRITE_SUPPORTED
       /* Treat them as errors on write */
       png_set_benign_errors(write_ptr, 0);
-#endif
+# endif
 
       /* if strict is not set, then app warnings and errors are treated as
        * warnings in release builds, but not in unstable builds; this can be
@@ -1001,10 +993,20 @@
       /* Allow application (pngtest) errors and warnings to pass */
       png_set_benign_errors(read_ptr, 1);
 
-#ifdef PNG_WRITE_SUPPORTED
-      png_set_benign_errors(write_ptr, 1);
+      /* Turn off CRC checking while reading */
+      png_set_crc_action(read_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
+
+#ifdef PNG_IGNORE_ADLER32
+      /* Turn off ADLER32 checking while reading */
+      png_set_option(read_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON);
 #endif
+
+# ifdef PNG_WRITE_SUPPORTED
+      png_set_benign_errors(write_ptr, 1);
+# endif
+
    }
+#endif /* BENIGN_ERRORS */
 
    pngtest_debug("Initializing input and output streams");
 #ifdef PNG_STDIO_SUPPORTED
@@ -1017,9 +1019,9 @@
 #  ifdef PNG_WRITE_SUPPORTED
    png_set_write_fn(write_ptr, (png_voidp)fpout,  pngtest_write_data,
 #    ifdef PNG_WRITE_FLUSH_SUPPORTED
-      pngtest_flush);
+       pngtest_flush);
 #    else
-      NULL);
+       NULL);
 #    endif
 #  endif
 #endif
@@ -1059,11 +1061,11 @@
     */
 #ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
    png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
-      NULL, 0);
+       NULL, 0);
 #endif
 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
    png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS,
-      NULL, 0);
+       NULL, 0);
 #endif
 #endif
 
@@ -1087,7 +1089,7 @@
           &color_type, &interlace_type, &compression_type, &filter_type) != 0)
       {
          png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
-            color_type, interlace_type, compression_type, filter_type);
+             color_type, interlace_type, compression_type, filter_type);
          /* num_passes may not be available below if interlace support is not
           * provided by libpng for both read and write.
           */
@@ -1114,13 +1116,13 @@
 #ifdef PNG_cHRM_SUPPORTED
    {
       png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
-         blue_y;
+          blue_y;
 
       if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y,
-         &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
+          &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
       {
          png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
-            red_y, green_x, green_y, blue_x, blue_y);
+             red_y, green_x, green_y, blue_x, blue_y);
       }
    }
 #endif
@@ -1137,13 +1139,13 @@
 #ifdef PNG_cHRM_SUPPORTED
    {
       double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
-         blue_y;
+          blue_y;
 
       if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
-         &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
+          &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
       {
          png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
-            red_y, green_x, green_y, blue_x, blue_y);
+             red_y, green_x, green_y, blue_x, blue_y);
       }
    }
 #endif
@@ -1165,10 +1167,10 @@
       int compression_type;
 
       if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
-                      &profile, &proflen) != 0)
+          &profile, &proflen) != 0)
       {
          png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
-                      profile, proflen);
+             profile, proflen);
       }
    }
 #endif
@@ -1197,6 +1199,22 @@
       }
    }
 #endif
+#ifdef PNG_READ_eXIf_SUPPORTED
+   {
+      png_bytep exif=NULL;
+      png_uint_32 exif_length;
+
+      if (png_get_eXIf_1(read_ptr, read_info_ptr, &exif_length, &exif) != 0)
+      {
+         if (exif_length > 1)
+            fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1],
+               (unsigned long)exif_length);
+# ifdef PNG_WRITE_eXIf_SUPPORTED
+         png_set_eXIf_1(write_ptr, write_info_ptr, exif_length, exif);
+# endif
+      }
+   }
+#endif
 #ifdef PNG_hIST_SUPPORTED
    {
       png_uint_16p hist;
@@ -1225,10 +1243,10 @@
       int type, nparams;
 
       if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
-         &nparams, &units, &params) != 0)
+          &nparams, &units, &params) != 0)
       {
          png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
-            nparams, units, params);
+             nparams, units, params);
       }
    }
 #endif
@@ -1258,7 +1276,7 @@
       double scal_width, scal_height;
 
       if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
-         &scal_height) != 0)
+          &scal_height) != 0)
       {
          png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
       }
@@ -1270,7 +1288,7 @@
       png_charp scal_width, scal_height;
 
       if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
-          &scal_height) != 0)
+           &scal_height) != 0)
       {
          png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width,
              scal_height);
@@ -1307,11 +1325,11 @@
          {
             int i;
 
-            printf("\n");
+            fprintf(STDERR,"\n");
             for (i=0; i<num_text; i++)
             {
-               printf("   Text compression[%d]=%d\n",
-                     i, text_ptr[i].compression);
+               fprintf(STDERR,"   Text compression[%d]=%d\n",
+                   i, text_ptr[i].compression);
             }
          }
 
@@ -1348,7 +1366,7 @@
       png_color_16p trans_color;
 
       if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans,
-         &trans_color) != 0)
+          &trans_color) != 0)
       {
          int sample_max = (1 << bit_depth);
          /* libpng doesn't reject a tRNS chunk with out-of-range samples */
@@ -1367,12 +1385,12 @@
    {
       png_unknown_chunkp unknowns;
       int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr,
-         &unknowns);
+          &unknowns);
 
       if (num_unknowns != 0)
       {
          png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
-           num_unknowns);
+             num_unknowns);
 #if PNG_LIBPNG_VER < 10600
          /* Copy the locations from the read_info_ptr.  The automatically
           * generated locations in write_end_info_ptr are wrong prior to 1.6.0
@@ -1382,7 +1400,7 @@
             int i;
             for (i = 0; i < num_unknowns; i++)
               png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
-                unknowns[i].location);
+                  unknowns[i].location);
          }
 #endif
       }
@@ -1402,12 +1420,21 @@
    png_write_info(write_ptr, write_info_ptr);
 
    write_chunks(write_ptr, before_IDAT); /* after PLTE */
+
+   png_write_info(write_ptr, write_end_info_ptr);
+
+   write_chunks(write_ptr, after_IDAT); /* after IDAT */
+
+#ifdef PNG_COMPRESSION_COMPAT
+   /* Test the 'compatibility' setting here, if it is available. */
+   png_set_compression(write_ptr, PNG_COMPRESSION_COMPAT);
+#endif
 #endif
 
 #ifdef SINGLE_ROWBUF_ALLOC
    pngtest_debug("Allocating row buffer...");
    row_buf = (png_bytep)png_malloc(read_ptr,
-      png_get_rowbytes(read_ptr, read_info_ptr));
+       png_get_rowbytes(read_ptr, read_info_ptr));
 
    pngtest_debug1("\t0x%08lx", (unsigned long)row_buf);
 #endif /* SINGLE_ROWBUF_ALLOC */
@@ -1421,10 +1448,10 @@
     */
    if (png_set_interlace_handling(read_ptr) != num_passes)
       png_error(write_ptr,
-            "png_set_interlace_handling(read): wrong pass count ");
+          "png_set_interlace_handling(read): wrong pass count ");
    if (png_set_interlace_handling(write_ptr) != num_passes)
       png_error(write_ptr,
-            "png_set_interlace_handling(write): wrong pass count ");
+          "png_set_interlace_handling(write): wrong pass count ");
 #else /* png_set_interlace_handling not called on either read or write */
 #  define calc_pass_height
 #endif /* not using libpng interlace handling */
@@ -1461,10 +1488,10 @@
          pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
 
          row_buf = (png_bytep)png_malloc(read_ptr,
-            png_get_rowbytes(read_ptr, read_info_ptr));
+             png_get_rowbytes(read_ptr, read_info_ptr));
 
          pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf,
-            (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
+             (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
 
 #endif /* !SINGLE_ROWBUF_ALLOC */
          png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
@@ -1518,11 +1545,11 @@
          {
             int i;
 
-            printf("\n");
+            fprintf(STDERR,"\n");
             for (i=0; i<num_text; i++)
             {
-               printf("   Text compression[%d]=%d\n",
-                     i, text_ptr[i].compression);
+               fprintf(STDERR,"   Text compression[%d]=%d\n",
+                   i, text_ptr[i].compression);
             }
          }
 
@@ -1530,6 +1557,22 @@
       }
    }
 #endif
+#ifdef PNG_READ_eXIf_SUPPORTED
+   {
+      png_bytep exif=NULL;
+      png_uint_32 exif_length;
+
+      if (png_get_eXIf_1(read_ptr, end_info_ptr, &exif_length, &exif) != 0)
+      {
+         if (exif_length > 1)
+            fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1],
+               (unsigned long)exif_length);
+# ifdef PNG_WRITE_eXIf_SUPPORTED
+         png_set_eXIf_1(write_ptr, write_end_info_ptr, exif_length, exif);
+# endif
+      }
+   }
+#endif
 #ifdef PNG_tIME_SUPPORTED
    {
       png_timep mod_time;
@@ -1556,12 +1599,12 @@
    {
       png_unknown_chunkp unknowns;
       int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr,
-         &unknowns);
+          &unknowns);
 
       if (num_unknowns != 0)
       {
          png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
-           num_unknowns);
+             num_unknowns);
 #if PNG_LIBPNG_VER < 10600
          /* Copy the locations from the read_info_ptr.  The automatically
           * generated locations in write_end_info_ptr are wrong prior to 1.6.0
@@ -1571,7 +1614,7 @@
             int i;
             for (i = 0; i < num_unknowns; i++)
               png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
-                unknowns[i].location);
+                  unknowns[i].location);
          }
 #endif
       }
@@ -1605,7 +1648,7 @@
       iwidth = png_get_image_width(write_ptr, write_info_ptr);
       iheight = png_get_image_height(write_ptr, write_info_ptr);
       fprintf(STDERR, "\n Image width = %lu, height = %lu\n",
-         (unsigned long)iwidth, (unsigned long)iheight);
+          (unsigned long)iwidth, (unsigned long)iheight);
    }
 #endif
 
@@ -1638,7 +1681,7 @@
        * above, but this is safe.
        */
       fprintf(STDERR, "\n  %s: %d libpng errors found (%d warnings)",
-         inname, error_count, warning_count);
+          inname, error_count, warning_count);
 
       if (strict != 0)
          return (1);
@@ -1649,14 +1692,14 @@
       else if (unsupported_chunks > 0)
       {
          fprintf(STDERR, "\n  %s: unsupported chunks (%d)%s",
-            inname, unsupported_chunks, strict ? ": IGNORED --strict!" : "");
+             inname, unsupported_chunks, strict ? ": IGNORED --strict!" : "");
       }
 #  endif
 
    else if (warning_count > 0)
    {
       fprintf(STDERR, "\n  %s: %d libpng warnings found",
-         inname, warning_count);
+          inname, warning_count);
 
       if (strict != 0)
          return (1);
@@ -1692,18 +1735,19 @@
          if (num_in != num_out)
          {
             fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
-                    inname, outname);
+                inname, outname);
 
             if (wrote_question == 0 && unsupported_chunks == 0)
             {
                fprintf(STDERR,
-         "   Was %s written with the same maximum IDAT chunk size (%d bytes),",
-                 inname, PNG_ZBUF_SIZE);
+                   "   Was %s written with the same maximum IDAT"
+                   " chunk size (%d bytes),",
+                   inname, PNG_ZBUF_SIZE);
                fprintf(STDERR,
-                 "\n   filtering heuristic (libpng default), compression");
+                   "\n   filtering heuristic (libpng default), compression");
                fprintf(STDERR,
-                 " level (zlib default),\n   and zlib version (%s)?\n\n",
-                 ZLIB_VERSION);
+                   " level (zlib default),\n   and zlib version (%s)?\n\n",
+                   ZLIB_VERSION);
                wrote_question = 1;
             }
 
@@ -1723,17 +1767,18 @@
          if (memcmp(inbuf, outbuf, num_in))
          {
             fprintf(STDERR, "\nFiles %s and %s are different\n", inname,
-               outname);
+                outname);
 
             if (wrote_question == 0 && unsupported_chunks == 0)
             {
                fprintf(STDERR,
-         "   Was %s written with the same maximum IDAT chunk size (%d bytes),",
+                   "   Was %s written with the same maximum"
+                   " IDAT chunk size (%d bytes),",
                     inname, PNG_ZBUF_SIZE);
                fprintf(STDERR,
-                 "\n   filtering heuristic (libpng default), compression");
+                   "\n   filtering heuristic (libpng default), compression");
                fprintf(STDERR,
-                 " level (zlib default),\n   and zlib version (%s)?\n\n",
+                   " level (zlib default),\n   and zlib version (%s)?\n\n",
                  ZLIB_VERSION);
                wrote_question = 1;
             }
@@ -1784,12 +1829,12 @@
    fprintf(STDERR, "%s", png_get_copyright(NULL));
    /* Show the version of libpng used in building the library */
    fprintf(STDERR, " library (%lu):%s",
-      (unsigned long)png_access_version_number(),
-      png_get_header_version(NULL));
+       (unsigned long)png_access_version_number(),
+       png_get_header_version(NULL));
 
    /* Show the version of libpng used in building the application */
    fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
-      PNG_HEADER_VERSION_STRING);
+       PNG_HEADER_VERSION_STRING);
 
    /* Do some consistency checking on the memory allocation settings, I'm
     * not sure this matters, but it is nice to know, the first of these
@@ -1807,7 +1852,7 @@
    if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
    {
       fprintf(STDERR,
-         "Warning: versions are different between png.h and png.c\n");
+          "Warning: versions are different between png.h and png.c\n");
       fprintf(STDERR, "  png.h version: %s\n", PNG_LIBPNG_VER_STRING);
       fprintf(STDERR, "  png.c version: %s\n\n", png_libpng_ver);
       ++ierror;
@@ -1843,6 +1888,7 @@
          inname = argv[2];
          strict++;
          relaxed = 0;
+         multiple=1;
       }
 
       else if (strcmp(argv[1], "--relaxed") == 0)
@@ -1852,6 +1898,17 @@
          inname = argv[2];
          strict = 0;
          relaxed++;
+         multiple=1;
+      }
+      else if (strcmp(argv[1], "--xfail") == 0)
+      {
+         status_dots_requested = 0;
+         verbose = 1;
+         inname = argv[2];
+         strict = 0;
+         xfail++;
+         relaxed++;
+         multiple=1;
       }
 
       else
@@ -1862,26 +1919,26 @@
    }
 
    if (multiple == 0 && argc == 3 + verbose)
-     outname = argv[2 + verbose];
+      outname = argv[2 + verbose];
 
    if ((multiple == 0 && argc > 3 + verbose) ||
        (multiple != 0 && argc < 2))
    {
-     fprintf(STDERR,
-       "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
-        argv[0], argv[0]);
-     fprintf(STDERR,
-       "  reads/writes one PNG file (without -m) or multiple files (-m)\n");
-     fprintf(STDERR,
-       "  with -m %s is used as a temporary file\n", outname);
-     exit(1);
+      fprintf(STDERR,
+          "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
+          argv[0], argv[0]);
+      fprintf(STDERR,
+          "  reads/writes one PNG file (without -m) or multiple files (-m)\n");
+      fprintf(STDERR,
+          "  with -m %s is used as a temporary file\n", outname);
+      exit(1);
    }
 
    if (multiple != 0)
    {
       int i;
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
-      png_alloc_size_t allocation_now = current_allocation;
+      int allocation_now = current_allocation;
 #endif
       for (i=2; i<argc; ++i)
       {
@@ -1895,7 +1952,7 @@
          {
 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
             fprintf(STDERR, "\n PASS (%lu zero samples)\n",
-               (unsigned long)zero_samples);
+                (unsigned long)zero_samples);
 #else
             fprintf(STDERR, " PASS\n");
 #endif
@@ -1909,40 +1966,45 @@
 
          else
          {
-            fprintf(STDERR, " FAIL\n");
-            ierror += kerror;
+            if (xfail)
+              fprintf(STDERR, " XFAIL\n");
+            else
+            {
+              fprintf(STDERR, " FAIL\n");
+              ierror += kerror;
+            }
          }
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
          if (allocation_now != current_allocation)
-            fprintf(STDERR, "MEMORY ERROR: %lu bytes lost\n",
-               (unsigned long)(current_allocation - allocation_now));
+            fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
+                current_allocation - allocation_now);
 
          if (current_allocation != 0)
          {
             memory_infop pinfo = pinformation;
 
-            fprintf(STDERR, "MEMORY ERROR: %lu bytes still allocated\n",
-               (unsigned long)current_allocation);
+            fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
+                current_allocation);
 
             while (pinfo != NULL)
             {
                fprintf(STDERR, " %lu bytes at %p\n",
-                 (unsigned long)pinfo->size,
-                 pinfo->pointer);
+                   (unsigned long)pinfo->size,
+                   pinfo->pointer);
                pinfo = pinfo->next;
             }
          }
 #endif
       }
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
-         fprintf(STDERR, " Current memory allocation: %20lu bytes\n",
-            (unsigned long)current_allocation);
-         fprintf(STDERR, " Maximum memory allocation: %20lu bytes\n",
-            (unsigned long) maximum_allocation);
-         fprintf(STDERR, " Total   memory allocation: %20lu bytes\n",
-            (unsigned long)total_allocation);
-         fprintf(STDERR, "     Number of allocations: %20lu\n",
-            (unsigned long)num_allocations);
+         fprintf(STDERR, " Current memory allocation: %10d bytes\n",
+             current_allocation);
+         fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
+             maximum_allocation);
+         fprintf(STDERR, " Total   memory allocation: %10d bytes\n",
+             total_allocation);
+         fprintf(STDERR, "     Number of allocations: %10d\n",
+             num_allocations);
 #endif
    }
 
@@ -1953,7 +2015,7 @@
       {
          int kerror;
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
-         png_alloc_size_t allocation_now = current_allocation;
+         int allocation_now = current_allocation;
 #endif
          if (i == 1)
             status_dots_requested = 1;
@@ -1977,7 +2039,7 @@
             {
 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
                 fprintf(STDERR, "\n PASS (%lu zero samples)\n",
-                   (unsigned long)zero_samples);
+                    (unsigned long)zero_samples);
 #else
                 fprintf(STDERR, " PASS\n");
 #endif
@@ -1998,39 +2060,44 @@
 #endif
             }
 
-            fprintf(STDERR, " FAIL\n");
-            ierror += kerror;
+            if (xfail)
+              fprintf(STDERR, " XFAIL\n");
+            else
+            {
+              fprintf(STDERR, " FAIL\n");
+              ierror += kerror;
+            }
          }
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
          if (allocation_now != current_allocation)
-             fprintf(STDERR, "MEMORY ERROR: %lu bytes lost\n",
-               (unsigned long)(current_allocation - allocation_now));
+             fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
+                 current_allocation - allocation_now);
 
          if (current_allocation != 0)
          {
              memory_infop pinfo = pinformation;
 
-             fprintf(STDERR, "MEMORY ERROR: %lu bytes still allocated\n",
-                (unsigned long)current_allocation);
+             fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
+                 current_allocation);
 
              while (pinfo != NULL)
              {
                 fprintf(STDERR, " %lu bytes at %p\n",
-                   (unsigned long)pinfo->size, pinfo->pointer);
+                    (unsigned long)pinfo->size, pinfo->pointer);
                 pinfo = pinfo->next;
              }
           }
 #endif
        }
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
-       fprintf(STDERR, " Current memory allocation: %20lu bytes\n",
-          (unsigned long)current_allocation);
-       fprintf(STDERR, " Maximum memory allocation: %20lu bytes\n",
-          (unsigned long)maximum_allocation);
-       fprintf(STDERR, " Total   memory allocation: %20lu bytes\n",
-          (unsigned long)total_allocation);
-       fprintf(STDERR, "     Number of allocations: %20lu\n",
-            (unsigned long)num_allocations);
+       fprintf(STDERR, " Current memory allocation: %10d bytes\n",
+           current_allocation);
+       fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
+           maximum_allocation);
+       fprintf(STDERR, " Total   memory allocation: %10d bytes\n",
+           total_allocation);
+       fprintf(STDERR, "     Number of allocations: %10d\n",
+           num_allocations);
 #endif
    }
 
@@ -2039,13 +2106,13 @@
    t_misc += (t_stop - t_start);
    t_start = t_stop;
    fprintf(STDERR, " CPU time used = %.3f seconds",
-      (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
+       (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
    fprintf(STDERR, " (decoding %.3f,\n",
-      t_decode/(float)CLOCKS_PER_SEC);
+       t_decode/(float)CLOCKS_PER_SEC);
    fprintf(STDERR, "        encoding %.3f ,",
-      t_encode/(float)CLOCKS_PER_SEC);
+       t_encode/(float)CLOCKS_PER_SEC);
    fprintf(STDERR, " other %.3f seconds)\n\n",
-      t_misc/(float)CLOCKS_PER_SEC);
+       t_misc/(float)CLOCKS_PER_SEC);
 #endif
 
    if (ierror == 0)
@@ -2057,19 +2124,19 @@
    dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    fprintf(STDERR, " Default limits:\n");
    fprintf(STDERR, "  width_max  = %lu\n",
-      (unsigned long) png_get_user_width_max(dummy_ptr));
+       (unsigned long) png_get_user_width_max(dummy_ptr));
    fprintf(STDERR, "  height_max = %lu\n",
-      (unsigned long) png_get_user_height_max(dummy_ptr));
+       (unsigned long) png_get_user_height_max(dummy_ptr));
    if (png_get_chunk_cache_max(dummy_ptr) == 0)
       fprintf(STDERR, "  cache_max  = unlimited\n");
    else
       fprintf(STDERR, "  cache_max  = %lu\n",
-         (unsigned long) png_get_chunk_cache_max(dummy_ptr));
+          (unsigned long) png_get_chunk_cache_max(dummy_ptr));
    if (png_get_chunk_malloc_max(dummy_ptr) == 0)
       fprintf(STDERR, "  malloc_max = unlimited\n");
    else
       fprintf(STDERR, "  malloc_max = %lu\n",
-         (unsigned long) png_get_chunk_malloc_max(dummy_ptr));
+          (unsigned long) png_get_chunk_malloc_max(dummy_ptr));
    png_destroy_read_struct(&dummy_ptr, NULL, NULL);
 
    return (int)(ierror != 0);
@@ -2079,11 +2146,11 @@
 main(void)
 {
    fprintf(STDERR,
-      " test ignored because libpng was not built with read support\n");
+       " test ignored because libpng was not built with read support\n");
    /* And skip this test */
-   return SKIP;
+   return PNG_LIBPNG_VER < 10600 ? 0 : 77;
 }
 #endif
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_22 Your_png_h_is_not_version_1_6_22;
+typedef png_libpng_version_1_6_34 Your_png_h_is_not_version_1_6_34;
diff --git a/third_party/libpng/pngtrans.c b/third_party/libpng/pngtrans.c
index 7f8cc455..6882f0f 100644
--- a/third_party/libpng/pngtrans.c
+++ b/third_party/libpng/pngtrans.c
@@ -1,8 +1,8 @@
 
 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
  *
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -172,13 +172,14 @@
                    * size!
                    */
                   png_app_error(png_ptr,
-                     "png_set_filler is invalid for low bit depth gray output");
+                      "png_set_filler is invalid for"
+                      " low bit depth gray output");
                   return;
                }
 
             default:
                png_app_error(png_ptr,
-                  "png_set_filler: inappropriate color type");
+                   "png_set_filler: inappropriate color type");
                return;
          }
 #     else
@@ -513,11 +514,15 @@
          if (at_start != 0) /* Skip initial filler */
             ++sp;
          else          /* Skip initial channel and, for sp, the filler */
-            sp += 2, ++dp;
+         {
+            sp += 2; ++dp;
+         }
 
          /* For a 1 pixel wide image there is nothing to do */
          while (sp < ep)
-            *dp++ = *sp, sp += 2;
+         {
+            *dp++ = *sp; sp += 2;
+         }
 
          row_info->pixel_depth = 8;
       }
@@ -527,10 +532,14 @@
          if (at_start != 0) /* Skip initial filler */
             sp += 2;
          else          /* Skip initial channel and, for sp, the filler */
-            sp += 4, dp += 2;
+         {
+            sp += 4; dp += 2;
+         }
 
          while (sp < ep)
-            *dp++ = *sp++, *dp++ = *sp, sp += 3;
+         {
+            *dp++ = *sp++; *dp++ = *sp; sp += 3;
+         }
 
          row_info->pixel_depth = 16;
       }
@@ -553,11 +562,15 @@
          if (at_start != 0) /* Skip initial filler */
             ++sp;
          else          /* Skip initial channels and, for sp, the filler */
-            sp += 4, dp += 3;
+         {
+            sp += 4; dp += 3;
+         }
 
          /* Note that the loop adds 3 to dp and 4 to sp each time. */
          while (sp < ep)
-            *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
+         {
+            *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
+         }
 
          row_info->pixel_depth = 24;
       }
@@ -567,14 +580,16 @@
          if (at_start != 0) /* Skip initial filler */
             sp += 2;
          else          /* Skip initial channels and, for sp, the filler */
-            sp += 8, dp += 6;
+         {
+            sp += 8; dp += 6;
+         }
 
          while (sp < ep)
          {
             /* Copy 6 bytes, skip 2 */
-            *dp++ = *sp++, *dp++ = *sp++;
-            *dp++ = *sp++, *dp++ = *sp++;
-            *dp++ = *sp++, *dp++ = *sp, sp += 3;
+            *dp++ = *sp++; *dp++ = *sp++;
+            *dp++ = *sp++; *dp++ = *sp++;
+            *dp++ = *sp++; *dp++ = *sp; sp += 3;
          }
 
          row_info->pixel_depth = 48;
@@ -594,7 +609,7 @@
       return; /* The filler channel has gone already */
 
    /* Fix the rowbytes value. */
-   row_info->rowbytes = dp-row;
+   row_info->rowbytes = (png_size_t)(dp-row);
 }
 #endif
 
@@ -692,8 +707,8 @@
        * and this calculation is used because it avoids warnings that other
        * forms produced on either GCC or MSVC.
        */
-      int padding = (-row_info->pixel_depth * row_info->width) & 7;
-      png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
+      int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
+      png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
 
       switch (row_info->bit_depth)
       {
@@ -797,7 +812,7 @@
       (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
    {
       png_app_error(png_ptr,
-            "info change after png_start_read_image or png_read_update_info");
+          "info change after png_start_read_image or png_read_update_info");
       return;
    }
 #endif
diff --git a/third_party/libpng/pngwio.c b/third_party/libpng/pngwio.c
index 586c03b..37c7c3a7 100644
--- a/third_party/libpng/pngwio.c
+++ b/third_party/libpng/pngwio.c
@@ -1,8 +1,8 @@
 
 /* pngwio.c - functions for data output
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -35,7 +35,7 @@
    /* NOTE: write_data_fn must not change the buffer! */
    if (png_ptr->write_data_fn != NULL )
       (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
-         length);
+          length);
 
    else
       png_error(png_ptr, "Call to NULL write function");
diff --git a/third_party/libpng/pngwrite.c b/third_party/libpng/pngwrite.c
index 181a899..e25e5dc 100644
--- a/third_party/libpng/pngwrite.c
+++ b/third_party/libpng/pngwrite.c
@@ -1,8 +1,8 @@
 
 /* pngwrite.c - general routines to write a PNG file
  *
- * Last changed in libpng 1.6.19 [November 12, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -22,7 +22,7 @@
 /* Write out all the unknown chunks for the current given location */
 static void
 write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
-   unsigned int where)
+    unsigned int where)
 {
    if (info_ptr->unknown_chunks_num != 0)
    {
@@ -148,11 +148,11 @@
 #    ifdef PNG_WRITE_sRGB_SUPPORTED
                if ((info_ptr->valid & PNG_INFO_sRGB) != 0)
                   png_app_warning(png_ptr,
-                     "profile matches sRGB but writing iCCP instead");
+                      "profile matches sRGB but writing iCCP instead");
 #     endif
 
             png_write_iCCP(png_ptr, info_ptr->iccp_name,
-               info_ptr->iccp_profile);
+                info_ptr->iccp_profile);
          }
 #     ifdef PNG_WRITE_sRGB_SUPPORTED
          else
@@ -237,6 +237,11 @@
       png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
 #endif
 
+#ifdef PNG_WRITE_eXIf_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_eXIf) != 0)
+      png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif);
+#endif
+
 #ifdef PNG_WRITE_hIST_SUPPORTED
    if ((info_ptr->valid & PNG_INFO_hIST) != 0)
       png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
@@ -383,7 +388,7 @@
       for (i = 0; i < info_ptr->num_text; i++)
       {
          png_debug2(2, "Writing trailer text chunk %d, type %d", i,
-            info_ptr->text[i].compression);
+             info_ptr->text[i].compression);
          /* An internationalized chunk? */
          if (info_ptr->text[i].compression > 0)
          {
@@ -432,6 +437,12 @@
          }
       }
 #endif
+
+#ifdef PNG_WRITE_eXIf_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_eXIf) != 0)
+      png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif);
+#endif
+
 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
       write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT);
 #endif
@@ -666,9 +677,9 @@
 
          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
          {
-            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
-            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
-            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
+            png_uint_32 s0   = (png_uint_32)(*(rp    ) << 8) | *(rp + 1);
+            png_uint_32 s1   = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3);
+            png_uint_32 s2   = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5);
             png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
             png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
             *(rp    ) = (png_byte)(red >> 8);
@@ -693,7 +704,7 @@
       return;
 
    png_debug2(1, "in png_write_row (row %u, pass %d)",
-      png_ptr->row_number, png_ptr->pass);
+       png_ptr->row_number, png_ptr->pass);
 
    /* Initialize transformations and other stuff if first time */
    if (png_ptr->row_number == 0 && png_ptr->pass == 0)
@@ -901,7 +912,7 @@
    if (png_ptr == NULL)
       return;
 
-   png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
+   png_ptr->flush_dist = (nrows < 0 ? 0 : (png_uint_32)nrows);
 }
 
 /* Flush the current output buffers now */
@@ -937,6 +948,10 @@
    png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
    png_free(png_ptr, png_ptr->row_buf);
    png_ptr->row_buf = NULL;
+#ifdef PNG_READ_EXPANDED_SUPPORTED
+   png_free(png_ptr, png_ptr->riffled_palette);
+   png_ptr->riffled_palette = NULL;
+#endif
 #ifdef PNG_WRITE_FILTER_SUPPORTED
    png_free(png_ptr, png_ptr->prev_row);
    png_free(png_ptr, png_ptr->try_row);
@@ -1007,8 +1022,8 @@
          case 5:
          case 6:
          case 7: png_app_error(png_ptr, "Unknown row filter for method 0");
-            /* FALL THROUGH */
 #endif /* WRITE_FILTER */
+            /* FALLTHROUGH */
          case PNG_FILTER_VALUE_NONE:
             png_ptr->do_filter = PNG_FILTER_NONE; break;
 
@@ -1069,7 +1084,7 @@
              * is not available so the filter can't be used.  Just warn here.
              */
             png_app_warning(png_ptr,
-               "png_set_filter: UP/AVG/PAETH cannot be added after start");
+                "png_set_filter: UP/AVG/PAETH cannot be added after start");
             filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
          }
 
@@ -1095,13 +1110,13 @@
 
          if (png_ptr->try_row == NULL)
             png_ptr->try_row = png_voidcast(png_bytep,
-               png_malloc(png_ptr, buf_size));
+                png_malloc(png_ptr, buf_size));
 
          if (num_filters > 1)
          {
             if (png_ptr->tst_row == NULL)
                png_ptr->tst_row = png_voidcast(png_bytep,
-                  png_malloc(png_ptr, buf_size));
+                   png_malloc(png_ptr, buf_size));
          }
       }
       png_ptr->do_filter = (png_byte)filters;
@@ -1525,7 +1540,8 @@
        display->first_row);
    png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
    png_uint_16p row_end;
-   const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
+   const unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ?
+       3 : 1;
    int aindex = 0;
    png_uint_32 y = image->height;
 
@@ -1539,9 +1555,9 @@
          ++output_row;
       }
          else
-            aindex = channels;
+            aindex = (int)channels;
 #     else
-         aindex = channels;
+         aindex = (int)channels;
 #     endif
    }
 
@@ -1554,7 +1570,7 @@
     */
    row_end = output_row + image->width * (channels+1);
 
-   while (y-- > 0)
+   for (; y > 0; --y)
    {
       png_const_uint_16p in_ptr = input_row;
       png_uint_16p out_ptr = output_row;
@@ -1575,7 +1591,7 @@
          if (alpha > 0 && alpha < 65535)
             reciprocal = ((0xffff<<15)+(alpha>>1))/alpha;
 
-         c = channels;
+         c = (int)channels;
          do /* always at least one channel */
          {
             png_uint_16 component = *in_ptr++;
@@ -1610,7 +1626,7 @@
       }
 
       png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row));
-      input_row += display->row_bytes/(sizeof (png_uint_16));
+      input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
    }
 
    return 1;
@@ -1628,7 +1644,7 @@
 
 static png_byte
 png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
-   png_uint_32 reciprocal/*from the above macro*/)
+    png_uint_32 reciprocal/*from the above macro*/)
 {
    /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0
     * is represented as some other value there is more likely to be a
@@ -1683,7 +1699,8 @@
        display->first_row);
    png_bytep output_row = png_voidcast(png_bytep, display->local_row);
    png_uint_32 y = image->height;
-   const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
+   const unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ?
+       3 : 1;
 
    if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
    {
@@ -1700,12 +1717,12 @@
 
       else
 #   endif
-      aindex = channels;
+      aindex = (int)channels;
 
       /* Use row_end in place of a loop counter: */
       row_end = output_row + image->width * (channels+1);
 
-      while (y-- > 0)
+      for (; y > 0; --y)
       {
          png_const_uint_16p in_ptr = input_row;
          png_bytep out_ptr = output_row;
@@ -1723,7 +1740,7 @@
             if (alphabyte > 0 && alphabyte < 255)
                reciprocal = UNP_RECIPROCAL(alpha);
 
-            c = channels;
+            c = (int)channels;
             do /* always at least one channel */
                *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal);
             while (--c > 0);
@@ -1735,7 +1752,7 @@
 
          png_write_row(png_ptr, png_voidcast(png_const_bytep,
              display->local_row));
-         input_row += display->row_bytes/(sizeof (png_uint_16));
+         input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
       } /* while y */
    }
 
@@ -1746,7 +1763,7 @@
        */
       png_bytep row_end = output_row + image->width * channels;
 
-      while (y-- > 0)
+      for (; y > 0; --y)
       {
          png_const_uint_16p in_ptr = input_row;
          png_bytep out_ptr = output_row;
@@ -1760,7 +1777,7 @@
          }
 
          png_write_row(png_ptr, output_row);
-         input_row += display->row_bytes/(sizeof (png_uint_16));
+         input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
       }
    }
 
@@ -1777,7 +1794,7 @@
 
    /* NOTE: the caller must check for cmap != NULL and entries != 0 */
    const png_uint_32 format = image->format;
-   const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
+   const unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
 
 #   if defined(PNG_FORMAT_BGR_SUPPORTED) &&\
       defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED)
@@ -1809,7 +1826,7 @@
       {
          png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap);
 
-         entry += i * channels;
+         entry += (unsigned int)i * channels;
 
          if ((channels & 1) != 0) /* no alpha */
          {
@@ -1848,16 +1865,16 @@
             if (channels >= 3) /* RGB */
             {
                palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)],
-                  alpha, reciprocal);
+                   alpha, reciprocal);
                palette[i].green = png_unpremultiply(entry[afirst + 1], alpha,
-                  reciprocal);
+                   reciprocal);
                palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha,
-                  reciprocal);
+                   reciprocal);
             }
 
             else /* gray */
                palette[i].blue = palette[i].red = palette[i].green =
-                  png_unpremultiply(entry[afirst], alpha, reciprocal);
+                   png_unpremultiply(entry[afirst], alpha, reciprocal);
          }
       }
 
@@ -1865,7 +1882,7 @@
       {
          png_const_bytep entry = png_voidcast(png_const_bytep, cmap);
 
-         entry += i * channels;
+         entry += (unsigned int)i * channels;
 
          switch (channels)
          {
@@ -1873,7 +1890,7 @@
                tRNS[i] = entry[afirst ? 0 : 3];
                if (tRNS[i] < 255)
                   num_trans = i+1;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
             case 3:
                palette[i].blue = entry[afirst + (2 ^ bgr)];
                palette[i].green = entry[afirst + 1];
@@ -1884,7 +1901,7 @@
                tRNS[i] = entry[1 ^ afirst];
                if (tRNS[i] < 255)
                   num_trans = i+1;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
             case 1:
                palette[i].blue = palette[i].red = palette[i].green =
                   entry[afirst];
@@ -1904,20 +1921,20 @@
 #   endif
 
    png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,
-      entries);
+       entries);
 
    if (num_trans > 0)
       png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS,
-         num_trans, NULL);
+          num_trans, NULL);
 
-   image->colormap_entries = entries;
+   image->colormap_entries = (png_uint_32)entries;
 }
 
 static int
 png_image_write_main(png_voidp argument)
 {
    png_image_write_control *display = png_voidcast(png_image_write_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    png_inforp info_ptr = image->opaque->info_ptr;
@@ -1927,7 +1944,7 @@
    int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
    int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
    int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);
-   int write_16bit = linear && !colormap && (display->convert_to_8bit == 0);
+   int write_16bit = linear && (display->convert_to_8bit == 0);
 
 #   ifdef PNG_BENIGN_ERRORS_SUPPORTED
       /* Make sure we error out on any bad situation */
@@ -1940,7 +1957,7 @@
    {
       const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
 
-      if (image->width <= 0x7FFFFFFFU/channels) /* no overflow */
+      if (image->width <= 0x7fffffffU/channels) /* no overflow */
       {
          png_uint_32 check;
          const png_uint_32 png_row_stride = image->width * channels;
@@ -1949,10 +1966,10 @@
             display->row_stride = (png_int_32)/*SAFE*/png_row_stride;
 
          if (display->row_stride < 0)
-            check = -display->row_stride;
+            check = (png_uint_32)(-display->row_stride);
 
          else
-            check = display->row_stride;
+            check = (png_uint_32)display->row_stride;
 
          if (check >= png_row_stride)
          {
@@ -1960,7 +1977,7 @@
              * limits the whole image size to 32 bits for API compatibility with
              * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
              */
-            if (image->height > 0xFFFFFFFF/png_row_stride)
+            if (image->height > 0xffffffffU/png_row_stride)
                png_error(image->opaque->png_ptr, "memory image too large");
          }
 
@@ -1980,24 +1997,24 @@
          png_uint_32 entries = image->colormap_entries;
 
          png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
-            entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
-            PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
-            PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+             entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
+             PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
+             PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
 
          png_image_set_PLTE(display);
       }
 
       else
          png_error(image->opaque->png_ptr,
-            "no color-map for color-mapped image");
+             "no color-map for color-mapped image");
    }
 
    else
       png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
-         write_16bit ? 16 : 8,
-         ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
-         ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
-         PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+          write_16bit ? 16 : 8,
+          ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
+          ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
+          PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
 
    /* Counter-intuitively the data transformations must be called *after*
     * png_write_info, not before as in the read code, but the 'set' functions
@@ -2012,11 +2029,11 @@
 
       if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
          png_set_cHRM_fixed(png_ptr, info_ptr,
-            /* color      x       y */
-            /* white */ 31270, 32900,
-            /* red   */ 64000, 33000,
-            /* green */ 30000, 60000,
-            /* blue  */ 15000,  6000
+             /* color      x       y */
+             /* white */ 31270, 32900,
+             /* red   */ 64000, 33000,
+             /* green */ 30000, 60000,
+             /* blue  */ 15000,  6000
          );
    }
 
@@ -2110,7 +2127,7 @@
        (colormap == 0 && display->convert_to_8bit != 0))
    {
       png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
-         png_get_rowbytes(png_ptr, info_ptr)));
+          png_get_rowbytes(png_ptr, info_ptr)));
       int result;
 
       display->local_row = row;
@@ -2136,7 +2153,7 @@
       ptrdiff_t row_bytes = display->row_bytes;
       png_uint_32 y = image->height;
 
-      while (y-- > 0)
+      for (; y > 0; --y)
       {
          png_write_row(png_ptr, row);
          row += row_bytes;
@@ -2150,10 +2167,10 @@
 
 static void (PNGCBAPI
 image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data,
-   png_size_t size)
+    png_size_t size)
 {
    png_image_write_control *display = png_voidcast(png_image_write_control*,
-      png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/);
+       png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/);
    const png_alloc_size_t ob = display->output_bytes;
 
    /* Check for overflow; this should never happen: */
@@ -2184,22 +2201,22 @@
 png_image_write_memory(png_voidp argument)
 {
    png_image_write_control *display = png_voidcast(png_image_write_control*,
-      argument);
+       argument);
 
    /* The rest of the memory-specific init and write_main in an error protected
     * environment.  This case needs to use callbacks for the write operations
     * since libpng has no built in support for writing to memory.
     */
    png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/,
-         image_memory_write, image_memory_flush);
+       image_memory_write, image_memory_flush);
 
    return png_image_write_main(display);
 }
 
 int PNGAPI
 png_image_write_to_memory(png_imagep image, void *memory,
-   png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit,
-   const void *buffer, png_int_32 row_stride, const void *colormap)
+    png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit,
+    const void *buffer, png_int_32 row_stride, const void *colormap)
 {
    /* Write the image to the given buffer, or count the bytes if it is NULL */
    if (image != NULL && image->version == PNG_IMAGE_VERSION)
@@ -2251,12 +2268,12 @@
 
       else
          return png_image_error(image,
-            "png_image_write_to_memory: invalid argument");
+             "png_image_write_to_memory: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION");
+          "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION");
 
    else
       return 0;
@@ -2265,7 +2282,7 @@
 #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
 int PNGAPI
 png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
-   const void *buffer, png_int_32 row_stride, const void *colormap)
+    const void *buffer, png_int_32 row_stride, const void *colormap)
 {
    /* Write the image to the given (FILE*). */
    if (image != NULL && image->version == PNG_IMAGE_VERSION)
@@ -2301,12 +2318,12 @@
 
       else
          return png_image_error(image,
-            "png_image_write_to_stdio: invalid argument");
+             "png_image_write_to_stdio: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
+          "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
 
    else
       return 0;
@@ -2314,8 +2331,8 @@
 
 int PNGAPI
 png_image_write_to_file(png_imagep image, const char *file_name,
-   int convert_to_8bit, const void *buffer, png_int_32 row_stride,
-   const void *colormap)
+    int convert_to_8bit, const void *buffer, png_int_32 row_stride,
+    const void *colormap)
 {
    /* Write the image to the named file. */
    if (image != NULL && image->version == PNG_IMAGE_VERSION)
@@ -2327,7 +2344,7 @@
          if (fp != NULL)
          {
             if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
-               row_stride, colormap) != 0)
+                row_stride, colormap) != 0)
             {
                int error; /* from fflush/fclose */
 
@@ -2368,12 +2385,12 @@
 
       else
          return png_image_error(image,
-            "png_image_write_to_file: invalid argument");
+             "png_image_write_to_file: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
+          "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
 
    else
       return 0;
diff --git a/third_party/libpng/pngwtran.c b/third_party/libpng/pngwtran.c
index 038a2ef..377b43e5 100644
--- a/third_party/libpng/pngwtran.c
+++ b/third_party/libpng/pngwtran.c
@@ -1,8 +1,8 @@
 
 /* pngwtran.c - transforms the data in a row for PNG writers
  *
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.26 [October 20, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -177,7 +177,7 @@
    if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
    {
       int shift_start[4], shift_dec[4];
-      int channels = 0;
+      unsigned int channels = 0;
 
       if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
       {
@@ -525,7 +525,7 @@
 #ifdef PNG_WRITE_FILLER_SUPPORTED
    if ((png_ptr->transformations & PNG_FILLER) != 0)
       png_do_strip_channel(row_info, png_ptr->row_buf + 1,
-         !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
+          !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
 #endif
 
 #ifdef PNG_WRITE_PACKSWAP_SUPPORTED
@@ -549,7 +549,7 @@
 #ifdef PNG_WRITE_SHIFT_SUPPORTED
    if ((png_ptr->transformations & PNG_SHIFT) != 0)
       png_do_shift(row_info, png_ptr->row_buf + 1,
-          &(png_ptr->shift));
+           &(png_ptr->shift));
 #endif
 
 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
diff --git a/third_party/libpng/pngwutil.c b/third_party/libpng/pngwutil.c
index ca8a03ad..0d4fb133 100644
--- a/third_party/libpng/pngwutil.c
+++ b/third_party/libpng/pngwutil.c
@@ -1,8 +1,8 @@
 
 /* pngwutil.c - utilities to write a PNG file
  *
- * Last changed in libpng 1.6.22 [May 26, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -59,7 +59,7 @@
 
    /* Write the rest of the 8 byte signature */
    png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
-      (png_size_t)(8 - png_ptr->sig_bytes));
+       (png_size_t)(8 - png_ptr->sig_bytes));
 
    if (png_ptr->sig_bytes < 3)
       png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
@@ -174,7 +174,7 @@
  */
 static void
 png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
-   png_const_bytep data, png_size_t length)
+    png_const_bytep data, png_size_t length)
 {
    if (png_ptr == NULL)
       return;
@@ -191,10 +191,10 @@
 /* This is the API that calls the internal function above. */
 void PNGAPI
 png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,
-   png_const_bytep data, png_size_t length)
+    png_const_bytep data, png_size_t length)
 {
    png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
-      length);
+       length);
 }
 
 /* This is used below to find the size of an image to pass to png_deflate_claim,
@@ -291,7 +291,7 @@
 /* Initialize the compressor for the appropriate type of compression. */
 static int
 png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
-   png_alloc_size_t data_size)
+    png_alloc_size_t data_size)
 {
    if (png_ptr->zowner != 0)
    {
@@ -408,7 +408,7 @@
       png_ptr->zstream.avail_out = 0;
 
       /* Now initialize if required, setting the new parameters, otherwise just
-       * to a simple reset to the previous parameters.
+       * do a simple reset to the previous parameters.
        */
       if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
          ret = deflateReset(&png_ptr->zstream);
@@ -416,7 +416,7 @@
       else
       {
          ret = deflateInit2(&png_ptr->zstream, level, method, windowBits,
-            memLevel, strategy);
+             memLevel, strategy);
 
          if (ret == Z_OK)
             png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
@@ -477,7 +477,7 @@
 
 static void
 png_text_compress_init(compression_state *comp, png_const_bytep input,
-   png_alloc_size_t input_len)
+    png_alloc_size_t input_len)
 {
    comp->input = input;
    comp->input_len = input_len;
@@ -487,7 +487,7 @@
 /* Compress the data in the compression state input */
 static int
 png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
-   compression_state *comp, png_uint_32 prefix_len)
+    compression_state *comp, png_uint_32 prefix_len)
 {
    int ret;
 
@@ -579,7 +579,7 @@
 
          /* Compress the data */
          ret = deflate(&png_ptr->zstream,
-            input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
+             input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
 
          /* Claw back input data that was not consumed (because avail_in is
           * reset above every time round the loop).
@@ -675,6 +675,7 @@
     int interlace_type)
 {
    png_byte buf[13]; /* Buffer to store the IHDR info */
+   int is_invalid_depth;
 
    png_debug(1, "in png_write_IHDR");
 
@@ -700,11 +701,11 @@
          break;
 
       case PNG_COLOR_TYPE_RGB:
+         is_invalid_depth = (bit_depth != 8);
 #ifdef PNG_WRITE_16BIT_SUPPORTED
-         if (bit_depth != 8 && bit_depth != 16)
-#else
-         if (bit_depth != 8)
+         is_invalid_depth = (is_invalid_depth && bit_depth != 16);
 #endif
+         if (is_invalid_depth)
             png_error(png_ptr, "Invalid bit depth for RGB image");
 
          png_ptr->channels = 3;
@@ -726,18 +727,22 @@
          break;
 
       case PNG_COLOR_TYPE_GRAY_ALPHA:
-         if (bit_depth != 8 && bit_depth != 16)
+         is_invalid_depth = (bit_depth != 8);
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+         is_invalid_depth = (is_invalid_depth && bit_depth != 16);
+#endif
+         if (is_invalid_depth)
             png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
 
          png_ptr->channels = 2;
          break;
 
       case PNG_COLOR_TYPE_RGB_ALPHA:
+         is_invalid_depth = (bit_depth != 8);
 #ifdef PNG_WRITE_16BIT_SUPPORTED
-         if (bit_depth != 8 && bit_depth != 16)
-#else
-         if (bit_depth != 8)
+         is_invalid_depth = (is_invalid_depth && bit_depth != 16);
 #endif
+         if (is_invalid_depth)
             png_error(png_ptr, "Invalid bit depth for RGBA image");
 
          png_ptr->channels = 4;
@@ -925,7 +930,7 @@
  */
 void /* PRIVATE */
 png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
-   png_alloc_size_t input_len, int flush)
+    png_alloc_size_t input_len, int flush)
 {
    if (png_ptr->zowner != png_IDAT)
    {
@@ -937,7 +942,7 @@
       if (png_ptr->zbuffer_list == NULL)
       {
          png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp,
-            png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
+             png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
          png_ptr->zbuffer_list->next = NULL;
       }
 
@@ -998,7 +1003,8 @@
                optimize_cmf(data, png_image_size(png_ptr));
 #endif
 
-         png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+         if (size > 0)
+            png_write_complete_chunk(png_ptr, png_IDAT, data, size);
          png_ptr->mode |= PNG_HAVE_IDAT;
 
          png_ptr->zstream.next_out = data;
@@ -1044,7 +1050,8 @@
             optimize_cmf(data, png_image_size(png_ptr));
 #endif
 
-         png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+         if (size > 0)
+            png_write_complete_chunk(png_ptr, png_IDAT, data, size);
          png_ptr->zstream.avail_out = 0;
          png_ptr->zstream.next_out = NULL;
          png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
@@ -1176,7 +1183,7 @@
    png_byte new_name[80];
    png_byte entrybuf[10];
    png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
-   png_size_t palette_size = entry_size * spalette->nentries;
+   png_size_t palette_size = entry_size * (png_size_t)spalette->nentries;
    png_sPLT_entryp ep;
 #ifndef PNG_POINTER_INDEXING_SUPPORTED
    int i;
@@ -1358,7 +1365,7 @@
 
       /* Write the chunk out as it is */
       png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
-         (png_size_t)num_trans);
+          (png_size_t)num_trans);
    }
 
    else if (color_type == PNG_COLOR_TYPE_GRAY)
@@ -1389,7 +1396,7 @@
 #endif
       {
          png_app_warning(png_ptr,
-           "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
+             "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
          return;
       }
 
@@ -1441,7 +1448,8 @@
 #endif
       {
          png_warning(png_ptr,
-             "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
+             "Ignoring attempt to write 16-bit bKGD chunk "
+             "when bit_depth is 8");
 
          return;
       }
@@ -1465,6 +1473,28 @@
 }
 #endif
 
+#ifdef PNG_WRITE_eXIf_SUPPORTED
+/* Write the Exif data */
+void /* PRIVATE */
+png_write_eXIf(png_structrp png_ptr, png_bytep exif, int num_exif)
+{
+   int i;
+   png_byte buf[1];
+
+   png_debug(1, "in png_write_eXIf");
+
+   png_write_chunk_header(png_ptr, png_eXIf, (png_uint_32)(num_exif));
+
+   for (i = 0; i < num_exif; i++)
+   {
+      buf[0] = exif[i];
+      png_write_chunk_data(png_ptr, buf, (png_size_t)1);
+   }
+
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
 #ifdef PNG_WRITE_hIST_SUPPORTED
 /* Write the histogram */
 void /* PRIVATE */
@@ -1571,7 +1601,7 @@
 
    /* Compute the compressed data; do it now for the length */
    png_text_compress_init(&comp, (png_const_bytep)text,
-      text == NULL ? 0 : strlen(text));
+       text == NULL ? 0 : strlen(text));
 
    if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)
       png_error(png_ptr, png_ptr->zstream.msg);
@@ -1742,7 +1772,7 @@
    total_len = purpose_len + units_len + 10;
 
    params_len = (png_size_tp)png_malloc(png_ptr,
-       (png_alloc_size_t)(nparams * (sizeof (png_size_t))));
+       (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (png_size_t))));
 
    /* Find the length of each parameter, making sure we don't count the
     * null terminator for the last parameter.
@@ -1941,7 +1971,7 @@
     */
    if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0)
       png_ptr->prev_row = png_voidcast(png_bytep,
-         png_calloc(png_ptr, buf_size));
+          png_calloc(png_ptr, buf_size));
 #endif /* WRITE_FILTER */
 
 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
@@ -2244,7 +2274,7 @@
  */
 static void /* PRIVATE */
 png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
-   png_size_t row_bytes);
+    png_size_t row_bytes);
 
 #ifdef PNG_WRITE_FILTER_SUPPORTED
 static png_size_t /* PRIVATE */
@@ -2254,7 +2284,7 @@
    png_bytep rp, dp, lp;
    png_size_t i;
    png_size_t sum = 0;
-   int v;
+   unsigned int v;
 
    png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
 
@@ -2262,14 +2292,22 @@
         i++, rp++, dp++)
    {
       v = *dp = *rp;
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
    }
 
    for (lp = png_ptr->row_buf + 1; i < row_bytes;
       i++, rp++, lp++, dp++)
    {
       v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
 
       if (sum > lmins)  /* We are already worse, don't continue. */
         break;
@@ -2307,7 +2345,7 @@
    png_bytep rp, dp, pp;
    png_size_t i;
    png_size_t sum = 0;
-   int v;
+   unsigned int v;
 
    png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
 
@@ -2316,7 +2354,11 @@
        i++, rp++, pp++, dp++)
    {
       v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
 
       if (sum > lmins)  /* We are already worse, don't continue. */
         break;
@@ -2342,21 +2384,25 @@
 
 static png_size_t /* PRIVATE */
 png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
-      const png_size_t row_bytes, const png_size_t lmins)
+    const png_size_t row_bytes, const png_size_t lmins)
 {
    png_bytep rp, dp, pp, lp;
    png_uint_32 i;
    png_size_t sum = 0;
-   int v;
+   unsigned int v;
 
    png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
 
    for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
-        pp = png_ptr->prev_row + 1; i < bpp; i++)
+       pp = png_ptr->prev_row + 1; i < bpp; i++)
    {
       v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
 
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
    }
 
    for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
@@ -2364,7 +2410,11 @@
       v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
           & 0xff);
 
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
 
       if (sum > lmins)  /* We are already worse, don't continue. */
         break;
@@ -2374,7 +2424,7 @@
 }
 static void /* PRIVATE */
 png_setup_avg_row_only(png_structrp png_ptr, const png_uint_32 bpp,
-      const png_size_t row_bytes)
+    const png_size_t row_bytes)
 {
    png_bytep rp, dp, pp, lp;
    png_uint_32 i;
@@ -2382,7 +2432,7 @@
    png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
 
    for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
-        pp = png_ptr->prev_row + 1; i < bpp; i++)
+       pp = png_ptr->prev_row + 1; i < bpp; i++)
    {
       *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
    }
@@ -2401,7 +2451,7 @@
    png_bytep rp, dp, pp, cp, lp;
    png_size_t i;
    png_size_t sum = 0;
-   int v;
+   unsigned int v;
 
    png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
 
@@ -2410,7 +2460,11 @@
    {
       v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
 
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
    }
 
    for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
@@ -2439,7 +2493,11 @@
 
       v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
 
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
 
       if (sum > lmins)  /* We are already worse, don't continue. */
         break;
@@ -2548,7 +2606,7 @@
       /* Overflow can occur in the calculation, just select the lowest set
        * filter.
        */
-      filter_to_do &= -filter_to_do;
+      filter_to_do &= 0U-filter_to_do;
    }
    else if ((filter_to_do & PNG_FILTER_NONE) != 0 &&
          filter_to_do != PNG_FILTER_NONE)
@@ -2559,13 +2617,17 @@
       png_bytep rp;
       png_size_t sum = 0;
       png_size_t i;
-      int v;
+      unsigned int v;
 
       {
          for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
          {
             v = *rp;
+#ifdef PNG_USE_ABS
+            sum += 128 - abs((int)v - 128);
+#else
             sum += (v < 128) ? v : 256 - v;
+#endif
          }
       }
 
@@ -2652,7 +2714,7 @@
    }
 
    /* Paeth filter */
-   if ((filter_to_do == PNG_FILTER_PAETH) != 0)
+   if (filter_to_do == PNG_FILTER_PAETH)
    {
       png_setup_paeth_row_only(png_ptr, bpp, row_bytes);
       best_row = png_ptr->try_row;
@@ -2686,7 +2748,7 @@
 /* Do the actual writing of a previously filtered row. */
 static void
 png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
-   png_size_t full_row_length/*includes filter byte*/)
+    png_size_t full_row_length/*includes filter byte*/)
 {
    png_debug(1, "in png_write_filtered_row");
 
diff --git a/third_party/sqlite/amalgamation/sqlite3.c b/third_party/sqlite/amalgamation/sqlite3.c
index 37aace7..3b5b9c0 100644
--- a/third_party/sqlite/amalgamation/sqlite3.c
+++ b/third_party/sqlite/amalgamation/sqlite3.c
@@ -146592,9 +146592,9 @@
 
 #ifdef DEFAULT_ENABLE_RECOVER
   /* Initialize recover virtual table for testing. */
-  extern int recoverVtableInit(sqlite3 *db);
+  extern int chrome_sqlite3_recoverVtableInit(sqlite3 *db);
   if( !db->mallocFailed && rc==SQLITE_OK ){
-    rc = recoverVtableInit(db);
+    rc = chrome_sqlite3_recoverVtableInit(db);
   }
 #endif
 
diff --git a/third_party/sqlite/patches/0004-Virtual-table-supporting-recovery-of-corrupted-datab.patch b/third_party/sqlite/patches/0004-Virtual-table-supporting-recovery-of-corrupted-datab.patch
index 5175f72..09290b4e9 100644
--- a/third_party/sqlite/patches/0004-Virtual-table-supporting-recovery-of-corrupted-datab.patch
+++ b/third_party/sqlite/patches/0004-Virtual-table-supporting-recovery-of-corrupted-datab.patch
@@ -73,9 +73,9 @@
 
 +#ifdef DEFAULT_ENABLE_RECOVER
 +  /* Initialize recover virtual table for testing. */
-+  extern int recoverVtableInit(sqlite3 *db);
++  extern int chrome_sqlite3_recoverVtableInit(sqlite3 *db);
 +  if( !db->mallocFailed && rc==SQLITE_OK ){
-+    rc = recoverVtableInit(db);
++    rc = chrome_sqlite3_recoverVtableInit(db);
 +  }
 +#endif
 +
@@ -2071,7 +2071,7 @@
 +};
 +
 +SQLITE_API
-+int recoverVtableInit(sqlite3 *db){
++int chrome_sqlite3_recoverVtableInit(sqlite3 *db){
 +  return sqlite3_create_module_v2(db, "recover", &recoverModule, NULL, 0);
 +}
 +
@@ -2382,7 +2382,7 @@
 +** selected users to enable it (currently sql/recovery.cc).
 +*/
 +SQLITE_API
-+int recoverVtableInit(sqlite3 *db);
++int chrome_sqlite3_recoverVtableInit(sqlite3 *db);
 +
 +#ifdef __cplusplus
 +}  /* End of the 'extern "C"' block */
diff --git a/third_party/sqlite/src/src/main.c b/third_party/sqlite/src/src/main.c
index aaf30bb..5a4ebfa 100644
--- a/third_party/sqlite/src/src/main.c
+++ b/third_party/sqlite/src/src/main.c
@@ -3054,9 +3054,9 @@
 
 #ifdef DEFAULT_ENABLE_RECOVER
   /* Initialize recover virtual table for testing. */
-  extern int recoverVtableInit(sqlite3 *db);
+  extern int chrome_sqlite3_recoverVtableInit(sqlite3 *db);
   if( !db->mallocFailed && rc==SQLITE_OK ){
-    rc = recoverVtableInit(db);
+    rc = chrome_sqlite3_recoverVtableInit(db);
   }
 #endif
 
diff --git a/third_party/sqlite/src/src/recover.c b/third_party/sqlite/src/src/recover.c
index c22fd4d..ba239a5 100644
--- a/third_party/sqlite/src/src/recover.c
+++ b/third_party/sqlite/src/src/recover.c
@@ -1981,7 +1981,7 @@
 };
 
 SQLITE_API
-int recoverVtableInit(sqlite3 *db){
+int chrome_sqlite3_recoverVtableInit(sqlite3 *db){
   return sqlite3_create_module_v2(db, "recover", &recoverModule, NULL, 0);
 }
 
diff --git a/third_party/sqlite/src/src/recover.h b/third_party/sqlite/src/src/recover.h
index 691f2fd..5bf50c8 100644
--- a/third_party/sqlite/src/src/recover.h
+++ b/third_party/sqlite/src/src/recover.h
@@ -16,7 +16,7 @@
 ** selected users to enable it (currently sql/recovery.cc).
 */
 SQLITE_API
-int recoverVtableInit(sqlite3 *db);
+int chrome_sqlite3_recoverVtableInit(sqlite3* db);
 
 #ifdef __cplusplus
 }  /* End of the 'extern "C"' block */
diff --git a/third_party/zlib/google/zip.cc b/third_party/zlib/google/zip.cc
index 89330d6..8ad2941c 100644
--- a/third_party/zlib/google/zip.cc
+++ b/third_party/zlib/google/zip.cc
@@ -12,6 +12,7 @@
 #include "base/files/file.h"
 #include "base/files/file_enumerator.h"
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/string_util.h"
 #include "build/build_config.h"
 #include "third_party/zlib/google/zip_internal.h"
@@ -33,6 +34,20 @@
   return !IsHiddenFile(file_path);
 }
 
+// Creates a directory at |extract_dir|/|entry_path|, including any parents.
+bool CreateDirectory(const base::FilePath& extract_dir,
+                     const base::FilePath& entry_path) {
+  return base::CreateDirectory(extract_dir.Append(entry_path));
+}
+
+// Creates a WriterDelegate that can write a file at |extract_dir|/|entry_path|.
+std::unique_ptr<WriterDelegate> CreateFilePathWriterDelegate(
+    const base::FilePath& extract_dir,
+    const base::FilePath& entry_path) {
+  return std::make_unique<FilePathWriterDelegate>(
+      extract_dir.Append(entry_path));
+}
+
 class DirectFileAccessor : public FileAccessor {
  public:
   explicit DirectFileAccessor(base::FilePath src_dir) : src_dir_(src_dir) {}
@@ -166,30 +181,52 @@
                              const base::FilePath& dest_dir,
                              const FilterCallback& filter_cb,
                              bool log_skipped_files) {
-  ZipReader reader;
-  if (!reader.Open(src_file)) {
+  base::File file(src_file, base::File::FLAG_OPEN | base::File::FLAG_READ);
+  if (!file.IsValid()) {
     DLOG(WARNING) << "Failed to open " << src_file.value();
     return false;
   }
+  return UnzipWithFilterAndWriters(
+      file.GetPlatformFile(),
+      base::BindRepeating(&CreateFilePathWriterDelegate, dest_dir),
+      base::BindRepeating(&CreateDirectory, dest_dir), filter_cb,
+      log_skipped_files);
+}
+
+bool UnzipWithFilterAndWriters(const base::PlatformFile& src_file,
+                               const WriterFactory& writer_factory,
+                               const DirectoryCreator& directory_creator,
+                               const FilterCallback& filter_cb,
+                               bool log_skipped_files) {
+  ZipReader reader;
+  if (!reader.OpenFromPlatformFile(src_file)) {
+    DLOG(WARNING) << "Failed to open src_file " << src_file;
+    return false;
+  }
   while (reader.HasMore()) {
     if (!reader.OpenCurrentEntryInZip()) {
       DLOG(WARNING) << "Failed to open the current file in zip";
       return false;
     }
+    const base::FilePath& entry_path = reader.current_entry_info()->file_path();
     if (reader.current_entry_info()->is_unsafe()) {
-      DLOG(WARNING) << "Found an unsafe file in zip "
-                    << reader.current_entry_info()->file_path().value();
+      DLOG(WARNING) << "Found an unsafe file in zip " << entry_path;
       return false;
     }
-    if (filter_cb.Run(reader.current_entry_info()->file_path())) {
-      if (!reader.ExtractCurrentEntryIntoDirectory(dest_dir)) {
-        DLOG(WARNING) << "Failed to extract "
-                      << reader.current_entry_info()->file_path().value();
-        return false;
+    if (filter_cb.Run(entry_path)) {
+      if (reader.current_entry_info()->is_directory()) {
+        if (!directory_creator.Run(entry_path))
+          return false;
+      } else {
+        std::unique_ptr<WriterDelegate> writer = writer_factory.Run(entry_path);
+        if (!reader.ExtractCurrentEntry(writer.get(),
+                                        std::numeric_limits<uint64_t>::max())) {
+          DLOG(WARNING) << "Failed to extract " << entry_path;
+          return false;
+        }
       }
     } else if (log_skipped_files) {
-      DLOG(WARNING) << "Skipped file "
-                    << reader.current_entry_info()->file_path().value();
+      DLOG(WARNING) << "Skipped file " << entry_path;
     }
 
     if (!reader.AdvanceToNextEntry()) {
diff --git a/third_party/zlib/google/zip.h b/third_party/zlib/google/zip.h
index 77d1e8ee..7458be0 100644
--- a/third_party/zlib/google/zip.h
+++ b/third_party/zlib/google/zip.h
@@ -19,6 +19,8 @@
 
 namespace zip {
 
+class WriterDelegate;
+
 // Abstraction for file access operation required by Zip().
 // Can be passed to the ZipParams for providing custom access to the files,
 // for example over IPC.
@@ -156,6 +158,21 @@
                              const FilterCallback& filter_cb,
                              bool log_skipped_files);
 
+// Unzip the contents of zip_file, using the writers provided by writer_factory.
+// For each file in zip_file, include it only if the callback |filter_cb|
+// returns true. Otherwise omit it.
+// If |log_skipped_files| is true, files skipped during extraction are printed
+// to debug log.
+typedef base::RepeatingCallback<std::unique_ptr<WriterDelegate>(
+    const base::FilePath&)>
+    WriterFactory;
+typedef base::RepeatingCallback<bool(const base::FilePath&)> DirectoryCreator;
+bool UnzipWithFilterAndWriters(const base::PlatformFile& zip_file,
+                               const WriterFactory& writer_factory,
+                               const DirectoryCreator& directory_creator,
+                               const FilterCallback& filter_cb,
+                               bool log_skipped_files);
+
 // Unzip the contents of zip_file into dest_dir.
 bool Unzip(const base::FilePath& zip_file, const base::FilePath& dest_dir);
 
diff --git a/third_party/zlib/google/zip_reader.cc b/third_party/zlib/google/zip_reader.cc
index 08c10b6..cca9c46 100644
--- a/third_party/zlib/google/zip_reader.cc
+++ b/third_party/zlib/google/zip_reader.cc
@@ -30,54 +30,6 @@
 
 namespace {
 
-// FilePathWriterDelegate ------------------------------------------------------
-
-// A writer delegate that writes a file at a given path.
-class FilePathWriterDelegate : public WriterDelegate {
- public:
-  explicit FilePathWriterDelegate(const base::FilePath& output_file_path);
-  ~FilePathWriterDelegate() override;
-
-  // WriterDelegate methods:
-
-  // Creates the output file and any necessary intermediate directories.
-  bool PrepareOutput() override;
-
-  // Writes |num_bytes| bytes of |data| to the file, returning false if not all
-  // bytes could be written.
-  bool WriteBytes(const char* data, int num_bytes) override;
-
- private:
-  base::FilePath output_file_path_;
-  base::File file_;
-
-  DISALLOW_COPY_AND_ASSIGN(FilePathWriterDelegate);
-};
-
-FilePathWriterDelegate::FilePathWriterDelegate(
-    const base::FilePath& output_file_path)
-    : output_file_path_(output_file_path) {
-}
-
-FilePathWriterDelegate::~FilePathWriterDelegate() {
-}
-
-bool FilePathWriterDelegate::PrepareOutput() {
-  // We can't rely on parent directory entries being specified in the
-  // zip, so we make sure they are created.
-  if (!base::CreateDirectory(output_file_path_.DirName()))
-    return false;
-
-  file_.Initialize(output_file_path_,
-                   base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
-  return file_.IsValid();
-}
-
-bool FilePathWriterDelegate::WriteBytes(const char* data, int num_bytes) {
-  return num_bytes == file_.WriteAtCurrentPos(data, num_bytes);
-}
-
-
 // StringWriterDelegate --------------------------------------------------------
 
 // A writer delegate that writes no more than |max_read_bytes| to a given
@@ -96,6 +48,8 @@
   // if |num_bytes| will cause the string to exceed |max_read_bytes|.
   bool WriteBytes(const char* data, int num_bytes) override;
 
+  void SetTimeModified(const base::Time& time) override;
+
  private:
   size_t max_read_bytes_;
   std::string* output_;
@@ -123,6 +77,10 @@
   return true;
 }
 
+void StringWriterDelegate::SetTimeModified(const base::Time& time) {
+  // Do nothing.
+}
+
 }  // namespace
 
 // TODO(satorux): The implementation assumes that file names in zip files
@@ -273,22 +231,6 @@
   return true;
 }
 
-bool ZipReader::LocateAndOpenEntry(const base::FilePath& path_in_zip) {
-  DCHECK(zip_file_);
-
-  current_entry_info_.reset();
-  reached_end_ = false;
-  const int kDefaultCaseSensivityOfOS = 0;
-  const int result = unzLocateFile(zip_file_,
-                                   path_in_zip.AsUTF8Unsafe().c_str(),
-                                   kDefaultCaseSensivityOfOS);
-  if (result != UNZ_OK)
-    return false;
-
-  // Then Open the entry.
-  return OpenCurrentEntryInZip();
-}
-
 bool ZipReader::ExtractCurrentEntry(WriterDelegate* delegate,
                                     uint64_t num_bytes_to_extract) const {
   DCHECK(zip_file_);
@@ -331,32 +273,12 @@
 
   unzCloseCurrentFile(zip_file_);
 
-  return entire_file_extracted;
-}
-
-bool ZipReader::ExtractCurrentEntryToFilePath(
-    const base::FilePath& output_file_path) const {
-  DCHECK(zip_file_);
-
-  // If this is a directory, just create it and return.
-  if (current_entry_info()->is_directory())
-    return base::CreateDirectory(output_file_path);
-
-  bool success = false;
-  {
-    FilePathWriterDelegate writer(output_file_path);
-    success =
-        ExtractCurrentEntry(&writer, std::numeric_limits<uint64_t>::max());
-  }
-
-  if (success &&
+  if (entire_file_extracted &&
       current_entry_info()->last_modified() != base::Time::UnixEpoch()) {
-    base::TouchFile(output_file_path,
-                    base::Time::Now(),
-                    current_entry_info()->last_modified());
+    delegate->SetTimeModified(current_entry_info()->last_modified());
   }
 
-  return success;
+  return entire_file_extracted;
 }
 
 void ZipReader::ExtractCurrentEntryToFilePathAsync(
@@ -408,27 +330,6 @@
                  failure_callback, progress_callback, 0 /* initial offset */));
 }
 
-bool ZipReader::ExtractCurrentEntryIntoDirectory(
-    const base::FilePath& output_directory_path) const {
-  DCHECK(current_entry_info_.get());
-
-  base::FilePath output_file_path = output_directory_path.Append(
-      current_entry_info()->file_path());
-  return ExtractCurrentEntryToFilePath(output_file_path);
-}
-
-bool ZipReader::ExtractCurrentEntryToFile(base::File* file) const {
-  DCHECK(zip_file_);
-
-  // If this is a directory, there's nothing to extract to the file, so return
-  // false.
-  if (current_entry_info()->is_directory())
-    return false;
-
-  FileWriterDelegate writer(file);
-  return ExtractCurrentEntry(&writer, std::numeric_limits<uint64_t>::max());
-}
-
 bool ZipReader::ExtractCurrentEntryToString(uint64_t max_read_bytes,
                                             std::string* output) const {
   DCHECK(output);
@@ -533,10 +434,10 @@
 
 // FileWriterDelegate ----------------------------------------------------------
 
-FileWriterDelegate::FileWriterDelegate(base::File* file)
-    : file_(file),
-      file_length_(0) {
-}
+FileWriterDelegate::FileWriterDelegate(base::File* file) : file_(file) {}
+
+FileWriterDelegate::FileWriterDelegate(std::unique_ptr<base::File> file)
+    : file_(file.get()), owned_file_(std::move(file)) {}
 
 FileWriterDelegate::~FileWriterDelegate() {
   if (!file_->SetLength(file_length_)) {
@@ -555,4 +456,36 @@
   return bytes_written == num_bytes;
 }
 
+void FileWriterDelegate::SetTimeModified(const base::Time& time) {
+  file_->SetTimes(base::Time::Now(), time);
+}
+
+// FilePathWriterDelegate ------------------------------------------------------
+
+FilePathWriterDelegate::FilePathWriterDelegate(
+    const base::FilePath& output_file_path)
+    : output_file_path_(output_file_path) {}
+
+FilePathWriterDelegate::~FilePathWriterDelegate() {}
+
+bool FilePathWriterDelegate::PrepareOutput() {
+  // We can't rely on parent directory entries being specified in the
+  // zip, so we make sure they are created.
+  if (!base::CreateDirectory(output_file_path_.DirName()))
+    return false;
+
+  file_.Initialize(output_file_path_,
+                   base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
+  return file_.IsValid();
+}
+
+bool FilePathWriterDelegate::WriteBytes(const char* data, int num_bytes) {
+  return num_bytes == file_.WriteAtCurrentPos(data, num_bytes);
+}
+
+void FilePathWriterDelegate::SetTimeModified(const base::Time& time) {
+  file_.Close();
+  base::TouchFile(output_file_path_, base::Time::Now(), time);
+}
+
 }  // namespace zip
diff --git a/third_party/zlib/google/zip_reader.h b/third_party/zlib/google/zip_reader.h
index 0464acd..cd24075 100644
--- a/third_party/zlib/google/zip_reader.h
+++ b/third_party/zlib/google/zip_reader.h
@@ -39,6 +39,9 @@
   // Invoked to write the next chunk of data. Return false on failure to cancel
   // extraction.
   virtual bool WriteBytes(const char* data, int num_bytes) = 0;
+
+  // Sets the last-modified time of the data.
+  virtual void SetTimeModified(const base::Time& time) = 0;
 };
 
 // This class is used for reading zip files. A typical use case of this
@@ -49,16 +52,16 @@
 //   reader.Open(zip_file_path);
 //   while (reader.HasMore()) {
 //     reader.OpenCurrentEntryInZip();
-//     reader.ExtractCurrentEntryToDirectory(output_directory_path);
+//     const base::FilePath& entry_path =
+//        reader.current_entry_info()->file_path();
+//     auto writer = CreateFilePathWriterDelegate(extract_dir, entry_path);
+//     reader.ExtractCurrentEntry(writer, std::numeric_limits<uint64_t>::max());
 //     reader.AdvanceToNextEntry();
 //   }
 //
 // For simplicity, error checking is omitted in the example code above. The
 // production code should check return values from all of these functions.
 //
-// This calls can also be used for random access of contents in a zip file
-// using LocateAndOpenEntry().
-//
 class ZipReader {
  public:
   // A callback that is called when the operation is successful.
@@ -154,27 +157,12 @@
   // state is reset automatically as needed.
   bool OpenCurrentEntryInZip();
 
-  // Locates an entry in the zip file and opens it. Returns true on
-  // success. This function internally calls OpenCurrentEntryInZip() on
-  // success. On failure, current_entry_info() becomes NULL.
-  bool LocateAndOpenEntry(const base::FilePath& path_in_zip);
-
   // Extracts |num_bytes_to_extract| bytes of the current entry to |delegate|,
   // starting from the beginning of the entry. Return value specifies whether
   // the entire file was extracted.
   bool ExtractCurrentEntry(WriterDelegate* delegate,
                            uint64_t num_bytes_to_extract) const;
 
-  // Extracts the current entry to the given output file path. If the
-  // current file is a directory, just creates a directory
-  // instead. Returns true on success. OpenCurrentEntryInZip() must be
-  // called beforehand.
-  //
-  // This function preserves the timestamp of the original entry. If that
-  // timestamp is not valid, the timestamp will be set to the current time.
-  bool ExtractCurrentEntryToFilePath(
-      const base::FilePath& output_file_path) const;
-
   // Asynchronously extracts the current entry to the given output file path.
   // If the current entry is a directory it just creates the directory
   // synchronously instead.  OpenCurrentEntryInZip() must be called beforehand.
@@ -187,24 +175,6 @@
       const FailureCallback& failure_callback,
       const ProgressCallback& progress_callback);
 
-  // Extracts the current entry to the given output directory path using
-  // ExtractCurrentEntryToFilePath(). Sub directories are created as needed
-  // based on the file path of the current entry. For example, if the file
-  // path in zip is "foo/bar.txt", and the output directory is "output",
-  // "output/foo/bar.txt" will be created.
-  //
-  // Returns true on success. OpenCurrentEntryInZip() must be called
-  // beforehand.
-  //
-  // This function preserves the timestamp of the original entry. If that
-  // timestamp is not valid, the timestamp will be set to the current time.
-  bool ExtractCurrentEntryIntoDirectory(
-      const base::FilePath& output_directory_path) const;
-
-  // Extracts the current entry by writing directly to a platform file.
-  // Does not close the file. Returns true on success.
-  bool ExtractCurrentEntryToFile(base::File* file) const;
-
   // Extracts the current entry into memory. If the current entry is a
   // directory, the |output| parameter is set to the empty string. If the
   // current entry is a file, the |output| parameter is filled with its
@@ -258,8 +228,14 @@
 // A writer delegate that writes to a given File.
 class FileWriterDelegate : public WriterDelegate {
  public:
+  // Constructs a FileWriterDelegate that manipulates |file|. The delegate will
+  // not own |file|, therefore the caller must guarantee |file| will outlive the
+  // delegate.
   explicit FileWriterDelegate(base::File* file);
 
+  // Constructs a FileWriterDelegate that takes ownership of |file|.
+  explicit FileWriterDelegate(std::unique_ptr<base::File> file);
+
   // Truncates the file to the number of bytes written.
   ~FileWriterDelegate() override;
 
@@ -272,13 +248,47 @@
   // if not all bytes could be written.
   bool WriteBytes(const char* data, int num_bytes) override;
 
+  // Sets the last-modified time of the data.
+  void SetTimeModified(const base::Time& time) override;
+
  private:
+  // The file the delegate modifies.
   base::File* file_;
-  int64_t file_length_;
+
+  // The delegate can optionally own the file it modifies, in which case
+  // owned_file_ is set and file_ is an alias for owned_file_.
+  std::unique_ptr<base::File> owned_file_;
+
+  int64_t file_length_ = 0;
 
   DISALLOW_COPY_AND_ASSIGN(FileWriterDelegate);
 };
 
+// A writer delegate that writes a file at a given path.
+class FilePathWriterDelegate : public WriterDelegate {
+ public:
+  explicit FilePathWriterDelegate(const base::FilePath& output_file_path);
+  ~FilePathWriterDelegate() override;
+
+  // WriterDelegate methods:
+
+  // Creates the output file and any necessary intermediate directories.
+  bool PrepareOutput() override;
+
+  // Writes |num_bytes| bytes of |data| to the file, returning false if not all
+  // bytes could be written.
+  bool WriteBytes(const char* data, int num_bytes) override;
+
+  // Sets the last-modified time of the data.
+  void SetTimeModified(const base::Time& time) override;
+
+ private:
+  base::FilePath output_file_path_;
+  base::File file_;
+
+  DISALLOW_COPY_AND_ASSIGN(FilePathWriterDelegate);
+};
+
 }  // namespace zip
 
 #endif  // THIRD_PARTY_ZLIB_GOOGLE_ZIP_READER_H_
diff --git a/third_party/zlib/google/zip_reader_unittest.cc b/third_party/zlib/google/zip_reader_unittest.cc
index 30a56f11..0c74f37 100644
--- a/third_party/zlib/google/zip_reader_unittest.cc
+++ b/third_party/zlib/google/zip_reader_unittest.cc
@@ -109,8 +109,30 @@
  public:
   MOCK_METHOD0(PrepareOutput, bool());
   MOCK_METHOD2(WriteBytes, bool(const char*, int));
+  MOCK_METHOD1(SetTimeModified, void(const base::Time&));
 };
 
+bool ExtractCurrentEntryToFilePath(zip::ZipReader* reader,
+                                   base::FilePath path) {
+  zip::FilePathWriterDelegate writer(path);
+  return reader->ExtractCurrentEntry(&writer,
+                                     std::numeric_limits<uint64_t>::max());
+}
+
+bool LocateAndOpenEntry(zip::ZipReader* reader,
+                        const base::FilePath& path_in_zip) {
+  // The underlying library can do O(1) access, but ZipReader does not expose
+  // that. O(N) access is acceptable for these tests.
+  while (reader->HasMore()) {
+    if (!reader->OpenCurrentEntryInZip())
+      return false;
+    if (reader->current_entry_info()->file_path() == path_in_zip)
+      return true;
+    reader->AdvanceToNextEntry();
+  }
+  return false;
+}
+
 }   // namespace
 
 namespace zip {
@@ -250,112 +272,11 @@
   EXPECT_EQ(test_zip_contents_, actual_contents);
 }
 
-TEST_F(ZipReaderTest, LocateAndOpenEntry_ValidFile) {
-  std::set<base::FilePath> actual_contents;
-  ZipReader reader;
-  ASSERT_TRUE(reader.Open(test_zip_file_));
-  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
-  EXPECT_EQ(target_path, reader.current_entry_info()->file_path());
-}
-
-TEST_F(ZipReaderTest, LocateAndOpenEntry_NonExistentFile) {
-  std::set<base::FilePath> actual_contents;
-  ZipReader reader;
-  ASSERT_TRUE(reader.Open(test_zip_file_));
-  base::FilePath target_path(FILE_PATH_LITERAL("nonexistent.txt"));
-  ASSERT_FALSE(reader.LocateAndOpenEntry(target_path));
-  EXPECT_EQ(NULL, reader.current_entry_info());
-}
-
-TEST_F(ZipReaderTest, ExtractCurrentEntryToFilePath_RegularFile) {
-  ZipReader reader;
-  ASSERT_TRUE(reader.Open(test_zip_file_));
-  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
-  ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath(
-      test_dir_.AppendASCII("quux.txt")));
-  // Read the output file ans compute the MD5.
-  std::string output;
-  ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"),
-                                     &output));
-  const std::string md5 = base::MD5String(output);
-  EXPECT_EQ(kQuuxExpectedMD5, md5);
-  // quux.txt should be larger than kZipBufSize so that we can exercise
-  // the loop in ExtractCurrentEntry().
-  EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size());
-}
-
-TEST_F(ZipReaderTest, PlatformFileExtractCurrentEntryToFilePath_RegularFile) {
-  ZipReader reader;
-  FileWrapper zip_fd_wrapper(test_zip_file_, FileWrapper::READ_ONLY);
-  ASSERT_TRUE(reader.OpenFromPlatformFile(zip_fd_wrapper.platform_file()));
-  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
-  ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath(
-      test_dir_.AppendASCII("quux.txt")));
-  // Read the output file and compute the MD5.
-  std::string output;
-  ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"),
-                                     &output));
-  const std::string md5 = base::MD5String(output);
-  EXPECT_EQ(kQuuxExpectedMD5, md5);
-  // quux.txt should be larger than kZipBufSize so that we can exercise
-  // the loop in ExtractCurrentEntry().
-  EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size());
-}
-
-TEST_F(ZipReaderTest, PlatformFileExtractCurrentEntryToFile_RegularFile) {
-  ZipReader reader;
-  FileWrapper zip_fd_wrapper(test_zip_file_, FileWrapper::READ_ONLY);
-  ASSERT_TRUE(reader.OpenFromPlatformFile(zip_fd_wrapper.platform_file()));
-  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
-  base::FilePath out_path = test_dir_.AppendASCII("quux.txt");
-  FileWrapper out_fd_w(out_path, FileWrapper::READ_WRITE);
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
-  ASSERT_TRUE(reader.ExtractCurrentEntryToFile(out_fd_w.file()));
-  // Read the output file and compute the MD5.
-  std::string output;
-  ASSERT_TRUE(base::ReadFileToString(out_path, &output));
-  const std::string md5 = base::MD5String(output);
-  EXPECT_EQ(kQuuxExpectedMD5, md5);
-  // quux.txt should be larger than kZipBufSize so that we can exercise
-  // the loop in ExtractCurrentEntry().
-  EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size());
-}
-
-TEST_F(ZipReaderTest, ExtractCurrentEntryToFilePath_Directory) {
-  ZipReader reader;
-  ASSERT_TRUE(reader.Open(test_zip_file_));
-  base::FilePath target_path(FILE_PATH_LITERAL("foo/"));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
-  ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath(
-      test_dir_.AppendASCII("foo")));
-  // The directory should be created.
-  ASSERT_TRUE(base::DirectoryExists(test_dir_.AppendASCII("foo")));
-}
-
-TEST_F(ZipReaderTest, ExtractCurrentEntryIntoDirectory_RegularFile) {
-  ZipReader reader;
-  ASSERT_TRUE(reader.Open(test_zip_file_));
-  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
-  ASSERT_TRUE(reader.ExtractCurrentEntryIntoDirectory(test_dir_));
-  // Sub directories should be created.
-  ASSERT_TRUE(base::DirectoryExists(test_dir_.AppendASCII("foo/bar")));
-  // And the file should be created.
-  std::string output;
-  ASSERT_TRUE(base::ReadFileToString(
-      test_dir_.AppendASCII("foo/bar/quux.txt"), &output));
-  const std::string md5 = base::MD5String(output);
-  EXPECT_EQ(kQuuxExpectedMD5, md5);
-}
-
 TEST_F(ZipReaderTest, current_entry_info_RegularFile) {
   ZipReader reader;
   ASSERT_TRUE(reader.Open(test_zip_file_));
   base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
+  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
   ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
 
   EXPECT_EQ(target_path, current_entry_info->file_path());
@@ -381,7 +302,7 @@
   ASSERT_TRUE(reader.Open(evil_zip_file_));
   base::FilePath target_path(FILE_PATH_LITERAL(
       "../levilevilevilevilevilevilevilevilevilevilevilevil"));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
+  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
   ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
   EXPECT_EQ(target_path, current_entry_info->file_path());
 
@@ -409,7 +330,7 @@
   ZipReader reader;
   ASSERT_TRUE(reader.Open(evil_via_absolute_file_name_zip_file_));
   base::FilePath target_path(FILE_PATH_LITERAL("/evil.txt"));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
+  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
   ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
   EXPECT_EQ(target_path, current_entry_info->file_path());
 
@@ -422,7 +343,7 @@
   ZipReader reader;
   ASSERT_TRUE(reader.Open(test_zip_file_));
   base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/"));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
+  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
   ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
 
   EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("foo/bar/")),
@@ -469,9 +390,9 @@
   ZipReader reader;
   ASSERT_TRUE(reader.OpenFromString(data));
   base::FilePath target_path(FILE_PATH_LITERAL("test.txt"));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
-  ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath(
-      test_dir_.AppendASCII("test.txt")));
+  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
+  ASSERT_TRUE(ExtractCurrentEntryToFilePath(&reader,
+                                            test_dir_.AppendASCII("test.txt")));
 
   std::string actual;
   ASSERT_TRUE(base::ReadFileToString(
@@ -487,7 +408,7 @@
   base::FilePath target_file = test_dir_.AppendASCII("quux.txt");
   base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
   ASSERT_TRUE(reader.Open(test_zip_file_));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
+  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
   reader.ExtractCurrentEntryToFilePathAsync(
       target_file,
       base::Bind(&MockUnzipListener::OnUnzipSuccess,
@@ -527,7 +448,7 @@
   base::FilePath target_file = test_dir_.AppendASCII("foo");
   base::FilePath target_path(FILE_PATH_LITERAL("foo/"));
   ASSERT_TRUE(reader.Open(test_zip_file_));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
+  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
   reader.ExtractCurrentEntryToFilePathAsync(
       target_file,
       base::Bind(&MockUnzipListener::OnUnzipSuccess,
@@ -566,7 +487,7 @@
 
     base::FilePath file_name = base::FilePath::FromUTF8Unsafe(
         base::StringPrintf("%d.txt", static_cast<int>(i)));
-    ASSERT_TRUE(reader.LocateAndOpenEntry(file_name));
+    ASSERT_TRUE(LocateAndOpenEntry(&reader, file_name));
 
     if (i > 1) {
       // Off by one byte read limit: must fail.
@@ -598,14 +519,14 @@
   ASSERT_TRUE(reader.Open(test_zip_file));
 
   base::FilePath file_name0 = base::FilePath::FromUTF8Unsafe("0.txt");
-  ASSERT_TRUE(reader.LocateAndOpenEntry(file_name0));
+  ASSERT_TRUE(LocateAndOpenEntry(&reader, file_name0));
   EXPECT_TRUE(reader.ExtractCurrentEntryToString(0, &contents));
   EXPECT_EQ("", contents);
   EXPECT_TRUE(reader.ExtractCurrentEntryToString(1, &contents));
   EXPECT_EQ("", contents);
 
   base::FilePath file_name1 = base::FilePath::FromUTF8Unsafe("1.txt");
-  ASSERT_TRUE(reader.LocateAndOpenEntry(file_name1));
+  ASSERT_TRUE(LocateAndOpenEntry(&reader, file_name1));
   EXPECT_TRUE(reader.ExtractCurrentEntryToString(0, &contents));
   EXPECT_EQ("", contents);
   EXPECT_TRUE(reader.ExtractCurrentEntryToString(1, &contents));
@@ -614,7 +535,7 @@
   EXPECT_EQ("0", contents);
 
   base::FilePath file_name4 = base::FilePath::FromUTF8Unsafe("4.txt");
-  ASSERT_TRUE(reader.LocateAndOpenEntry(file_name4));
+  ASSERT_TRUE(LocateAndOpenEntry(&reader, file_name4));
   EXPECT_TRUE(reader.ExtractCurrentEntryToString(0, &contents));
   EXPECT_EQ("", contents);
   EXPECT_FALSE(reader.ExtractCurrentEntryToString(2, &contents));
@@ -650,7 +571,7 @@
   ZipReader reader;
 
   ASSERT_TRUE(reader.Open(test_zip_file_));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
+  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
   ASSERT_FALSE(reader.ExtractCurrentEntry(
       &mock_writer, std::numeric_limits<uint64_t>::max()));
 }
@@ -669,7 +590,7 @@
   ZipReader reader;
 
   ASSERT_TRUE(reader.Open(test_zip_file_));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
+  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
   ASSERT_FALSE(reader.ExtractCurrentEntry(
       &mock_writer, std::numeric_limits<uint64_t>::max()));
 }
@@ -682,12 +603,13 @@
       .WillOnce(Return(true));
   EXPECT_CALL(mock_writer, WriteBytes(_, _))
       .WillRepeatedly(Return(true));
+  EXPECT_CALL(mock_writer, SetTimeModified(_));
 
   base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
   ZipReader reader;
 
   ASSERT_TRUE(reader.Open(test_zip_file_));
-  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
+  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
   ASSERT_TRUE(reader.ExtractCurrentEntry(&mock_writer,
                                          std::numeric_limits<uint64_t>::max()));
 }
diff --git a/third_party/zlib/google/zip_unittest.cc b/third_party/zlib/google/zip_unittest.cc
index d282c57..21e1f71 100644
--- a/third_party/zlib/google/zip_unittest.cc
+++ b/third_party/zlib/google/zip_unittest.cc
@@ -10,6 +10,7 @@
 #include <string>
 #include <vector>
 
+#include "base/bind.h"
 #include "base/files/file.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
@@ -338,6 +339,75 @@
   ASSERT_FALSE(base::PathExists(evil_file));
 }
 
+TEST_F(ZipTest, UnzipWithFilter) {
+  auto filter = base::BindRepeating([](const base::FilePath& path) {
+    return path.BaseName().MaybeAsASCII() == "foo.txt";
+  });
+  base::FilePath path;
+  ASSERT_TRUE(GetTestDataDirectory(&path));
+  ASSERT_TRUE(zip::UnzipWithFilterCallback(path.AppendASCII("test.zip"),
+                                           test_dir_, filter, false));
+  // Only foo.txt should have been extracted. The following paths should not
+  // be extracted:
+  //   foo/
+  //   foo/bar.txt
+  //   foo/bar/
+  //   foo/bar/.hidden
+  //   foo/bar/baz.txt
+  //   foo/bar/quux.txt
+  ASSERT_TRUE(base::PathExists(test_dir_.AppendASCII("foo.txt")));
+  base::FileEnumerator extractedFiles(
+      test_dir_,
+      false,  // Do not enumerate recursively - the file must be in the root.
+      base::FileEnumerator::FileType::FILES);
+  int extracted_count = 0;
+  while (!extractedFiles.Next().empty())
+    ++extracted_count;
+  ASSERT_EQ(1, extracted_count);
+
+  base::FileEnumerator extractedDirs(
+      test_dir_,
+      false,  // Do not enumerate recursively - we require zero directories.
+      base::FileEnumerator::FileType::DIRECTORIES);
+  extracted_count = 0;
+  while (!extractedDirs.Next().empty())
+    ++extracted_count;
+  ASSERT_EQ(0, extracted_count);
+}
+
+TEST_F(ZipTest, UnzipWithDelegates) {
+  auto filter =
+      base::BindRepeating([](const base::FilePath& path) { return true; });
+  auto dir_creator = base::BindRepeating(
+      [](const base::FilePath& extract_dir, const base::FilePath& entry_path) {
+        return base::CreateDirectory(extract_dir.Append(entry_path));
+      },
+      test_dir_);
+  auto writer = base::BindRepeating(
+      [](const base::FilePath& extract_dir, const base::FilePath& entry_path)
+          -> std::unique_ptr<zip::WriterDelegate> {
+        return std::make_unique<zip::FilePathWriterDelegate>(
+            extract_dir.Append(entry_path));
+      },
+      test_dir_);
+  base::FilePath path;
+  ASSERT_TRUE(GetTestDataDirectory(&path));
+  base::File file(path.AppendASCII("test.zip"),
+                  base::File::Flags::FLAG_OPEN | base::File::Flags::FLAG_READ);
+  ASSERT_TRUE(zip::UnzipWithFilterAndWriters(file.GetPlatformFile(), writer,
+                                             dir_creator, filter, false));
+  base::FilePath dir = test_dir_;
+  base::FilePath dir_foo = dir.AppendASCII("foo");
+  base::FilePath dir_foo_bar = dir_foo.AppendASCII("bar");
+  ASSERT_TRUE(base::PathExists(dir.AppendASCII("foo.txt")));
+  ASSERT_TRUE(base::PathExists(dir_foo));
+  ASSERT_TRUE(base::PathExists(dir_foo.AppendASCII("bar.txt")));
+  ASSERT_TRUE(base::PathExists(dir_foo_bar));
+  ASSERT_TRUE(base::PathExists(dir_foo_bar.AppendASCII(".hidden")));
+  ASSERT_TRUE(base::PathExists(dir_foo_bar.AppendASCII("baz.txt")));
+  ASSERT_TRUE(base::PathExists(dir_foo_bar.AppendASCII("quux.txt")));
+}
+
 TEST_F(ZipTest, Zip) {
   base::FilePath src_dir;
   ASSERT_TRUE(GetTestDataDirectory(&src_dir));
@@ -424,10 +494,11 @@
   EXPECT_TRUE(reader.Open(zip_name));
   EXPECT_EQ(zip_file_list_.size(), static_cast<size_t>(reader.num_entries()));
   for (size_t i = 0; i < zip_file_list_.size(); ++i) {
-    EXPECT_TRUE(reader.LocateAndOpenEntry(zip_file_list_[i]));
-    // Check the path in the entry just in case.
+    EXPECT_TRUE(reader.HasMore());
+    EXPECT_TRUE(reader.OpenCurrentEntryInZip());
     const zip::ZipReader::EntryInfo* entry_info = reader.current_entry_info();
     EXPECT_EQ(entry_info->file_path(), zip_file_list_[i]);
+    reader.AdvanceToNextEntry();
   }
 }
 #endif  // defined(OS_POSIX)
diff --git a/third_party/zlib/patches/README b/third_party/zlib/patches/README
index 687842c..4cf06b81 100644
--- a/third_party/zlib/patches/README
+++ b/third_party/zlib/patches/README
@@ -19,8 +19,23 @@
 should help to solve frequent conflicts in pending new patches on
 Chromium's zlib.
 
-  The plan for the near future is to insulate better the platform specific
-changes to easy updates with new releases of zlib.
+  The plan for the near future is to better insulate the platform specific
+changes to ease update adoption with new releases of zlib. This insulation
+happens by making changes inside contrib/ rather than the root directory
+(where conflicts can happen).
+
+  If a change modifies enough things inside the root directory that the
+intention is not immediately clear, generate a .patch file to go with your
+change. If the change's modifications in the root directory are small, like:
+
+#ifdef FEATURE_FLAG
+use_special_feature();
+#elif
+use_default_behavior();
+#endif
+
+  then the intent is clear and a .patch file doesn't need to be generated (since
+it would not provide much value).
 
   Ideally local changes should have a merge request featured in either:
  - canonical zlib: https://github.com/madler/zlib/
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index d7abb08d8..f65c8026 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -25408,6 +25408,7 @@
   <int value="-1867342522" label="MaterialDesignHistory:enabled"/>
   <int value="-1861814223" label="MidiManagerDynamicInstantiation:enabled"/>
   <int value="-1860481724" label="ChromeHomeExpandButton:enabled"/>
+  <int value="-1859095876" label="Previews:disabled"/>
   <int value="-1856902397" label="LoadingWithMojo:enabled"/>
   <int value="-1854432127" label="ChromeHomePullToRefreshIphAtTop:disabled"/>
   <int value="-1854372227" label="VrBrowsingExperimentalFeatures:enabled"/>
@@ -25443,6 +25444,7 @@
   <int value="-1779753607" label="VizDisplayCompositor:disabled"/>
   <int value="-1778993296" label="ContextualSearchMlTapSuppression:disabled"/>
   <int value="-1772172557" label="enable-osk-overscroll"/>
+  <int value="-1768672408" label="ChromeDuplex:disabled"/>
   <int value="-1767470652" label="out-of-process-pdf"/>
   <int value="-1755301960" label="ClearOldBrowsingData:enabled"/>
   <int value="-1751928267" label="disable-icon-ntp"/>
@@ -25812,6 +25814,7 @@
   <int value="-855130893" label="enable-touch-calibration-setting"/>
   <int value="-853594220" label="disable-new-avatar-menu"/>
   <int value="-848691867" label="DesktopPWAWindowing:enabled"/>
+  <int value="-847216521" label="ChromeDuplex:enabled"/>
   <int value="-844537521" label="HttpFormWarning:disabled"/>
   <int value="-844381918" label="ArcNativeBridgeExperiment:disabled"/>
   <int value="-842438090" label="enable-md-feedback"/>
@@ -26269,6 +26272,7 @@
   <int value="372460068" label="QuickUnlockFingerprint:disabled"/>
   <int value="375785554" label="UserActivationV2:disabled"/>
   <int value="377093001" label="WebRtcHWH264Encoding:disabled"/>
+  <int value="378994579" label="Previews:enabled"/>
   <int value="379326303" label="enable-add-to-shelf"/>
   <int value="379428799" label="security-chip-animation"/>
   <int value="385969127" label="disable-win32k-lockdown"/>
@@ -35501,6 +35505,7 @@
   <int value="5" label="HyperText Transfer Protocol Secure (https)"/>
   <int value="6" label="App Socket (socket)"/>
   <int value="7" label="Line Print Daemon (lpd)"/>
+  <int value="8" label="IPP-over-USB (ippusb)"/>
 </enum>
 
 <enum name="PrinterServiceEventType">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index b78c8a0..90f440a 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -67256,11 +67256,17 @@
 </histogram>
 
 <histogram name="PreloadScanner.Counts2" units="preloads">
+  <obsolete>
+    Removed Feb 2018, no longer useful.
+  </obsolete>
   <owner>csharrison@chromium.org</owner>
   <summary>The number of preloads generated by the preload scanner.</summary>
 </histogram>
 
 <histogram name="PreloadScanner.Counts2.Miss" units="preloads">
+  <obsolete>
+    Removed Feb 2018, no longer useful.
+  </obsolete>
   <owner>csharrison@chromium.org</owner>
   <summary>
     The number of unused preloads generated by the preload scanner. Note that
diff --git a/ui/app_list/DEPS b/ui/app_list/DEPS
index 383234c1..eda8186 100644
--- a/ui/app_list/DEPS
+++ b/ui/app_list/DEPS
@@ -24,4 +24,5 @@
   # TODO(hejq): Remove this once app_list is migrated. http://crbug.com/733662
   "+ash/app_list",
   "+ash/public/cpp",
+  "+ash/public/interfaces",
 ]
diff --git a/ui/app_list/app_list_view_delegate.h b/ui/app_list/app_list_view_delegate.h
index ef8d98b3..485d70cb3 100644
--- a/ui/app_list/app_list_view_delegate.h
+++ b/ui/app_list/app_list_view_delegate.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "ash/public/interfaces/menu.mojom.h"
+#include "base/callback_forward.h"
 #include "base/strings/string16.h"
 #include "base/time/time.h"
 #include "third_party/skia/include/core/SkColor.h"
@@ -21,10 +23,6 @@
 class View;
 }
 
-namespace ui {
-class MenuModel;
-}
-
 namespace app_list {
 
 class AppListModel;
@@ -71,15 +69,29 @@
   virtual void ViewClosing() = 0;
 
   // Gets the wallpaper prominent colors.
-  virtual void GetWallpaperProminentColors(std::vector<SkColor>* colors) = 0;
+  using GetWallpaperProminentColorsCallback =
+      base::OnceCallback<void(const std::vector<SkColor>&)>;
+  virtual void GetWallpaperProminentColors(
+      GetWallpaperProminentColorsCallback callback) = 0;
 
   // Activates (opens) the item.
   virtual void ActivateItem(const std::string& id, int event_flags) = 0;
 
-  // Returns the context menu model for this item, or NULL if there is currently
-  // no menu for the item (e.g. during install).
-  // Note the returned menu model is owned by this item.
-  virtual ui::MenuModel* GetContextMenuModel(const std::string& id) = 0;
+  // Returns the context menu model for a ChromeAppListItem with |id|, or NULL
+  // if there is currently no menu for the item (e.g. during install).
+  // Note the returned menu model is owned by that item.
+  using GetContextMenuModelCallback =
+      base::OnceCallback<void(std::vector<ash::mojom::MenuItemPtr>)>;
+  virtual void GetContextMenuModel(const std::string& id,
+                                   GetContextMenuModelCallback callback) = 0;
+
+  // Invoked when a context menu item of an app list item is clicked.
+  // |id| is the clicked AppListItem's id
+  // |command_id| is the clicked menu item's command id
+  // |event_flags| is flags from the event which issued this command
+  virtual void ContextMenuItemSelected(const std::string& id,
+                                       int command_id,
+                                       int event_flags) = 0;
 
   // Add/remove observer for AppListViewDelegate.
   virtual void AddObserver(AppListViewDelegateObserver* observer) = 0;
diff --git a/ui/app_list/test/app_list_test_view_delegate.cc b/ui/app_list/test/app_list_test_view_delegate.cc
index 414078a1..5d1cc4d 100644
--- a/ui/app_list/test/app_list_test_view_delegate.cc
+++ b/ui/app_list/test/app_list_test_view_delegate.cc
@@ -5,9 +5,11 @@
 #include "ui/app_list/test/app_list_test_view_delegate.h"
 
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "ash/app_list/model/app_list_model.h"
+#include "ash/public/cpp/menu_utils.h"
 #include "base/callback.h"
 #include "base/files/file_path.h"
 #include "ui/app_list/app_list_switches.h"
@@ -66,14 +68,17 @@
   static_cast<AppListTestModel::AppListTestItem*>(item)->Activate(event_flags);
 }
 
-ui::MenuModel* AppListTestViewDelegate::GetContextMenuModel(
-    const std::string& id) {
+void AppListTestViewDelegate::GetContextMenuModel(
+    const std::string& id,
+    GetContextMenuModelCallback callback) {
   app_list::AppListItem* item = model_->FindItem(id);
   // TODO(stevenjb/jennyz): Implement this for folder items
-  if (!item || item->is_folder())
-    return nullptr;
-  return static_cast<AppListTestModel::AppListTestItem*>(item)
-      ->GetContextMenuModel();
+  ui::MenuModel* menu = nullptr;
+  if (item && !item->is_folder()) {
+    menu = static_cast<AppListTestModel::AppListTestItem*>(item)
+               ->GetContextMenuModel();
+  }
+  std::move(callback).Run(ash::menu_utils::GetMojoMenuItemsFromModel(menu));
 }
 
 }  // namespace test
diff --git a/ui/app_list/test/app_list_test_view_delegate.h b/ui/app_list/test/app_list_test_view_delegate.h
index bc16b49..c8fe7ac 100644
--- a/ui/app_list/test/app_list_test_view_delegate.h
+++ b/ui/app_list/test/app_list_test_view_delegate.h
@@ -55,9 +55,14 @@
   void ViewShown() override {}
   void Dismiss() override;
   void ViewClosing() override {}
-  void GetWallpaperProminentColors(std::vector<SkColor>* colors) override {}
+  void GetWallpaperProminentColors(
+      GetWallpaperProminentColorsCallback callback) override {}
   void ActivateItem(const std::string& id, int event_flags) override;
-  ui::MenuModel* GetContextMenuModel(const std::string& id) override;
+  void GetContextMenuModel(const std::string& id,
+                           GetContextMenuModelCallback callback) override;
+  void ContextMenuItemSelected(const std::string& id,
+                               int command_id,
+                               int event_flags) override {}
   void AddObserver(app_list::AppListViewDelegateObserver* observer) override {}
   void RemoveObserver(
       app_list::AppListViewDelegateObserver* observer) override {}
diff --git a/ui/app_list/views/app_list_item_view.cc b/ui/app_list/views/app_list_item_view.cc
index 8804a54..8c7cc50 100644
--- a/ui/app_list/views/app_list_item_view.cc
+++ b/ui/app_list/views/app_list_item_view.cc
@@ -5,9 +5,12 @@
 #include "ui/app_list/views/app_list_item_view.h"
 
 #include <algorithm>
+#include <utility>
+#include <vector>
 
 #include "ash/app_list/model/app_list_folder_item.h"
 #include "ash/app_list/model/app_list_item.h"
+#include "ash/public/cpp/menu_utils.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
@@ -280,15 +283,19 @@
                       base::TimeTicks::Now() - open_time);
 }
 
-void AppListItemView::ShowContextMenuForView(views::View* source,
-                                             const gfx::Point& point,
-                                             ui::MenuSourceType source_type) {
-  if (context_menu_runner_ && context_menu_runner_->IsRunning())
+void AppListItemView::OnContextMenuModelReceived(
+    const gfx::Point& point,
+    ui::MenuSourceType source_type,
+    std::vector<ash::mojom::MenuItemPtr> menu) {
+  if (menu.empty() ||
+      (context_menu_runner_ && context_menu_runner_->IsRunning()))
     return;
 
-  ui::MenuModel* menu_model = delegate_->GetContextMenuModel(item_weak_->id());
-  if (!menu_model)
-    return;
+  // Reset and populate the context menu model.
+  context_menu_model_ = std::make_unique<ui::SimpleMenuModel>(this);
+  ash::menu_utils::PopulateMenuFromMojoMenuItems(
+      context_menu_model_.get(), this, menu, &context_submenu_models_);
+  context_menu_items_ = std::move(menu);
 
   UMA_HISTOGRAM_ENUMERATION("Apps.ContextMenuShowSource.AppGrid", source_type,
                             ui::MenuSourceType::MENU_SOURCE_TYPE_LAST);
@@ -298,16 +305,44 @@
   int run_types = views::MenuRunner::HAS_MNEMONICS |
                   views::MenuRunner::SEND_GESTURE_EVENTS_TO_OWNER;
   context_menu_runner_.reset(new views::MenuRunner(
-      menu_model, run_types,
+      context_menu_model_.get(), run_types,
       base::Bind(&AppListItemView::OnContextMenuClosed,
                  weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now())));
   context_menu_runner_->RunMenuAt(GetWidget(), NULL,
                                   gfx::Rect(point, gfx::Size()),
                                   views::MENU_ANCHOR_TOPLEFT, source_type);
+}
+
+void AppListItemView::ShowContextMenuForView(views::View* source,
+                                             const gfx::Point& point,
+                                             ui::MenuSourceType source_type) {
+  delegate_->GetContextMenuModel(
+      item_weak_->id(),
+      base::BindOnce(&AppListItemView::OnContextMenuModelReceived,
+                     weak_ptr_factory_.GetWeakPtr(), point, source_type));
 
   source->RequestFocus();
 }
 
+bool AppListItemView::IsCommandIdChecked(int command_id) const {
+  return ash::menu_utils::GetMenuItemByCommandId(context_menu_items_,
+                                                 command_id)
+      ->checked;
+}
+
+bool AppListItemView::IsCommandIdEnabled(int command_id) const {
+  return ash::menu_utils::GetMenuItemByCommandId(context_menu_items_,
+                                                 command_id)
+      ->enabled;
+}
+
+void AppListItemView::ExecuteCommand(int command_id, int event_flags) {
+  if (item_weak_) {
+    delegate_->ContextMenuItemSelected(item_weak_->id(), command_id,
+                                       event_flags);
+  }
+}
+
 void AppListItemView::StateChanged(ButtonState old_state) {
   if (state() == STATE_HOVERED || state() == STATE_PRESSED) {
     if (shadow_animator_)
diff --git a/ui/app_list/views/app_list_item_view.h b/ui/app_list/views/app_list_item_view.h
index c69e374..5bf3d3f 100644
--- a/ui/app_list/views/app_list_item_view.h
+++ b/ui/app_list/views/app_list_item_view.h
@@ -7,14 +7,18 @@
 
 #include <memory>
 #include <string>
+#include <utility>
+#include <vector>
 
 #include "ash/app_list/model/app_list_item_observer.h"
+#include "ash/public/interfaces/menu.mojom.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/strings/string16.h"
 #include "base/timer/timer.h"
 #include "ui/app_list/app_list_export.h"
 #include "ui/app_list/views/image_shadow_animator.h"
+#include "ui/base/models/simple_menu_model.h"
 #include "ui/views/context_menu_controller.h"
 #include "ui/views/controls/button/button.h"
 
@@ -23,7 +27,7 @@
 class Label;
 class MenuRunner;
 class ProgressBar;
-}
+}  // namespace views
 
 namespace app_list {
 
@@ -34,7 +38,8 @@
 class APP_LIST_EXPORT AppListItemView : public views::Button,
                                         public views::ContextMenuController,
                                         public AppListItemObserver,
-                                        public ImageShadowAnimator::Delegate {
+                                        public ImageShadowAnimator::Delegate,
+                                        public ui::SimpleMenuModel::Delegate {
  public:
   // Internal class name.
   static const char kViewClassName[];
@@ -131,6 +136,12 @@
   // Records the context menu user journey time.
   void OnContextMenuClosed(const base::TimeTicks& open_time);
 
+  // Callback invoked when a context menu is received after calling
+  // |AppListViewDelegate::GetContextMenuModel|.
+  void OnContextMenuModelReceived(const gfx::Point& point,
+                                  ui::MenuSourceType source_type,
+                                  std::vector<ash::mojom::MenuItemPtr> menu);
+
   // views::ContextMenuController overrides:
   void ShowContextMenuForView(views::View* source,
                               const gfx::Point& point,
@@ -159,6 +170,11 @@
   void ItemPercentDownloadedChanged() override;
   void ItemBeingDestroyed() override;
 
+  // ui::SimpleMenuModel::Delegate overrides;
+  bool IsCommandIdChecked(int command_id) const override;
+  bool IsCommandIdEnabled(int command_id) const override;
+  void ExecuteCommand(int command_id, int event_flags) override;
+
   const bool is_folder_;
   const bool is_in_folder_;
 
@@ -171,6 +187,9 @@
   views::ProgressBar* progress_bar_;  // Strongly typed child view.
 
   std::unique_ptr<views::MenuRunner> context_menu_runner_;
+  std::unique_ptr<ui::SimpleMenuModel> context_menu_model_;
+  std::vector<ash::mojom::MenuItemPtr> context_menu_items_;
+  std::vector<std::unique_ptr<ui::MenuModel>> context_submenu_models_;
 
   UIState ui_state_ = UI_STATE_NORMAL;
 
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc
index 34db3157..a0c49440 100644
--- a/ui/app_list/views/app_list_view.cc
+++ b/ui/app_list/views/app_list_view.cc
@@ -5,6 +5,7 @@
 #include "ui/app_list/views/app_list_view.h"
 
 #include <algorithm>
+#include <utility>
 #include <vector>
 
 #include "ash/app_list/model/app_list_model.h"
@@ -23,7 +24,6 @@
 #include "ui/app_list/app_list_constants.h"
 #include "ui/app_list/app_list_features.h"
 #include "ui/app_list/app_list_util.h"
-#include "ui/app_list/app_list_view_delegate.h"
 #include "ui/app_list/views/app_list_folder_view.h"
 #include "ui/app_list/views/app_list_main_view.h"
 #include "ui/app_list/views/apps_container_view.h"
@@ -239,7 +239,8 @@
       previous_arrow_key_traversal_enabled_(
           views::FocusManager::arrow_key_traversal_enabled()),
       state_animation_metrics_reporter_(
-          std::make_unique<StateAnimationMetricsReporter>()) {
+          std::make_unique<StateAnimationMetricsReporter>()),
+      weak_ptr_factory_(this) {
   CHECK(delegate);
 
   display_observer_.Add(display::Screen::GetScreen());
@@ -1321,8 +1322,9 @@
   return coefficient * shield_opacity + (1 - coefficient) * shelf_opacity;
 }
 
-void AppListView::GetWallpaperProminentColors(std::vector<SkColor>* colors) {
-  delegate_->GetWallpaperProminentColors(colors);
+void AppListView::GetWallpaperProminentColors(
+    AppListViewDelegate::GetWallpaperProminentColorsCallback callback) {
+  delegate_->GetWallpaperProminentColors(std::move(callback));
 }
 
 void AppListView::OnWallpaperColorsChanged() {
@@ -1336,10 +1338,13 @@
   if (!app_list_background_shield_)
     return;
 
-  std::vector<SkColor> prominent_colors;
-  GetWallpaperProminentColors(&prominent_colors);
-  app_list_background_shield_->layer()->SetColor(
-      GetBackgroundShieldColor(prominent_colors));
+  GetWallpaperProminentColors(base::BindOnce(
+      [](base::WeakPtr<AppListView> self,
+         const std::vector<SkColor>& prominent_colors) {
+        self->app_list_background_shield_->layer()->SetColor(
+            GetBackgroundShieldColor(prominent_colors));
+      },
+      weak_ptr_factory_.GetWeakPtr()));
 }
 
 void AppListView::RecordFolderMetrics() {
diff --git a/ui/app_list/views/app_list_view.h b/ui/app_list/views/app_list_view.h
index fdb9b71..fa2650b 100644
--- a/ui/app_list/views/app_list_view.h
+++ b/ui/app_list/views/app_list_view.h
@@ -15,6 +15,7 @@
 #include "build/build_config.h"
 #include "ui/app_list/app_list_constants.h"
 #include "ui/app_list/app_list_export.h"
+#include "ui/app_list/app_list_view_delegate.h"
 #include "ui/app_list/app_list_view_delegate_observer.h"
 #include "ui/display/display_observer.h"
 #include "ui/views/widget/widget.h"
@@ -41,7 +42,6 @@
 class ApplicationDragAndDropHost;
 class AppListMainView;
 class AppListModel;
-class AppListViewDelegate;
 class AppsGridView;
 class HideViewAnimationObserver;
 class PaginationModel;
@@ -301,7 +301,8 @@
   // Overridden from AppListViewDelegateObserver:
   void OnWallpaperColorsChanged() override;
 
-  void GetWallpaperProminentColors(std::vector<SkColor>* colors);
+  void GetWallpaperProminentColors(
+      AppListViewDelegate::GetWallpaperProminentColorsCallback callback);
   void SetBackgroundShieldColor();
 
   // Records the number of folders, and the number of items in folders for UMA
@@ -386,6 +387,8 @@
   const std::unique_ptr<ui::AnimationMetricsReporter>
       state_animation_metrics_reporter_;
 
+  base::WeakPtrFactory<AppListView> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(AppListView);
 };
 
diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc
index 12fe6aa..e95a196 100644
--- a/ui/app_list/views/apps_grid_view.cc
+++ b/ui/app_list/views/apps_grid_view.cc
@@ -1589,6 +1589,15 @@
   rows_per_page_ = (items_in_one_page - 1) / cols_ + 1;
 }
 
+size_t AppsGridView::GetAppListItemViewIndexOffset() const {
+  if (folder_delegate_)
+    return 0;
+
+  // The first app list item view must be right behind the expand arrow view.
+  DCHECK(expand_arrow_view_);
+  return GetIndexOf(expand_arrow_view_) + 1;
+}
+
 void AppsGridView::DispatchDragEventForReparent(Pointer pointer,
                                                 const gfx::Point& drag_point) {
   folder_delegate_->DispatchDragEventForReparent(pointer, drag_point);
@@ -1904,6 +1913,11 @@
   DCHECK_GE(current_model_index, 0);
 
   int target_model_index = GetModelIndexFromIndex(target);
+
+  // Reorder the app list item views in accordance with |view_model_|.
+  ReorderChildView(item_view,
+                   GetAppListItemViewIndexOffset() + target_model_index);
+
   if (target_model_index == current_model_index)
     return;
 
@@ -1950,7 +1964,13 @@
           CreateViewForItemAtIndex(folder_item_index);
       target_folder_view->SetBoundsRect(target_view_bounds);
       view_model_.Add(target_folder_view, target_view_index);
-      AddChildView(target_folder_view);
+
+      // use |folder_item_index| instead of |target_view_index| because the
+      // dragged item has not yet been removed from |view_model_| and
+      // |target_view_index| is 1 greater than |folder_item_index| if target
+      // item is behind the dragged item.
+      AddChildViewAt(target_folder_view,
+                     GetAppListItemViewIndexOffset() + folder_item_index);
     } else {
       LOG(ERROR) << "Folder no longer in item_list: " << folder_item_id;
     }
@@ -2001,6 +2021,8 @@
     target_position = item_list_->item_at(target_model_index)->position();
   model_->MoveItemToFolderAt(reparent_item, "", target_position);
   view_model_.Move(current_model_index, target_model_index);
+  ReorderChildView(item_view,
+                   GetAppListItemViewIndexOffset() + target_model_index);
 
   RemoveLastItemFromReparentItemFolderIfNecessary(source_folder_id);
 
@@ -2062,7 +2084,8 @@
       AppListItemView* new_folder_view =
           CreateViewForItemAtIndex(new_folder_index);
       view_model_.Add(new_folder_view, target_view_index);
-      AddChildView(new_folder_view);
+      AddChildViewAt(new_folder_view,
+                     GetAppListItemViewIndexOffset() + new_folder_index);
     } else {
       LOG(ERROR) << "Folder no longer in item_list: " << new_folder_id;
     }
@@ -2113,7 +2136,8 @@
   }
   AppListItemView* last_item_view = CreateViewForItemAtIndex(last_item_index);
   view_model_.Add(last_item_view, last_item_index);
-  AddChildView(last_item_view);
+  AddChildViewAt(last_item_view,
+                 GetAppListItemViewIndexOffset() + last_item_index);
 }
 
 void AppsGridView::CancelFolderItemReparent(AppListItemView* drag_item_view) {
@@ -2196,7 +2220,7 @@
 
   AppListItemView* view = CreateViewForItemAtIndex(index);
   view_model_.Add(view, index);
-  AddChildView(view);
+  AddChildViewAt(view, GetAppListItemViewIndexOffset() + index);
 
   // Ensure that AppListItems that are added to the AppListItemList are not
   // shown while in PEEKING. The visibility of the app icons will be updated
@@ -2227,6 +2251,8 @@
                                    AppListItem* item) {
   EndDrag(true);
   view_model_.Move(from_index, to_index);
+  ReorderChildView(view_model_.view_at(to_index),
+                   GetAppListItemViewIndexOffset() + to_index);
 
   UpdateColsAndRowsForFolder();
   UpdatePaging();
diff --git a/ui/app_list/views/apps_grid_view.h b/ui/app_list/views/apps_grid_view.h
index 3c63f41..c3a8a770 100644
--- a/ui/app_list/views/apps_grid_view.h
+++ b/ui/app_list/views/apps_grid_view.h
@@ -525,6 +525,12 @@
   // Update number of columns and rows for apps within a folder.
   void UpdateColsAndRowsForFolder();
 
+  // Gets the index offset of an AppLitItemView as a child in this view. This is
+  // used to correct the order of the item views after moving the items into the
+  // new positions. As a result, a focus movement bug is resolved. (See
+  // https://crbug.com/791758)
+  size_t GetAppListItemViewIndexOffset() const;
+
   AppListModel* model_ = nullptr;         // Owned by AppListView.
   AppListItemList* item_list_ = nullptr;  // Not owned.
 
diff --git a/ui/app_list/views/apps_grid_view_unittest.cc b/ui/app_list/views/apps_grid_view_unittest.cc
index 571a57fa..472c4525 100644
--- a/ui/app_list/views/apps_grid_view_unittest.cc
+++ b/ui/app_list/views/apps_grid_view_unittest.cc
@@ -221,6 +221,21 @@
     apps_grid_view_->OnKeyPressed(key_event);
   }
 
+  // Tests that the order of item views in the AppsGridView is in accordance
+  // with the order in the view model.
+  void TestAppListItemViewIndice() {
+    const views::ViewModelT<AppListItemView>* view_model =
+        apps_grid_view_->view_model_for_test();
+    DCHECK_GT(view_model->view_size(), 0);
+    const int initial_index =
+        apps_grid_view_->GetIndexOf(view_model->view_at(0));
+    DCHECK_NE(-1, initial_index);
+    for (int i = 0; i < view_model->view_size(); ++i) {
+      EXPECT_EQ(view_model->view_at(i),
+                apps_grid_view_->child_at(i + initial_index));
+    }
+  }
+
   AppListView* app_list_view_ = nullptr;    // Owned by native widget.
   AppsGridView* apps_grid_view_ = nullptr;  // Owned by |app_list_view_|.
   ContentsView* contents_view_ = nullptr;   // Owned by |app_list_view_|.
@@ -500,6 +515,7 @@
   apps_grid_view_->EndDrag(false);
   EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
             model_->GetModelContent());
+  TestAppListItemViewIndice();
 
   // Drag left, past the folder dropping circle.
   gfx::Vector2d last_drag_vector(drag_vector);
@@ -509,6 +525,7 @@
   apps_grid_view_->EndDrag(false);
   EXPECT_EQ(std::string("Item 1,Item 0,Item 2,Item 3"),
             model_->GetModelContent());
+  TestAppListItemViewIndice();
 
   // Drag down, between apps 2 and 3. The gap should open up, making space for
   // app 1 in the bottom left.
@@ -520,6 +537,7 @@
   apps_grid_view_->EndDrag(false);
   EXPECT_EQ(std::string("Item 0,Item 2,Item 1,Item 3"),
             model_->GetModelContent());
+  TestAppListItemViewIndice();
 
   // Drag up, between apps 0 and 2. The gap should open up, making space for app
   // 1 in the top right.
@@ -531,6 +549,7 @@
   apps_grid_view_->EndDrag(false);
   EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
             model_->GetModelContent());
+  TestAppListItemViewIndice();
 
   // Dragging down past the last app should reorder to the last position.
   last_drag_vector = drag_vector;
@@ -541,6 +560,7 @@
   apps_grid_view_->EndDrag(false);
   EXPECT_EQ(std::string("Item 0,Item 2,Item 3,Item 1"),
             model_->GetModelContent());
+  TestAppListItemViewIndice();
 }
 
 TEST_F(AppsGridViewTest, MouseDragFolderReorder) {
@@ -565,6 +585,7 @@
   EXPECT_EQ("Item 2", model_->top_level_item_list()->item_at(0)->id());
   EXPECT_EQ(folder_item->id(), model_->top_level_item_list()->item_at(1)->id());
   test_api_->LayoutToIdealBounds();
+  TestAppListItemViewIndice();
 }
 
 TEST_F(AppsGridViewTest, MouseDragWithCancelDeleteAddItem) {
diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc
index 79be465..7a10593 100644
--- a/ui/app_list/views/search_box_view.cc
+++ b/ui/app_list/views/search_box_view.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <utility>
 #include <vector>
 
 #include "ash/app_list/model/search/search_box_model.h"
@@ -75,7 +76,8 @@
                              AppListView* app_list_view)
     : search_box::SearchBoxViewBase(delegate),
       view_delegate_(view_delegate),
-      app_list_view_(app_list_view) {
+      app_list_view_(app_list_view),
+      weak_ptr_factory_(this) {
   set_is_tablet_mode(app_list_view->is_tablet_mode());
   view_delegate_->AddObserver(this);
 }
@@ -242,8 +244,9 @@
                                            search_box_color()));
 }
 
-void SearchBoxView::GetWallpaperProminentColors(std::vector<SkColor>* colors) {
-  view_delegate_->GetWallpaperProminentColors(colors);
+void SearchBoxView::GetWallpaperProminentColors(
+    AppListViewDelegate::GetWallpaperProminentColorsCallback callback) {
+  view_delegate_->GetWallpaperProminentColors(std::move(callback));
 }
 
 void SearchBoxView::ContentsChanged(views::Textfield* sender,
@@ -307,9 +310,8 @@
   NotifyQueryChanged();
 }
 
-void SearchBoxView::OnWallpaperColorsChanged() {
-  std::vector<SkColor> prominent_colors;
-  GetWallpaperProminentColors(&prominent_colors);
+void SearchBoxView::OnWallpaperProminentColorsReceived(
+    const std::vector<SkColor>& prominent_colors) {
   if (prominent_colors.empty())
     return;
   DCHECK_EQ(static_cast<size_t>(ColorProfileType::NUM_OF_COLOR_PROFILES),
@@ -328,6 +330,12 @@
   SchedulePaint();
 }
 
+void SearchBoxView::OnWallpaperColorsChanged() {
+  GetWallpaperProminentColors(
+      base::BindOnce(&SearchBoxView::OnWallpaperProminentColorsReceived,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
 void SearchBoxView::UpdateSearchBoxBorder() {
   if (search_box()->HasFocus() && !is_search_box_active()) {
     // Show a gray ring around search box to indicate that the search box is
diff --git a/ui/app_list/views/search_box_view.h b/ui/app_list/views/search_box_view.h
index 0d788b3..8a933e47 100644
--- a/ui/app_list/views/search_box_view.h
+++ b/ui/app_list/views/search_box_view.h
@@ -9,6 +9,7 @@
 
 #include "ash/app_list/model/search/search_box_model_observer.h"
 #include "ash/public/cpp/app_list/app_list_types.h"
+#include "ui/app_list/app_list_view_delegate.h"
 #include "ui/app_list/app_list_view_delegate_observer.h"
 #include "ui/chromeos/search_box/search_box_view_base.h"
 
@@ -74,7 +75,13 @@
   void UpdateSearchIcon() override;
 
   // Gets the wallpaper prominent colors.
-  void GetWallpaperProminentColors(std::vector<SkColor>* colors);
+  void GetWallpaperProminentColors(
+      AppListViewDelegate::GetWallpaperProminentColorsCallback callback);
+
+  // Callback invoked when the wallpaper prominent colors are returned after
+  // calling |AppListViewDelegate::GetWallpaperProminentColors|.
+  void OnWallpaperProminentColorsReceived(
+      const std::vector<SkColor>& prominent_colors);
 
   // Overridden from views::TextfieldController:
   void ContentsChanged(views::Textfield* sender,
@@ -103,6 +110,8 @@
   // Owned by views hierarchy.
   app_list::AppListView* app_list_view_;
 
+  base::WeakPtrFactory<SearchBoxView> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(SearchBoxView);
 };
 
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc
index 6a26854d..bec984c 100644
--- a/ui/compositor/test/in_process_context_factory.cc
+++ b/ui/compositor/test/in_process_context_factory.cc
@@ -270,7 +270,7 @@
       GetFrameSinkManager(), display, nullptr /* display_client */,
       context_provider, shared_worker_context_provider_,
       compositor->task_runner(), &gpu_memory_buffer_manager_,
-      &shared_bitmap_manager_);
+      &shared_bitmap_manager_, false /* use_viz_hit_test */);
   compositor->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
 
   data->display->Resize(compositor->size());
diff --git a/ui/message_center/BUILD.gn b/ui/message_center/BUILD.gn
index 2b52de0f..8d657af2 100644
--- a/ui/message_center/BUILD.gn
+++ b/ui/message_center/BUILD.gn
@@ -118,7 +118,6 @@
       sources += [
         "views/bounded_label.cc",
         "views/bounded_label.h",
-        "views/constants.h",
         "views/desktop_popup_alignment_delegate.cc",
         "views/desktop_popup_alignment_delegate.h",
         "views/message_popup_collection.cc",
diff --git a/ui/message_center/public/cpp/notification.h b/ui/message_center/public/cpp/notification.h
index b993bae6..7b453b6 100644
--- a/ui/message_center/public/cpp/notification.h
+++ b/ui/message_center/public/cpp/notification.h
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "base/memory/ref_counted.h"
+#include "base/optional.h"
 #include "base/strings/string16.h"
 #include "base/time/time.h"
 #include "base/values.h"
@@ -45,15 +46,6 @@
   base::string16 message;
 };
 
-enum class ButtonType {
-  // A simple button having an icon and a title that the user can click on.
-  BUTTON,
-
-  // A button having an icon and a title that should also enable the user to
-  // input text, enabling them to quickly respond from the notification.
-  TEXT
-};
-
 enum class SettingsButtonHandler {
   NONE,     // No button. This is the default.
   TRAY,     // Button shown, the tray handles clicks. Only used on Chrome OS.
@@ -77,12 +69,10 @@
   // requirements of the notification.
   gfx::Image icon;
 
-  // Type of this button.
-  ButtonType type = ButtonType::BUTTON;
-
-  // The placeholder string that should be displayed in the input field for TEXT
-  // type buttons until the user has entered a response themselves.
-  base::string16 placeholder;
+  // The placeholder string that should be displayed in the input field for
+  // text input type buttons until the user has entered a response themselves.
+  // If the value is null, there is no input field associated with the button.
+  base::Optional<base::string16> placeholder;
 };
 
 // TODO(estade): add an ALWAYS value to mark notifications as additionally
diff --git a/ui/message_center/views/bounded_label.cc b/ui/message_center/views/bounded_label.cc
index 334cc34..01ad8a3 100644
--- a/ui/message_center/views/bounded_label.cc
+++ b/ui/message_center/views/bounded_label.cc
@@ -278,9 +278,9 @@
 BoundedLabel::~BoundedLabel() {
 }
 
-void BoundedLabel::SetColors(SkColor textColor, SkColor backgroundColor) {
-  label_->SetEnabledColor(textColor);
-  label_->SetBackgroundColor(backgroundColor);
+void BoundedLabel::SetColor(SkColor text_color) {
+  label_->SetEnabledColor(text_color);
+  label_->SetAutoColorReadabilityEnabled(false);
 }
 
 void BoundedLabel::SetLineHeight(int height) {
diff --git a/ui/message_center/views/bounded_label.h b/ui/message_center/views/bounded_label.h
index 1ae1a16f..ff7aa7a4 100644
--- a/ui/message_center/views/bounded_label.h
+++ b/ui/message_center/views/bounded_label.h
@@ -38,7 +38,7 @@
   BoundedLabel(const base::string16& text);
   ~BoundedLabel() override;
 
-  void SetColors(SkColor textColor, SkColor backgroundColor);
+  void SetColor(SkColor text_color);
   void SetLineHeight(int height);  // Pass in 0 for default height.
   void SetLineLimit(int lines);  // Pass in -1 for no limit.
   void SetText(const base::string16& text);  // Additionally clears caches.
diff --git a/ui/message_center/views/constants.h b/ui/message_center/views/constants.h
deleted file mode 100644
index 7fed808..0000000
--- a/ui/message_center/views/constants.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 UI_MESSAGE_CENTER_VIEWS_CONSTANTS_H_
-#define UI_MESSAGE_CENTER_VIEWS_CONSTANTS_H_
-
-#include <stddef.h>
-
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/message_center/public/cpp/message_center_constants.h"
-
-namespace message_center {
-
-// The text background colors below are used only to keep
-// view::Label from modifying the text color and will not actually be drawn.
-// See view::Label's RecalculateColors() for details.
-const SkColor kRegularTextBackgroundColor = SK_ColorWHITE;
-const SkColor kDimTextBackgroundColor = SK_ColorWHITE;
-const SkColor kContextTextBackgroundColor = SK_ColorWHITE;
-
-const int kTextBottomPadding = 12;
-const int kItemTitleToMessagePadding = 3;
-const int kButtonVerticalPadding = 0;
-const int kButtonTitleTopPadding = 0;
-const int kNotificationSettingsPadding = 5;
-
-// Character limits: Displayed text will be subject to the line limits above,
-// but we also remove trailing characters from text to reduce processing cost.
-// Character limit = pixels per line * line limit / min. pixels per character.
-const int kMinPixelsPerTitleCharacter = 4;
-const size_t kMessageCharacterLimit =
-    kNotificationWidth * kMessageExpandedLineLimit / 3;
-const size_t kContextMessageCharacterLimit =
-    kNotificationWidth * kContextMessageLineLimit / 3;
-
-}  // namespace message_center
-
-#endif // UI_MESSAGE_CENTER_VIEWS_CONSTANTS_H_
diff --git a/ui/message_center/views/notification_button.cc b/ui/message_center/views/notification_button.cc
index 86759f5d..5f92deff7 100644
--- a/ui/message_center/views/notification_button.cc
+++ b/ui/message_center/views/notification_button.cc
@@ -7,7 +7,6 @@
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/geometry/insets.h"
 #include "ui/message_center/public/cpp/message_center_constants.h"
-#include "ui/message_center/views/constants.h"
 #include "ui/views/background.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/image_view.h"
@@ -25,8 +24,7 @@
   SetBackground(views::CreateSolidBackground(kNotificationBackgroundColor));
   set_notify_enter_exit_on_child(true);
   SetLayoutManager(std::make_unique<views::BoxLayout>(
-      views::BoxLayout::kHorizontal,
-      gfx::Insets(kButtonVerticalPadding, kButtonHorizontalPadding),
+      views::BoxLayout::kHorizontal, gfx::Insets(0, kButtonHorizontalPadding),
       kButtonIconToTitlePadding));
   SetFocusPainter(views::Painter::CreateSolidFocusPainter(
       kFocusBorderColor, gfx::Insets(1, 2, 2, 2)));
@@ -53,17 +51,14 @@
 }
 
 void NotificationButton::SetTitle(const base::string16& title) {
-  if (title_ != NULL)
+  if (title_)
     delete title_;  // This removes the title from this view's children.
-  if (title.empty()) {
-    title_ = NULL;
-  } else {
+  title_ = nullptr;
+  if (!title.empty()) {
     title_ = new views::Label(title);
     title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
     title_->SetEnabledColor(kRegularTextColor);
-    title_->SetBackgroundColor(kRegularTextBackgroundColor);
-    title_->SetBorder(
-        views::CreateEmptyBorder(kButtonTitleTopPadding, 0, 0, 0));
+    title_->SetAutoColorReadabilityEnabled(false);
     AddChildView(title_);
   }
   SetAccessibleName(title);
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc
index f788856..7dc5d5d 100644
--- a/ui/message_center/views/notification_view.cc
+++ b/ui/message_center/views/notification_view.cc
@@ -27,7 +27,6 @@
 #include "ui/message_center/public/cpp/notification.h"
 #include "ui/message_center/public/cpp/notification_types.h"
 #include "ui/message_center/views/bounded_label.h"
-#include "ui/message_center/views/constants.h"
 #include "ui/message_center/views/notification_button.h"
 #include "ui/message_center/views/notification_control_buttons_view.h"
 #include "ui/message_center/views/padded_button.h"
@@ -52,6 +51,18 @@
 
 namespace {
 
+const int kTextBottomPadding = 12;
+const int kItemTitleToMessagePadding = 3;
+
+// Character limit = pixels per line * line limit / min. pixels per character.
+const int kMinPixelsPerTitleCharacter = 4;
+
+constexpr size_t kMessageCharacterLimit =
+    kNotificationWidth * kMessageExpandedLineLimit / 3;
+
+constexpr size_t kContextMessageCharacterLimit =
+    kNotificationWidth * kContextMessageLineLimit / 3;
+
 // Dimensions.
 const int kProgressBarBottomPadding = 0;
 
@@ -109,14 +120,14 @@
   title->set_collapse_when_hidden(true);
   title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   title->SetEnabledColor(kRegularTextColor);
-  title->SetBackgroundColor(kRegularTextBackgroundColor);
+  title->SetAutoColorReadabilityEnabled(false);
   AddChildView(title);
 
   views::Label* message = new views::Label(item.message);
   message->set_collapse_when_hidden(true);
   message->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   message->SetEnabledColor(kDimTextColor);
-  message->SetBackgroundColor(kDimTextBackgroundColor);
+  message->SetAutoColorReadabilityEnabled(false);
   AddChildView(message);
 
   PreferredSizeChanged();
@@ -391,19 +402,18 @@
   const gfx::FontList& font_list =
       views::Label().font_list().DeriveWithSizeDelta(2);
 
-  int title_character_limit =
+  constexpr int kTitleCharacterLimit =
       kNotificationWidth * kMaxTitleLines / kMinPixelsPerTitleCharacter;
 
-  base::string16 title = gfx::TruncateString(notification.title(),
-                                             title_character_limit,
-                                             gfx::WORD_BREAK);
+  base::string16 title = gfx::TruncateString(
+      notification.title(), kTitleCharacterLimit, gfx::WORD_BREAK);
   if (!title_view_) {
     int padding = kTitleLineHeight - font_list.GetHeight();
 
     title_view_ = new BoundedLabel(title, font_list);
     title_view_->SetLineHeight(kTitleLineHeight);
     title_view_->SetLineLimit(kMaxTitleLines);
-    title_view_->SetColors(kRegularTextColor, kRegularTextBackgroundColor);
+    title_view_->SetColor(kRegularTextColor);
     title_view_->SetBorder(MakeTextBorder(padding, 3, 0));
     top_view_->AddChildView(title_view_);
   } else {
@@ -429,7 +439,7 @@
     int padding = kMessageLineHeight - views::Label().font_list().GetHeight();
     message_view_ = new BoundedLabel(text);
     message_view_->SetLineHeight(kMessageLineHeight);
-    message_view_->SetColors(kRegularTextColor, kDimTextBackgroundColor);
+    message_view_->SetColor(kRegularTextColor);
     message_view_->SetBorder(MakeTextBorder(padding, 4, 0));
     top_view_->AddChildView(message_view_);
   } else {
@@ -473,8 +483,7 @@
     context_message_view_ = new BoundedLabel(message);
     context_message_view_->SetLineLimit(kContextMessageLineLimit);
     context_message_view_->SetLineHeight(kMessageLineHeight);
-    context_message_view_->SetColors(kDimTextColor,
-                                     kContextTextBackgroundColor);
+    context_message_view_->SetColor(kDimTextColor);
     context_message_view_->SetBorder(MakeTextBorder(padding, 4, 0));
     top_view_->AddChildView(context_message_view_);
   } else {
diff --git a/ui/message_center/views/notification_view_md.cc b/ui/message_center/views/notification_view_md.cc
index f715b38..1688e96 100644
--- a/ui/message_center/views/notification_view_md.cc
+++ b/ui/message_center/views/notification_view_md.cc
@@ -24,7 +24,6 @@
 #include "ui/message_center/public/cpp/notification_types.h"
 #include "ui/message_center/vector_icons.h"
 #include "ui/message_center/views/bounded_label.h"
-#include "ui/message_center/views/constants.h"
 #include "ui/message_center/views/notification_control_buttons_view.h"
 #include "ui/message_center/views/notification_header_view.h"
 #include "ui/message_center/views/padded_button.h"
@@ -120,8 +119,14 @@
     kLeftContentPadding.right() - kContentRowPadding.left() -
     kContentRowPadding.right();
 
-// "Roboto-Regular, 13sp" is specified in the mock.
-constexpr int kTextFontSize = 13;
+const int kMinPixelsPerTitleCharacter = 4;
+
+// Character limit = pixels per line * line limit / min. pixels per character.
+constexpr size_t kMessageCharacterLimit =
+    kNotificationWidth * kMessageExpandedLineLimit / 3;
+
+// The default is 12, so this normally come out to 13.
+constexpr int kTextFontSizeDelta = 1;
 
 // In progress notification, if both the title and the message are long, the
 // message would be prioritized and the title would be elided.
@@ -132,10 +137,8 @@
 // FontList for the texts except for the header.
 gfx::FontList GetTextFontList() {
   gfx::Font default_font;
-  int font_size_delta = kTextFontSize - default_font.GetFontSize();
-  gfx::Font font = default_font.Derive(font_size_delta, gfx::Font::NORMAL,
+  gfx::Font font = default_font.Derive(kTextFontSizeDelta, gfx::Font::NORMAL,
                                        gfx::Font::Weight::NORMAL);
-  DCHECK_EQ(kTextFontSize, font.GetFontSize());
   return gfx::FontList(font);
 }
 
@@ -173,7 +176,7 @@
   title->set_collapse_when_hidden(true);
   title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   title->SetEnabledColor(kRegularTextColorMD);
-  title->SetBackgroundColor(kDimTextBackgroundColor);
+  title->SetAutoColorReadabilityEnabled(false);
   AddChildView(title);
 
   views::Label* message = new views::Label(l10n_util::GetStringFUTF16(
@@ -182,7 +185,7 @@
   message->set_collapse_when_hidden(true);
   message->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   message->SetEnabledColor(kDimTextColorMD);
-  message->SetBackgroundColor(kDimTextBackgroundColor);
+  message->SetAutoColorReadabilityEnabled(false);
   AddChildView(message);
 }
 
@@ -329,14 +332,13 @@
 
 // NotificationButtonMD ////////////////////////////////////////////////////////
 
-NotificationButtonMD::NotificationButtonMD(views::ButtonListener* listener,
-                                           bool is_inline_reply,
-                                           const base::string16& label,
-                                           const base::string16& placeholder)
+NotificationButtonMD::NotificationButtonMD(
+    views::ButtonListener* listener,
+    const base::string16& label,
+    const base::Optional<base::string16>& placeholder)
     : views::LabelButton(listener,
                          base::i18n::ToUpper(label),
                          views::style::CONTEXT_BUTTON_MD),
-      is_inline_reply_(is_inline_reply),
       placeholder_(placeholder) {
   SetHorizontalAlignment(gfx::ALIGN_CENTER);
   SetInkDropMode(views::LabelButton::InkDropMode::ON);
@@ -783,10 +785,10 @@
   for (size_t i = 0; i < action_buttons_.size(); ++i) {
     if (sender != action_buttons_[i])
       continue;
-    if (action_buttons_[i]->is_inline_reply()) {
+    if (action_buttons_[i]->placeholder()) {
       inline_reply_->textfield()->set_index(i);
       inline_reply_->textfield()->set_placeholder(
-          action_buttons_[i]->placeholder());
+          *action_buttons_[i]->placeholder());
       inline_reply_->textfield()->RequestFocus();
       inline_reply_->AnimateBackground(*event.AsLocatedEvent());
       inline_reply_->SetVisible(true);
@@ -887,7 +889,7 @@
   if (!message_view_) {
     message_view_ = new BoundedLabel(text, font_list);
     message_view_->SetLineLimit(kMaxLinesForMessageView);
-    message_view_->SetColors(kDimTextColorMD, kContextTextBackgroundColor);
+    message_view_->SetColor(kDimTextColorMD);
 
     left_content_->AddChildView(message_view_);
   } else {
@@ -1048,7 +1050,7 @@
 
 void NotificationViewMD::CreateOrUpdateActionButtonViews(
     const Notification& notification) {
-  std::vector<ButtonInfo> buttons = notification.buttons();
+  const std::vector<ButtonInfo>& buttons = notification.buttons();
   bool new_buttons = action_buttons_.size() != buttons.size();
 
   if (new_buttons || buttons.size() == 0) {
@@ -1062,9 +1064,8 @@
   for (size_t i = 0; i < buttons.size(); ++i) {
     ButtonInfo button_info = buttons[i];
     if (new_buttons) {
-      bool is_inline_reply = button_info.type == ButtonType::TEXT;
       NotificationButtonMD* button = new NotificationButtonMD(
-          this, is_inline_reply, button_info.title, button_info.placeholder);
+          this, button_info.title, button_info.placeholder);
       action_buttons_.push_back(button);
       action_buttons_row_->AddChildView(button);
     } else {
@@ -1130,8 +1131,8 @@
   settings_row_->SetVisible(false);
 
   settings_done_button_ = new NotificationButtonMD(
-      this, false, l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS_DONE),
-      base::EmptyString16());
+      this, l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS_DONE),
+      base::nullopt);
   auto* settings_button_row = new views::View;
   auto settings_button_layout = std::make_unique<views::BoxLayout>(
       views::BoxLayout::kHorizontal, kSettingsButtonRowPadding, 0);
diff --git a/ui/message_center/views/notification_view_md.h b/ui/message_center/views/notification_view_md.h
index 331cc05..e35c266 100644
--- a/ui/message_center/views/notification_view_md.h
+++ b/ui/message_center/views/notification_view_md.h
@@ -9,6 +9,7 @@
 
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
+#include "base/optional.h"
 #include "ui/message_center/message_center_export.h"
 #include "ui/message_center/views/message_view.h"
 #include "ui/views/controls/button/button.h"
@@ -114,9 +115,8 @@
   // |placeholder| is placeholder text shown on the input field. Only used when
   // |is_inline_reply| is true.
   NotificationButtonMD(views::ButtonListener* listener,
-                       bool is_inline_reply,
                        const base::string16& label,
-                       const base::string16& placeholder);
+                       const base::Optional<base::string16>& placeholder);
   ~NotificationButtonMD() override;
 
   void SetText(const base::string16& text) override;
@@ -127,12 +127,12 @@
 
   SkColor enabled_color_for_testing() { return label()->enabled_color(); }
 
-  bool is_inline_reply() const { return is_inline_reply_; }
-  const base::string16& placeholder() const { return placeholder_; }
+  const base::Optional<base::string16>& placeholder() const {
+    return placeholder_;
+  }
 
  private:
-  const bool is_inline_reply_;
-  const base::string16 placeholder_;
+  const base::Optional<base::string16> placeholder_;
 
   DISALLOW_COPY_AND_ASSIGN(NotificationButtonMD);
 };
diff --git a/ui/message_center/views/notification_view_md_unittest.cc b/ui/message_center/views/notification_view_md_unittest.cc
index 3786067..ded9ae6 100644
--- a/ui/message_center/views/notification_view_md_unittest.cc
+++ b/ui/message_center/views/notification_view_md_unittest.cc
@@ -472,7 +472,7 @@
   delegate_->set_expecting_reply_submission(true);
 
   std::vector<ButtonInfo> buttons = CreateButtons(2);
-  buttons[1].type = ButtonType::TEXT;
+  buttons[1].placeholder = base::string16();
   notification()->set_buttons(buttons);
   UpdateNotificationViews();
   widget()->Show();
diff --git a/ui/message_center/views/notification_view_unittest.cc b/ui/message_center/views/notification_view_unittest.cc
index aba5451..3cbbf301 100644
--- a/ui/message_center/views/notification_view_unittest.cc
+++ b/ui/message_center/views/notification_view_unittest.cc
@@ -25,9 +25,9 @@
 #include "ui/message_center/message_center.h"
 #include "ui/message_center/message_center_style.h"
 #include "ui/message_center/notification_list.h"
+#include "ui/message_center/public/cpp/message_center_constants.h"
 #include "ui/message_center/public/cpp/notification.h"
 #include "ui/message_center/public/cpp/notification_types.h"
-#include "ui/message_center/views/constants.h"
 #include "ui/message_center/views/message_view_factory.h"
 #include "ui/message_center/views/notification_button.h"
 #include "ui/message_center/views/notification_control_buttons_view.h"