diff --git a/DEPS b/DEPS
index fea83f6c..d6b1086 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '6ccd2cabaac810edccab620d8a944f64b0432d44',
+  'skia_revision': '0bd8f36309293720b44af92f113f6ebe96d54779',
   # 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': '7eb6499a3bc6052ae8bd4dfc260b09de8a8c97d6',
+  'v8_revision': '007511a499ad81200ac4104bdcc4e12c6135c223',
   # 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.
@@ -56,7 +56,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
-  'buildtools_revision': 'a7cc7a3e21a061975b33dcdcd81a9716ba614c3c',
+  'buildtools_revision': 'c302711306f19ec9d29ac3461b09ecd4c781fac0',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '6438c4f36da162f72e0d53e8fff45cd6687b7f5c',
+  'pdfium_revision': '5535ac7897358d9b5f2f7eb508f4aa44791e501f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -96,7 +96,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': '3c9b30e0cc0d45d6728dec4440585ffd3ac89b2a',
+  'catapult_revision': '9907db54ee404c8a3efb585fa7db4c58e6966ef3',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
diff --git a/ash/system/chromeos/power/tablet_power_button_controller.cc b/ash/system/chromeos/power/tablet_power_button_controller.cc
index fb5c1393..cb316de 100644
--- a/ash/system/chromeos/power/tablet_power_button_controller.cc
+++ b/ash/system/chromeos/power/tablet_power_button_controller.cc
@@ -22,8 +22,14 @@
 namespace {
 
 // Amount of time the power button must be held to start the pre-shutdown
-// animation when in tablet mode.
-constexpr int kShutdownTimeoutMs = 500;
+// animation when in tablet mode. This differs depending on whether the screen
+// is on or off when the power button is initially pressed.
+constexpr int kShutdownWhenScreenOnTimeoutMs = 500;
+// TODO(derat): This is currently set to a high value to work around delays in
+// powerd's reports of button-up events when the preceding button-down event
+// turns the display on. Set it to a lower value once powerd no longer blocks on
+// asking Chrome to turn the display on: http://crbug.com/685734
+constexpr int kShutdownWhenScreenOffTimeoutMs = 2000;
 
 // Amount of time since last SuspendDone() that power button event needs to be
 // ignored.
@@ -221,9 +227,11 @@
 }
 
 void TabletPowerButtonController::StartShutdownTimer() {
-  shutdown_timer_.Start(FROM_HERE,
-                        base::TimeDelta::FromMilliseconds(kShutdownTimeoutMs),
-                        this, &TabletPowerButtonController::OnShutdownTimeout);
+  base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(
+      screen_off_when_power_button_down_ ? kShutdownWhenScreenOffTimeoutMs
+                                         : kShutdownWhenScreenOnTimeoutMs);
+  shutdown_timer_.Start(FROM_HERE, timeout, this,
+                        &TabletPowerButtonController::OnShutdownTimeout);
 }
 
 void TabletPowerButtonController::OnShutdownTimeout() {
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 7f46e71..69dfcc5 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1083,6 +1083,7 @@
     "win/wrapped_window_proc.h",
   ]
 
+  all_dependent_configs = []
   defines = []
   data = []
 
@@ -1113,9 +1114,37 @@
   }
 
   if (use_experimental_allocator_shim) {
-    # The allocator shim is part of the base API. This is to allow clients of
-    # base should to install hooks into the allocator path.
-    public_deps += [ "//base/allocator:unified_allocator_shim" ]
+    # TODO(primiano): support other platforms, currently this works only on
+    # Linux/CrOS/Android. http://crbug.com/550886 .
+    sources += [
+      "allocator/allocator_shim.cc",
+      "allocator/allocator_shim.h",
+      "allocator/allocator_shim_internals.h",
+      "allocator/allocator_shim_override_cpp_symbols.h",
+      "allocator/allocator_shim_override_libc_symbols.h",
+    ]
+    if (is_win) {
+      sources += [
+        "allocator/allocator_shim_default_dispatch_to_winheap.cc",
+        "allocator/allocator_shim_override_ucrt_symbols_win.h",
+        "allocator/winheap_stubs_win.cc",
+        "allocator/winheap_stubs_win.h",
+      ]
+    } else if (is_linux && use_allocator == "tcmalloc") {
+      sources += [
+        "allocator/allocator_shim_default_dispatch_to_tcmalloc.cc",
+        "allocator/allocator_shim_override_glibc_weak_symbols.h",
+      ]
+      deps += [ "//base/allocator:tcmalloc" ]
+    } else if (is_linux && use_allocator == "none") {
+      sources += [ "allocator/allocator_shim_default_dispatch_to_glibc.cc" ]
+    } else if (is_android && use_allocator == "none") {
+      sources += [
+        "allocator/allocator_shim_default_dispatch_to_linker_wrapped_symbols.cc",
+        "allocator/allocator_shim_override_linker_wrapped_symbols.h",
+      ]
+      all_dependent_configs += [ "//base/allocator:wrap_malloc_symbols" ]
+    }
   }
 
   # Allow more direct string conversions on platforms with native utf8
@@ -1376,7 +1405,7 @@
       "userenv.lib",
       "winmm.lib",
     ]
-    all_dependent_configs = [ ":base_win_linker_flags" ]
+    all_dependent_configs += [ ":base_win_linker_flags" ]
   } else if (!is_nacl || is_nacl_nonsfi) {
     # Non-Windows.
     deps += [ "//base/third_party/libevent" ]
@@ -1433,7 +1462,7 @@
     defines += [ "USE_SYMBOLIZE" ]
 
     configs += linux_configs
-    all_dependent_configs = linux_configs
+    all_dependent_configs += linux_configs
 
     # These dependencies are not required on Android, and in the case
     # of xdg_mime must be excluded due to licensing restrictions.
diff --git a/base/allocator/BUILD.gn b/base/allocator/BUILD.gn
index 4015196..8cdb061 100644
--- a/base/allocator/BUILD.gn
+++ b/base/allocator/BUILD.gn
@@ -294,56 +294,16 @@
   ]
 }
 
-if (use_experimental_allocator_shim) {
-  # Used to shim malloc symbols on Android. see //base/allocator/README.md.
-  config("wrap_malloc_symbols") {
-    ldflags = [
-      "-Wl,-wrap,calloc",
-      "-Wl,-wrap,free",
-      "-Wl,-wrap,malloc",
-      "-Wl,-wrap,memalign",
-      "-Wl,-wrap,posix_memalign",
-      "-Wl,-wrap,pvalloc",
-      "-Wl,-wrap,realloc",
-      "-Wl,-wrap,valloc",
-    ]
-  }
-
-  source_set("unified_allocator_shim") {
-    # TODO(primiano): support other platforms, currently this works only on
-    # Linux/CrOS/Android. http://crbug.com/550886 .
-    configs += [ "//base:base_implementation" ]  # for BASE_EXPORT
-    visibility = [ "//base:base" ]
-    sources = [
-      "allocator_shim.cc",
-      "allocator_shim.h",
-      "allocator_shim_internals.h",
-      "allocator_shim_override_cpp_symbols.h",
-      "allocator_shim_override_libc_symbols.h",
-    ]
-    if (is_win) {
-      sources += [
-        "allocator_shim_default_dispatch_to_winheap.cc",
-        "allocator_shim_override_ucrt_symbols_win.h",
-        "winheap_stubs_win.cc",
-        "winheap_stubs_win.h",
-      ]
-    } else if (is_linux && use_allocator == "tcmalloc") {
-      sources += [
-        "allocator_shim_default_dispatch_to_tcmalloc.cc",
-        "allocator_shim_override_glibc_weak_symbols.h",
-      ]
-      deps = [
-        ":tcmalloc",
-      ]
-    } else if (is_linux && use_allocator == "none") {
-      sources += [ "allocator_shim_default_dispatch_to_glibc.cc" ]
-    } else if (is_android && use_allocator == "none") {
-      sources += [
-        "allocator_shim_default_dispatch_to_linker_wrapped_symbols.cc",
-        "allocator_shim_override_linker_wrapped_symbols.h",
-      ]
-      all_dependent_configs = [ ":wrap_malloc_symbols" ]
-    }
-  }
+# Used to shim malloc symbols on Android. see //base/allocator/README.md.
+config("wrap_malloc_symbols") {
+  ldflags = [
+    "-Wl,-wrap,calloc",
+    "-Wl,-wrap,free",
+    "-Wl,-wrap,malloc",
+    "-Wl,-wrap,memalign",
+    "-Wl,-wrap,posix_memalign",
+    "-Wl,-wrap,pvalloc",
+    "-Wl,-wrap,realloc",
+    "-Wl,-wrap,valloc",
+  ]
 }
diff --git a/build/OWNERS b/build/OWNERS
index 122b6e6..e132538 100644
--- a/build/OWNERS
+++ b/build/OWNERS
@@ -10,3 +10,4 @@
 per-file mac_toolchain.py=justincohen@chromium.org
 per-file package_mac_toolchain.py=erikchen@chromium.org
 per-file package_mac_toolchain.py=justincohen@chromium.org
+per-file whitespace_file.txt=*
diff --git a/build/android/pylib/local/device/local_device_gtest_run.py b/build/android/pylib/local/device/local_device_gtest_run.py
index c361f2f..040e93a 100644
--- a/build/android/pylib/local/device/local_device_gtest_run.py
+++ b/build/android/pylib/local/device/local_device_gtest_run.py
@@ -438,7 +438,7 @@
           result.SetTombstonesUrl(tombstones_url)
 
     not_run_tests = set(test).difference(set(r.GetName() for r in results))
-    return results, list(not_run_tests)
+    return results, list(not_run_tests) if results else None
 
   #override
   def TearDown(self):
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index b8084dd..592589a 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -450,8 +450,6 @@
     "trees/element_id.h",
     "trees/latency_info_swap_promise_monitor.cc",
     "trees/latency_info_swap_promise_monitor.h",
-    "trees/layer_tree.cc",
-    "trees/layer_tree.h",
     "trees/layer_tree_host.cc",
     "trees/layer_tree_host.h",
     "trees/layer_tree_host_client.h",
@@ -528,6 +526,7 @@
     "//gpu/ipc:gl_in_process_context",
     "//gpu/skia_bindings:skia_bindings",
     "//media",
+    "//mojo/public/cpp/bindings:struct_traits",
     "//third_party/libyuv",
     "//ui/events:events_base",
     "//ui/gfx",
diff --git a/cc/debug/invalidation_benchmark.cc b/cc/debug/invalidation_benchmark.cc
index 3923c14..6e6d3433 100644
--- a/cc/debug/invalidation_benchmark.cc
+++ b/cc/debug/invalidation_benchmark.cc
@@ -14,7 +14,7 @@
 #include "cc/layers/layer.h"
 #include "cc/layers/picture_layer.h"
 #include "cc/trees/draw_property_utils.h"
-#include "cc/trees/layer_tree.h"
+#include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_host_common.h"
 #include "ui/gfx/geometry/rect.h"
 
@@ -63,9 +63,10 @@
 InvalidationBenchmark::~InvalidationBenchmark() {
 }
 
-void InvalidationBenchmark::DidUpdateLayers(LayerTree* layer_tree) {
+void InvalidationBenchmark::DidUpdateLayers(LayerTreeHost* layer_tree_host) {
   LayerTreeHostCommon::CallFunctionForEveryLayer(
-      layer_tree, [this](Layer* layer) { layer->RunMicroBenchmark(this); });
+      layer_tree_host,
+      [this](Layer* layer) { layer->RunMicroBenchmark(this); });
 }
 
 void InvalidationBenchmark::RunOnLayer(PictureLayer* layer) {
@@ -75,7 +76,7 @@
   if (!invertible)
     from_screen = gfx::Transform();
   gfx::Rect viewport_rect = MathUtil::ProjectEnclosingClippedRect(
-      from_screen, gfx::Rect(layer->GetLayerTree()->device_viewport_size()));
+      from_screen, gfx::Rect(layer->layer_tree_host()->device_viewport_size()));
   visible_layer_rect.Intersect(viewport_rect);
   switch (mode_) {
     case FIXED_SIZE: {
diff --git a/cc/debug/invalidation_benchmark.h b/cc/debug/invalidation_benchmark.h
index ca69957..a04663d6 100644
--- a/cc/debug/invalidation_benchmark.h
+++ b/cc/debug/invalidation_benchmark.h
@@ -13,7 +13,7 @@
 
 namespace cc {
 
-class LayerTree;
+class LayerTreeHost;
 
 // NOTE: this benchmark will not measure or return any results, it will simply
 // invalidate a certain area of each layer every frame. It is intended to be
@@ -26,7 +26,7 @@
   ~InvalidationBenchmark() override;
 
   // Implements MicroBenchmark interface.
-  void DidUpdateLayers(LayerTree* layer_tree) override;
+  void DidUpdateLayers(LayerTreeHost* layer_tree_host) override;
   void RunOnLayer(PictureLayer* layer) override;
   bool ProcessMessage(std::unique_ptr<base::Value> value) override;
 
diff --git a/cc/debug/micro_benchmark.cc b/cc/debug/micro_benchmark.cc
index ddedafc4..4bbca39 100644
--- a/cc/debug/micro_benchmark.cc
+++ b/cc/debug/micro_benchmark.cc
@@ -28,7 +28,7 @@
   return is_done_;
 }
 
-void MicroBenchmark::DidUpdateLayers(LayerTree* layer_tree) {}
+void MicroBenchmark::DidUpdateLayers(LayerTreeHost* layer_tree_host) {}
 
 void MicroBenchmark::NotifyDone(std::unique_ptr<base::Value> result) {
   callback_.Run(std::move(result));
diff --git a/cc/debug/micro_benchmark.h b/cc/debug/micro_benchmark.h
index 454aab6f..6703bf4 100644
--- a/cc/debug/micro_benchmark.h
+++ b/cc/debug/micro_benchmark.h
@@ -17,8 +17,8 @@
 
 namespace cc {
 
-class LayerTree;
 class Layer;
+class LayerTreeHost;
 class PictureLayer;
 class MicroBenchmarkImpl;
 class CC_EXPORT MicroBenchmark {
@@ -29,7 +29,7 @@
   virtual ~MicroBenchmark();
 
   bool IsDone() const;
-  virtual void DidUpdateLayers(LayerTree* layer_tree);
+  virtual void DidUpdateLayers(LayerTreeHost* layer_tree_host);
   int id() const { return id_; }
   void set_id(int id) { id_ = id; }
 
diff --git a/cc/debug/micro_benchmark_controller.cc b/cc/debug/micro_benchmark_controller.cc
index ac393a36..94d3d2e 100644
--- a/cc/debug/micro_benchmark_controller.cc
+++ b/cc/debug/micro_benchmark_controller.cc
@@ -103,7 +103,7 @@
 void MicroBenchmarkController::DidUpdateLayers() {
   for (const auto& benchmark : benchmarks_) {
     if (!benchmark->IsDone())
-      benchmark->DidUpdateLayers(host_->GetLayerTree());
+      benchmark->DidUpdateLayers(host_);
   }
 
   CleanUpFinishedBenchmarks();
diff --git a/cc/debug/rasterize_and_record_benchmark.cc b/cc/debug/rasterize_and_record_benchmark.cc
index 0ee705d13d..3b53a4ce 100644
--- a/cc/debug/rasterize_and_record_benchmark.cc
+++ b/cc/debug/rasterize_and_record_benchmark.cc
@@ -20,7 +20,7 @@
 #include "cc/layers/picture_layer.h"
 #include "cc/playback/display_item_list.h"
 #include "cc/playback/recording_source.h"
-#include "cc/trees/layer_tree.h"
+#include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_host_common.h"
 #include "skia/ext/analysis_canvas.h"
 #include "third_party/skia/include/utils/SkPictureUtils.h"
@@ -75,7 +75,7 @@
       record_repeat_count_(kDefaultRecordRepeatCount),
       settings_(std::move(value)),
       main_thread_benchmark_done_(false),
-      layer_tree_(nullptr),
+      layer_tree_host_(nullptr),
       weak_ptr_factory_(this) {
   base::DictionaryValue* settings = nullptr;
   settings_->GetAsDictionary(&settings);
@@ -90,10 +90,12 @@
   weak_ptr_factory_.InvalidateWeakPtrs();
 }
 
-void RasterizeAndRecordBenchmark::DidUpdateLayers(LayerTree* layer_tree) {
-  layer_tree_ = layer_tree;
+void RasterizeAndRecordBenchmark::DidUpdateLayers(
+    LayerTreeHost* layer_tree_host) {
+  layer_tree_host_ = layer_tree_host;
   LayerTreeHostCommon::CallFunctionForEveryLayer(
-      layer_tree, [this](Layer* layer) { layer->RunMicroBenchmark(this); });
+      layer_tree_host_,
+      [this](Layer* layer) { layer->RunMicroBenchmark(this); });
 
   DCHECK(!results_.get());
   results_ = base::WrapUnique(new base::DictionaryValue);
@@ -132,7 +134,7 @@
 }
 
 void RasterizeAndRecordBenchmark::RunOnLayer(PictureLayer* layer) {
-  DCHECK(layer_tree_);
+  DCHECK(layer_tree_host_);
 
   if (!layer->DrawsContent())
     return;
diff --git a/cc/debug/rasterize_and_record_benchmark.h b/cc/debug/rasterize_and_record_benchmark.h
index 63d7a34..91734a50 100644
--- a/cc/debug/rasterize_and_record_benchmark.h
+++ b/cc/debug/rasterize_and_record_benchmark.h
@@ -23,7 +23,7 @@
 
 namespace cc {
 
-class LayerTree;
+class LayerTreeHost;
 
 class RasterizeAndRecordBenchmark : public MicroBenchmark {
  public:
@@ -33,7 +33,7 @@
   ~RasterizeAndRecordBenchmark() override;
 
   // Implements MicroBenchmark interface.
-  void DidUpdateLayers(LayerTree* layer_tree) override;
+  void DidUpdateLayers(LayerTreeHost* layer_tree_host) override;
   void RunOnLayer(PictureLayer* layer) override;
 
   std::unique_ptr<MicroBenchmarkImpl> CreateBenchmarkImpl(
@@ -59,7 +59,7 @@
   // The following is used in DCHECKs.
   bool main_thread_benchmark_done_;
 
-  LayerTree* layer_tree_;
+  LayerTreeHost* layer_tree_host_;
 
   base::WeakPtrFactory<RasterizeAndRecordBenchmark> weak_ptr_factory_;
 };
diff --git a/cc/debug/unittest_only_benchmark.cc b/cc/debug/unittest_only_benchmark.cc
index 568f9609..321444d 100644
--- a/cc/debug/unittest_only_benchmark.cc
+++ b/cc/debug/unittest_only_benchmark.cc
@@ -33,7 +33,7 @@
   weak_ptr_factory_.InvalidateWeakPtrs();
 }
 
-void UnittestOnlyBenchmark::DidUpdateLayers(LayerTree* layer_tree) {
+void UnittestOnlyBenchmark::DidUpdateLayers(LayerTreeHost* layer_tree_host) {
   NotifyDone(nullptr);
 }
 
diff --git a/cc/debug/unittest_only_benchmark.h b/cc/debug/unittest_only_benchmark.h
index 2ed3578..ffeaceb 100644
--- a/cc/debug/unittest_only_benchmark.h
+++ b/cc/debug/unittest_only_benchmark.h
@@ -16,7 +16,7 @@
                         const DoneCallback& callback);
   ~UnittestOnlyBenchmark() override;
 
-  void DidUpdateLayers(LayerTree* layer_tree) override;
+  void DidUpdateLayers(LayerTreeHost* layer_tree_host) override;
   bool ProcessMessage(std::unique_ptr<base::Value> value) override;
 
  protected:
diff --git a/cc/ipc/BUILD.gn b/cc/ipc/BUILD.gn
index df7e55d..29084cc 100644
--- a/cc/ipc/BUILD.gn
+++ b/cc/ipc/BUILD.gn
@@ -56,6 +56,7 @@
     "surface_info.mojom",
     "surface_reference.mojom",
     "surface_sequence.mojom",
+    "texture_mailbox.mojom",
     "transferable_resource.mojom",
   ]
 
diff --git a/cc/ipc/struct_traits_unittest.cc b/cc/ipc/struct_traits_unittest.cc
index 95f4c06..f5313cf 100644
--- a/cc/ipc/struct_traits_unittest.cc
+++ b/cc/ipc/struct_traits_unittest.cc
@@ -101,6 +101,11 @@
     callback.Run(s);
   }
 
+  void EchoTextureMailbox(const TextureMailbox& t,
+                          const EchoTextureMailboxCallback& callback) override {
+    callback.Run(t);
+  }
+
   void EchoTransferableResource(
       const TransferableResource& t,
       const EchoTransferableResourceCallback& callback) override {
@@ -815,6 +820,57 @@
   EXPECT_EQ(sorting_context_id, output_sqs.sorting_context_id);
 }
 
+TEST_F(StructTraitsTest, TextureMailbox) {
+  const int8_t mailbox_name[GL_MAILBOX_SIZE_CHROMIUM] = {
+      0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2};
+  const gpu::CommandBufferNamespace command_buffer_namespace = gpu::IN_PROCESS;
+  const int32_t extra_data_field = 0xbeefbeef;
+  const gpu::CommandBufferId command_buffer_id(
+      gpu::CommandBufferId::FromUnsafeValue(0xdeadbeef));
+  const uint64_t release_count = 0xdeadbeefdeadL;
+  const gpu::SyncToken sync_token(command_buffer_namespace, extra_data_field,
+                                  command_buffer_id, release_count);
+  const uint32_t texture_target = 1337;
+  const gfx::Size size_in_pixels(93, 24);
+  const bool is_overlay_candidate = true;
+  const bool secure_output_only = true;
+  const bool nearest_neighbor = true;
+  const gfx::ColorSpace color_space(4, 5, 9, gfx::ColorSpace::RangeID::LIMITED);
+#if defined(OS_ANDROID)
+  const bool is_backed_by_surface_texture = true;
+  const bool wants_promotion_hint = true;
+#endif
+
+  gpu::Mailbox mailbox;
+  mailbox.SetName(mailbox_name);
+  TextureMailbox input(mailbox, sync_token, texture_target, size_in_pixels,
+                       is_overlay_candidate, secure_output_only);
+  input.set_nearest_neighbor(nearest_neighbor);
+  input.set_color_space(color_space);
+#if defined(OS_ANDROID)
+  input.set_is_backed_by_surface_texture(is_backed_by_surface_texture);
+  input.set_wants_promotion_hint(wants_promotion_hint);
+#endif
+
+  mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy();
+  TextureMailbox output;
+  proxy->EchoTextureMailbox(input, &output);
+
+  EXPECT_EQ(mailbox, output.mailbox());
+  EXPECT_EQ(sync_token, output.sync_token());
+  EXPECT_EQ(texture_target, output.target());
+  EXPECT_EQ(size_in_pixels, output.size_in_pixels());
+  EXPECT_EQ(is_overlay_candidate, output.is_overlay_candidate());
+  EXPECT_EQ(secure_output_only, output.secure_output_only());
+  EXPECT_EQ(nearest_neighbor, output.nearest_neighbor());
+  EXPECT_EQ(color_space, output.color_space());
+#if defined(OS_ANDROID)
+  EXPECT_EQ(is_backed_by_surface_texture,
+            output.is_backed_by_surface_texture());
+  EXPECT_EQ(wants_promotion_hint, output.wants_promotion_hint());
+#endif
+}
+
 TEST_F(StructTraitsTest, TransferableResource) {
   const uint32_t id = 1337;
   const ResourceFormat format = ALPHA_8;
diff --git a/cc/ipc/texture_mailbox.mojom b/cc/ipc/texture_mailbox.mojom
new file mode 100644
index 0000000..90a92b7
--- /dev/null
+++ b/cc/ipc/texture_mailbox.mojom
@@ -0,0 +1,22 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module cc.mojom;
+
+import "gpu/ipc/common/mailbox_holder.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
+import "ui/gfx/mojo/color_space.mojom";
+
+// TODO(samans): Add shared_bitmap. See crbug.com/686221.
+// See cc/resources/texture_mailbox.h.
+struct TextureMailbox {
+  gpu.mojom.MailboxHolder mailbox_holder;
+  gfx.mojom.Size size_in_pixels;
+  bool is_overlay_candidate;
+  bool is_backed_by_surface_texture;
+  bool wants_promotion_hint;
+  bool secure_output_only;
+  bool nearest_neighbor;
+  gfx.mojom.ColorSpace color_space;
+};
diff --git a/cc/ipc/texture_mailbox.typemap b/cc/ipc/texture_mailbox.typemap
new file mode 100644
index 0000000..9855c31
--- /dev/null
+++ b/cc/ipc/texture_mailbox.typemap
@@ -0,0 +1,11 @@
+# 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.
+
+mojom = "//cc/ipc/texture_mailbox.mojom"
+public_headers = [ "//cc/resources/texture_mailbox.h" ]
+traits_headers = [ "//cc/ipc/texture_mailbox_struct_traits.h" ]
+sources = [
+  "//cc/ipc:struct_traits",
+]
+type_mappings = [ "cc.mojom.TextureMailbox=cc::TextureMailbox" ]
diff --git a/cc/ipc/texture_mailbox_struct_traits.h b/cc/ipc/texture_mailbox_struct_traits.h
new file mode 100644
index 0000000..3a72328
--- /dev/null
+++ b/cc/ipc/texture_mailbox_struct_traits.h
@@ -0,0 +1,74 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_IPC_TEXTURE_MAILBOX_STRUCT_TRAITS_H_
+#define CC_IPC_TEXTURE_MAILBOX_STRUCT_TRAITS_H_
+
+#include "cc/ipc/texture_mailbox.mojom-shared.h"
+#include "cc/resources/texture_mailbox.h"
+
+namespace mojo {
+
+template <>
+struct StructTraits<cc::mojom::TextureMailboxDataView, cc::TextureMailbox> {
+  static const gpu::MailboxHolder& mailbox_holder(
+      const cc::TextureMailbox& input) {
+    return input.mailbox_holder_;
+  }
+
+  static const gfx::Size& size_in_pixels(const cc::TextureMailbox& input) {
+    return input.size_in_pixels_;
+  }
+
+  static bool is_overlay_candidate(const cc::TextureMailbox& input) {
+    return input.is_overlay_candidate_;
+  }
+
+  static bool is_backed_by_surface_texture(const cc::TextureMailbox& input) {
+#if defined(OS_ANDROID)
+    return input.is_backed_by_surface_texture_;
+#else
+    return false;
+#endif
+  }
+
+  static bool wants_promotion_hint(const cc::TextureMailbox& input) {
+#if defined(OS_ANDROID)
+    return input.wants_promotion_hint_;
+#else
+    return false;
+#endif
+  }
+
+  static bool secure_output_only(const cc::TextureMailbox& input) {
+    return input.secure_output_only_;
+  }
+
+  static bool nearest_neighbor(const cc::TextureMailbox& input) {
+    return input.nearest_neighbor_;
+  }
+
+  static const gfx::ColorSpace& color_space(const cc::TextureMailbox& input) {
+    return input.color_space_;
+  }
+
+  static bool Read(cc::mojom::TextureMailboxDataView data,
+                   cc::TextureMailbox* out) {
+#if defined(OS_ANDROID)
+    out->is_backed_by_surface_texture_ = data.is_backed_by_surface_texture();
+    out->wants_promotion_hint_ = data.wants_promotion_hint();
+#endif
+    out->is_overlay_candidate_ = data.is_overlay_candidate();
+    out->secure_output_only_ = data.secure_output_only();
+    out->nearest_neighbor_ = data.nearest_neighbor();
+
+    return data.ReadMailboxHolder(&out->mailbox_holder_) &&
+           data.ReadSizeInPixels(&out->size_in_pixels_) &&
+           data.ReadColorSpace(&out->color_space_);
+  }
+};
+
+}  // namespace mojo
+
+#endif  // CC_IPC_TEXTURE_MAILBOX_STRUCT_TRAITS_H_
diff --git a/cc/ipc/traits_test_service.mojom b/cc/ipc/traits_test_service.mojom
index 8891949..b77c187c 100644
--- a/cc/ipc/traits_test_service.mojom
+++ b/cc/ipc/traits_test_service.mojom
@@ -17,6 +17,7 @@
 import "cc/ipc/surface_id.mojom";
 import "cc/ipc/surface_reference.mojom";
 import "cc/ipc/surface_sequence.mojom";
+import "cc/ipc/texture_mailbox.mojom";
 import "cc/ipc/transferable_resource.mojom";
 
 // All functions on this interface echo their arguments to test StructTraits
@@ -60,6 +61,10 @@
   EchoSurfaceSequence(SurfaceSequence s) => (SurfaceSequence pass);
 
   [Sync]
+  EchoTextureMailbox(TextureMailbox t) =>
+      (TextureMailbox pass);
+
+  [Sync]
   EchoTransferableResource(TransferableResource t) =>
       (TransferableResource pass);
 };
diff --git a/cc/ipc/typemaps.gni b/cc/ipc/typemaps.gni
index 2243fed1..7c3dda2 100644
--- a/cc/ipc/typemaps.gni
+++ b/cc/ipc/typemaps.gni
@@ -18,5 +18,6 @@
   "//cc/ipc/surface_info.typemap",
   "//cc/ipc/surface_reference.typemap",
   "//cc/ipc/surface_sequence.typemap",
+  "//cc/ipc/texture_mailbox.typemap",
   "//cc/ipc/transferable_resource.typemap",
 ]
diff --git a/cc/layers/heads_up_display_unittest.cc b/cc/layers/heads_up_display_unittest.cc
index 8babb183..1801021 100644
--- a/cc/layers/heads_up_display_unittest.cc
+++ b/cc/layers/heads_up_display_unittest.cc
@@ -47,40 +47,40 @@
   void DidCommit() override {
     ++num_commits_;
 
-    ASSERT_TRUE(layer_tree()->hud_layer());
+    ASSERT_TRUE(layer_tree_host()->hud_layer());
 
     switch (num_commits_) {
       case 1:
         // Change directly to a new root layer.
-        layer_tree()->SetRootLayer(root_layer1_);
+        layer_tree_host()->SetRootLayer(root_layer1_);
         break;
       case 2:
-        EXPECT_EQ(root_layer1_.get(), layer_tree()->hud_layer()->parent());
+        EXPECT_EQ(root_layer1_.get(), layer_tree_host()->hud_layer()->parent());
         // Unset the root layer.
-        layer_tree()->SetRootLayer(nullptr);
+        layer_tree_host()->SetRootLayer(nullptr);
         break;
       case 3:
-        EXPECT_EQ(0, layer_tree()->hud_layer()->parent());
+        EXPECT_EQ(0, layer_tree_host()->hud_layer()->parent());
         // Change back to the previous root layer.
-        layer_tree()->SetRootLayer(root_layer1_);
+        layer_tree_host()->SetRootLayer(root_layer1_);
         break;
       case 4:
-        EXPECT_EQ(root_layer1_.get(), layer_tree()->hud_layer()->parent());
+        EXPECT_EQ(root_layer1_.get(), layer_tree_host()->hud_layer()->parent());
         // Unset the root layer.
-        layer_tree()->SetRootLayer(nullptr);
+        layer_tree_host()->SetRootLayer(nullptr);
         break;
       case 5:
-        EXPECT_EQ(0, layer_tree()->hud_layer()->parent());
+        EXPECT_EQ(0, layer_tree_host()->hud_layer()->parent());
         // Change to a new root layer from a null root.
-        layer_tree()->SetRootLayer(root_layer2_);
+        layer_tree_host()->SetRootLayer(root_layer2_);
         break;
       case 6:
-        EXPECT_EQ(root_layer2_.get(), layer_tree()->hud_layer()->parent());
+        EXPECT_EQ(root_layer2_.get(), layer_tree_host()->hud_layer()->parent());
         // Change directly back to the last root layer/
-        layer_tree()->SetRootLayer(root_layer1_);
+        layer_tree_host()->SetRootLayer(root_layer1_);
         break;
       case 7:
-        EXPECT_EQ(root_layer1_.get(), layer_tree()->hud_layer()->parent());
+        EXPECT_EQ(root_layer1_.get(), layer_tree_host()->hud_layer()->parent());
         EndTest();
         break;
     }
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index e878a20..f8f5a19 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -76,7 +76,6 @@
     : ignore_set_needs_commit_(false),
       parent_(nullptr),
       layer_tree_host_(nullptr),
-      layer_tree_(nullptr),
       // Layer IDs start from 1.
       inputs_(g_next_layer_id.GetNext() + 1),
       num_descendants_that_draw_content_(0),
@@ -120,25 +119,23 @@
     return;
 
   if (layer_tree_host_) {
-    layer_tree_->property_trees()->RemoveIdFromIdToIndexMaps(id());
-    layer_tree_->property_trees()->needs_rebuild = true;
-    layer_tree_->UnregisterLayer(this);
+    layer_tree_host_->property_trees()->RemoveIdFromIdToIndexMaps(id());
+    layer_tree_host_->property_trees()->needs_rebuild = true;
+    layer_tree_host_->UnregisterLayer(this);
     if (inputs_.element_id) {
-      layer_tree_->UnregisterElement(inputs_.element_id,
-                                     ElementListType::ACTIVE, this);
+      layer_tree_host_->UnregisterElement(inputs_.element_id,
+                                          ElementListType::ACTIVE, this);
     }
   }
   if (host) {
-    host->GetLayerTree()->property_trees()->needs_rebuild = true;
-    host->GetLayerTree()->RegisterLayer(this);
+    host->property_trees()->needs_rebuild = true;
+    host->RegisterLayer(this);
     if (inputs_.element_id) {
-      host->GetLayerTree()->RegisterElement(inputs_.element_id,
-                                            ElementListType::ACTIVE, this);
+      host->RegisterElement(inputs_.element_id, ElementListType::ACTIVE, this);
     }
   }
 
   layer_tree_host_ = host;
-  layer_tree_ = host ? host->GetLayerTree() : nullptr;
   InvalidatePropertyTreesIndices();
 
   // When changing hosts, the layer needs to commit its properties to the impl
@@ -169,7 +166,7 @@
     return;
 
   SetNeedsPushProperties();
-  layer_tree_->property_trees()->needs_rebuild = true;
+  layer_tree_host_->property_trees()->needs_rebuild = true;
 
   if (ignore_set_needs_commit_)
     return;
@@ -190,10 +187,10 @@
 }
 
 void Layer::SetNeedsFullTreeSync() {
-  if (!layer_tree_)
+  if (!layer_tree_host_)
     return;
 
-  layer_tree_->SetNeedsFullTreeSync();
+  layer_tree_host_->SetNeedsFullTreeSync();
 }
 
 void Layer::SetNextCommitWaitsForActivation() {
@@ -204,20 +201,20 @@
 }
 
 void Layer::SetNeedsPushProperties() {
-  if (layer_tree_)
-    layer_tree_->AddLayerShouldPushProperties(this);
+  if (layer_tree_host_)
+    layer_tree_host_->AddLayerShouldPushProperties(this);
 }
 
 void Layer::ResetNeedsPushPropertiesForTesting() {
-  if (layer_tree_)
-    layer_tree_->RemoveLayerShouldPushProperties(this);
+  if (layer_tree_host_)
+    layer_tree_host_->RemoveLayerShouldPushProperties(this);
 }
 
 bool Layer::IsPropertyChangeAllowed() const {
-  if (!layer_tree_)
+  if (!layer_tree_host_)
     return true;
 
-  return !layer_tree_->in_paint_layer_contents();
+  return !layer_tree_host_->in_paint_layer_contents();
 }
 
 sk_sp<SkPicture> Layer::GetPicture() const {
@@ -233,7 +230,7 @@
   if (!layer_tree_host_)
     return;
 
-  layer_tree_->property_trees()->needs_rebuild = true;
+  layer_tree_host_->property_trees()->needs_rebuild = true;
 }
 
 void Layer::AddChild(scoped_refptr<Layer> child) {
@@ -467,7 +464,7 @@
   inputs_.opacity = opacity;
   SetSubtreePropertyChanged();
   if (layer_tree_host_ && !force_rebuild) {
-    PropertyTrees* property_trees = layer_tree_->property_trees();
+    PropertyTrees* property_trees = layer_tree_host_->property_trees();
     auto effect_id_to_index =
         property_trees->layer_id_to_effect_node_index.find(id());
     if (effect_id_to_index !=
@@ -573,7 +570,7 @@
     return;
 
   SetSubtreePropertyChanged();
-  PropertyTrees* property_trees = layer_tree_->property_trees();
+  PropertyTrees* property_trees = layer_tree_host_->property_trees();
   if (property_trees->IsInIdToIndexMap(PropertyTrees::TreeType::TRANSFORM,
                                        id())) {
     DCHECK_EQ(transform_tree_index(),
@@ -592,7 +589,7 @@
     }
     transform_node->needs_local_transform_update = true;
     transform_node->transform_changed = true;
-    layer_tree_->property_trees()->transform_tree.set_needs_update(true);
+    layer_tree_host_->property_trees()->transform_tree.set_needs_update(true);
     SetNeedsCommitNoRebuild();
     return;
   }
@@ -630,7 +627,7 @@
 
   SetSubtreePropertyChanged();
   if (layer_tree_host_) {
-    PropertyTrees* property_trees = layer_tree_->property_trees();
+    PropertyTrees* property_trees = layer_tree_host_->property_trees();
     if (property_trees->IsInIdToIndexMap(PropertyTrees::TreeType::TRANSFORM,
                                          id())) {
       // We need to trigger a rebuild if we could have affected 2d axis
@@ -646,7 +643,7 @@
       transform_node->local = transform;
       transform_node->needs_local_transform_update = true;
       transform_node->transform_changed = true;
-      layer_tree_->property_trees()->transform_tree.set_needs_update(true);
+      layer_tree_host_->property_trees()->transform_tree.set_needs_update(true);
       if (preserves_2d_axis_alignment)
         SetNeedsCommitNoRebuild();
       else
@@ -671,7 +668,7 @@
     return;
 
   SetSubtreePropertyChanged();
-  PropertyTrees* property_trees = layer_tree_->property_trees();
+  PropertyTrees* property_trees = layer_tree_host_->property_trees();
   if (property_trees->IsInIdToIndexMap(PropertyTrees::TreeType::TRANSFORM,
                                        id())) {
     DCHECK_EQ(transform_tree_index(),
@@ -682,7 +679,7 @@
     transform_node->update_post_local_transform(position(), transform_origin);
     transform_node->needs_local_transform_update = true;
     transform_node->transform_changed = true;
-    layer_tree_->property_trees()->transform_tree.set_needs_update(true);
+    layer_tree_host_->property_trees()->transform_tree.set_needs_update(true);
     SetNeedsCommitNoRebuild();
     return;
   }
@@ -743,8 +740,8 @@
     inputs_.clip_parent->AddClipChild(this);
 
   SetNeedsCommit();
-  if (layer_tree_)
-    layer_tree_->SetNeedsMetaInfoRecomputation(true);
+  if (layer_tree_host_)
+    layer_tree_host_->SetNeedsMetaInfoRecomputation(true);
 }
 
 void Layer::AddClipChild(Layer* child) {
@@ -771,7 +768,7 @@
   if (!layer_tree_host_)
     return;
 
-  PropertyTrees* property_trees = layer_tree_->property_trees();
+  PropertyTrees* property_trees = layer_tree_host_->property_trees();
   if (scroll_tree_index() != ScrollTree::kInvalidNodeId && scrollable())
     property_trees->scroll_tree.SetScrollOffset(id(), scroll_offset);
 
@@ -804,7 +801,7 @@
 
   bool needs_rebuild = true;
 
-  PropertyTrees* property_trees = layer_tree_->property_trees();
+  PropertyTrees* property_trees = layer_tree_host_->property_trees();
   if (scroll_tree_index() != ScrollTree::kInvalidNodeId && scrollable())
     property_trees->scroll_tree.SetScrollOffset(id(), scroll_offset);
 
@@ -838,8 +835,8 @@
 }
 
 Layer* Layer::scroll_clip_layer() const {
-  DCHECK(layer_tree_);
-  return layer_tree_->LayerById(inputs_.scroll_clip_layer_id);
+  DCHECK(layer_tree_host_);
+  return layer_tree_host_->LayerById(inputs_.scroll_clip_layer_id);
 }
 
 void Layer::SetUserScrollable(bool horizontal, bool vertical) {
@@ -931,7 +928,7 @@
 
 int Layer::transform_tree_index() const {
   if (!layer_tree_host_ ||
-      layer_tree_->property_trees()->sequence_number !=
+      layer_tree_host_->property_trees()->sequence_number !=
           property_tree_sequence_number_) {
     return TransformTree::kInvalidNodeId;
   }
@@ -948,7 +945,7 @@
 
 int Layer::clip_tree_index() const {
   if (!layer_tree_host_ ||
-      layer_tree_->property_trees()->sequence_number !=
+      layer_tree_host_->property_trees()->sequence_number !=
           property_tree_sequence_number_) {
     return ClipTree::kInvalidNodeId;
   }
@@ -965,7 +962,7 @@
 
 int Layer::effect_tree_index() const {
   if (!layer_tree_host_ ||
-      layer_tree_->property_trees()->sequence_number !=
+      layer_tree_host_->property_trees()->sequence_number !=
           property_tree_sequence_number_) {
     return EffectTree::kInvalidNodeId;
   }
@@ -982,7 +979,7 @@
 
 int Layer::scroll_tree_index() const {
   if (!layer_tree_host_ ||
-      layer_tree_->property_trees()->sequence_number !=
+      layer_tree_host_->property_trees()->sequence_number !=
           property_tree_sequence_number_) {
     return ScrollTree::kInvalidNodeId;
   }
@@ -1197,7 +1194,7 @@
   subtree_property_changed_ = false;
   inputs_.update_rect = gfx::Rect();
 
-  layer_tree_->RemoveLayerShouldPushProperties(this);
+  layer_tree_host_->RemoveLayerShouldPushProperties(this);
 }
 
 void Layer::TakeCopyRequests(
@@ -1337,7 +1334,7 @@
   // recording may be needed.
   SetNeedsUpdate();
   if (layer_tree_host_) {
-    PropertyTrees* property_trees = layer_tree_->property_trees();
+    PropertyTrees* property_trees = layer_tree_host_->property_trees();
     if (property_trees->IsInIdToIndexMap(PropertyTrees::TreeType::EFFECT,
                                          id())) {
       DCHECK_EQ(effect_tree_index(),
@@ -1357,7 +1354,7 @@
   // recording may be needed.
   SetNeedsUpdate();
   if (layer_tree_host_) {
-    PropertyTrees* property_trees = layer_tree_->property_trees();
+    PropertyTrees* property_trees = layer_tree_host_->property_trees();
     if (property_trees->IsInIdToIndexMap(PropertyTrees::TreeType::TRANSFORM,
                                          id())) {
       DCHECK_EQ(transform_tree_index(),
@@ -1381,7 +1378,7 @@
 void Layer::OnIsAnimatingChanged(const PropertyAnimationState& mask,
                                  const PropertyAnimationState& state) {
   DCHECK(layer_tree_host_);
-  PropertyTrees* property_trees = layer_tree_->property_trees();
+  PropertyTrees* property_trees = layer_tree_host_->property_trees();
 
   TransformNode* transform_node = nullptr;
   if (property_trees->IsInIdToIndexMap(PropertyTrees::TreeType::TRANSFORM,
@@ -1481,7 +1478,7 @@
 }
 
 MutatorHost* Layer::GetMutatorHost() const {
-  return layer_tree_ ? layer_tree_->mutator_host() : nullptr;
+  return layer_tree_host_ ? layer_tree_host_->mutator_host() : nullptr;
 }
 
 ElementListType Layer::GetElementTypeForAnimation() const {
@@ -1536,15 +1533,15 @@
   TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("compositor-worker"),
                "Layer::SetElementId", "element", id.AsValue().release());
   if (inputs_.element_id && layer_tree_host()) {
-    layer_tree_->UnregisterElement(inputs_.element_id, ElementListType::ACTIVE,
-                                   this);
+    layer_tree_host_->UnregisterElement(inputs_.element_id,
+                                        ElementListType::ACTIVE, this);
   }
 
   inputs_.element_id = id;
 
   if (inputs_.element_id && layer_tree_host()) {
-    layer_tree_->RegisterElement(inputs_.element_id, ElementListType::ACTIVE,
-                                 this);
+    layer_tree_host_->RegisterElement(inputs_.element_id,
+                                      ElementListType::ACTIVE, this);
   }
 
   SetNeedsCommit();
@@ -1569,7 +1566,7 @@
 }
 
 int Layer::num_copy_requests_in_target_subtree() {
-  return layer_tree_->property_trees()
+  return layer_tree_host_->property_trees()
       ->effect_tree.Node(effect_tree_index())
       ->num_copy_requests_in_subtree;
 }
@@ -1577,11 +1574,7 @@
 gfx::Transform Layer::screen_space_transform() const {
   DCHECK_NE(transform_tree_index_, TransformTree::kInvalidNodeId);
   return draw_property_utils::ScreenSpaceTransform(
-      this, layer_tree_->property_trees()->transform_tree);
-}
-
-LayerTree* Layer::GetLayerTree() const {
-  return layer_tree_;
+      this, layer_tree_host_->property_trees()->transform_tree);
 }
 
 }  // namespace cc
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index c373ec27..9986087 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -26,7 +26,6 @@
 #include "cc/layers/paint_properties.h"
 #include "cc/output/filter_operations.h"
 #include "cc/trees/element_id.h"
-#include "cc/trees/layer_tree.h"
 #include "cc/trees/mutator_host_client.h"
 #include "cc/trees/property_tree.h"
 #include "cc/trees/target_property.h"
@@ -326,7 +325,6 @@
   virtual void PushPropertiesTo(LayerImpl* layer);
 
   LayerTreeHost* GetLayerTreeHostForTesting() const { return layer_tree_host_; }
-  LayerTree* GetLayerTree() const;
 
   virtual ScrollbarLayerInterface* ToScrollbarLayer();
 
@@ -441,14 +439,14 @@
 
   const gfx::Rect& update_rect() const { return inputs_.update_rect; }
 
+  LayerTreeHost* layer_tree_host() const { return layer_tree_host_; }
+
  protected:
   friend class LayerImpl;
   friend class TreeSynchronizer;
   virtual ~Layer();
   Layer();
 
-  LayerTreeHost* layer_tree_host() { return layer_tree_host_; }
-
   // These SetNeeds functions are in order of severity of update:
   //
   // Called when this layer has been modified in some way, but isn't sure
@@ -488,7 +486,7 @@
  private:
   friend class base::RefCounted<Layer>;
   friend class LayerTreeHostCommon;
-  friend class LayerTree;
+  friend class LayerTreeHost;
   friend class LayerInternalsForTest;
 
   // Interactions with attached animations.
@@ -628,7 +626,6 @@
   // This pointer value is nil when a Layer is not in a tree and is
   // updated via SetLayerTreeHost() if a layer moves between trees.
   LayerTreeHost* layer_tree_host_;
-  LayerTree* layer_tree_;
 
   Inputs inputs_;
 
diff --git a/cc/layers/layer_list_iterator_unittest.cc b/cc/layers/layer_list_iterator_unittest.cc
index 38cedf5c..54e1006e 100644
--- a/cc/layers/layer_list_iterator_unittest.cc
+++ b/cc/layers/layer_list_iterator_unittest.cc
@@ -68,7 +68,7 @@
   host->SetRootLayer(std::move(layer1));
 
   int i = 1;
-  for (auto* layer : *host->GetLayerTree()) {
+  for (auto* layer : *host) {
     EXPECT_EQ(i++, layer_id_to_order[layer->id()]);
   }
   EXPECT_EQ(8, i);
@@ -90,7 +90,7 @@
   host->SetRootLayer(std::move(layer1));
 
   int i = 1;
-  for (auto* layer : *host->GetLayerTree()) {
+  for (auto* layer : *host) {
     EXPECT_EQ(i++, layer_id_to_order[layer->id()]);
   }
   EXPECT_EQ(2, i);
@@ -156,7 +156,7 @@
 
   int i = 7;
 
-  for (auto* layer : base::Reversed(*host->GetLayerTree())) {
+  for (auto* layer : base::Reversed(*host)) {
     EXPECT_EQ(i--, layer_id_to_order[layer->id()]);
   }
 
@@ -179,7 +179,7 @@
   host->SetRootLayer(std::move(layer1));
 
   int i = 1;
-  for (auto* layer : base::Reversed(*host->GetLayerTree())) {
+  for (auto* layer : base::Reversed(*host)) {
     EXPECT_EQ(i--, layer_id_to_order[layer->id()]);
   }
   EXPECT_EQ(0, i);
diff --git a/cc/layers/layer_position_constraint_unittest.cc b/cc/layers/layer_position_constraint_unittest.cc
index fb0b805..4451b0a 100644
--- a/cc/layers/layer_position_constraint_unittest.cc
+++ b/cc/layers/layer_position_constraint_unittest.cc
@@ -134,17 +134,17 @@
     root_->AddChild(inner_viewport_container_layer_);
 
     layer_tree_host_->SetRootLayer(root_);
-    layer_tree_host_->GetLayerTree()->RegisterViewportLayers(
-        nullptr, root_, scroll_layer_, child_);
+    layer_tree_host_->RegisterViewportLayers(nullptr, root_, scroll_layer_,
+                                             child_);
   }
 
   void CommitAndUpdateImplPointers() {
     LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
         root_.get(), root_->bounds());
     inputs.inner_viewport_scroll_layer =
-        layer_tree_host_->GetLayerTree()->inner_viewport_scroll_layer();
+        layer_tree_host_->inner_viewport_scroll_layer();
     inputs.outer_viewport_scroll_layer =
-        layer_tree_host_->GetLayerTree()->outer_viewport_scroll_layer();
+        layer_tree_host_->outer_viewport_scroll_layer();
     LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
     // Since scroll deltas aren't sent back to the main thread in this test
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc
index 28689cbd..55057aed 100644
--- a/cc/layers/layer_unittest.cc
+++ b/cc/layers/layer_unittest.cc
@@ -47,67 +47,56 @@
 using ::testing::StrictMock;
 using ::testing::_;
 
-#define EXPECT_SET_NEEDS_FULL_TREE_SYNC(expect, code_to_test)          \
-  do {                                                                 \
-    EXPECT_CALL(*layer_tree_, SetNeedsFullTreeSync()).Times((expect)); \
-    code_to_test;                                                      \
-    Mock::VerifyAndClearExpectations(layer_tree_);                     \
+#define EXPECT_SET_NEEDS_FULL_TREE_SYNC(expect, code_to_test)               \
+  do {                                                                      \
+    EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times((expect)); \
+    code_to_test;                                                           \
+    Mock::VerifyAndClearExpectations(layer_tree_host_.get());               \
   } while (false)
 
-#define EXECUTE_AND_VERIFY_SUBTREE_CHANGED(code_to_test)                       \
-  code_to_test;                                                                \
-  root->GetLayerTree()->BuildPropertyTreesForTesting();                        \
-  EXPECT_TRUE(root->subtree_property_changed());                               \
-  EXPECT_TRUE(                                                                 \
-      root->GetLayerTree()->LayerNeedsPushPropertiesForTesting(root.get()));   \
-  EXPECT_TRUE(child->subtree_property_changed());                              \
-  EXPECT_TRUE(                                                                 \
-      child->GetLayerTree()->LayerNeedsPushPropertiesForTesting(child.get())); \
-  EXPECT_TRUE(grand_child->subtree_property_changed());                        \
-  EXPECT_TRUE(grand_child->GetLayerTree()->LayerNeedsPushPropertiesForTesting( \
-      grand_child.get()));
+#define EXECUTE_AND_VERIFY_SUBTREE_CHANGED(code_to_test)                    \
+  code_to_test;                                                             \
+  root->layer_tree_host()->BuildPropertyTreesForTesting();                  \
+  EXPECT_TRUE(root->subtree_property_changed());                            \
+  EXPECT_TRUE(root->layer_tree_host()->LayerNeedsPushPropertiesForTesting(  \
+      root.get()));                                                         \
+  EXPECT_TRUE(child->subtree_property_changed());                           \
+  EXPECT_TRUE(child->layer_tree_host()->LayerNeedsPushPropertiesForTesting( \
+      child.get()));                                                        \
+  EXPECT_TRUE(grand_child->subtree_property_changed());                     \
+  EXPECT_TRUE(                                                              \
+      grand_child->layer_tree_host()->LayerNeedsPushPropertiesForTesting(   \
+          grand_child.get()));
 
-#define EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(code_to_test)                 \
-  code_to_test;                                                                \
-  EXPECT_FALSE(root->subtree_property_changed());                              \
-  EXPECT_FALSE(                                                                \
-      root->GetLayerTree()->LayerNeedsPushPropertiesForTesting(root.get()));   \
-  EXPECT_FALSE(child->subtree_property_changed());                             \
-  EXPECT_FALSE(                                                                \
-      child->GetLayerTree()->LayerNeedsPushPropertiesForTesting(child.get())); \
-  EXPECT_FALSE(grand_child->subtree_property_changed());                       \
-  EXPECT_FALSE(                                                                \
-      grand_child->GetLayerTree()->LayerNeedsPushPropertiesForTesting(         \
+#define EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(code_to_test)               \
+  code_to_test;                                                              \
+  EXPECT_FALSE(root->subtree_property_changed());                            \
+  EXPECT_FALSE(root->layer_tree_host()->LayerNeedsPushPropertiesForTesting(  \
+      root.get()));                                                          \
+  EXPECT_FALSE(child->subtree_property_changed());                           \
+  EXPECT_FALSE(child->layer_tree_host()->LayerNeedsPushPropertiesForTesting( \
+      child.get()));                                                         \
+  EXPECT_FALSE(grand_child->subtree_property_changed());                     \
+  EXPECT_FALSE(                                                              \
+      grand_child->layer_tree_host()->LayerNeedsPushPropertiesForTesting(    \
           grand_child.get()));
 
 namespace cc {
 
 namespace {
 
-class MockLayerTree : public LayerTree {
- public:
-  MockLayerTree(LayerTreeHost::InitParams* params,
-                LayerTreeHost* layer_tree_host)
-      : LayerTree(params->mutator_host, layer_tree_host) {}
-  ~MockLayerTree() override {}
-
-  MOCK_METHOD0(SetNeedsFullTreeSync, void());
-};
-
 class MockLayerTreeHost : public LayerTreeHost {
  public:
   MockLayerTreeHost(LayerTreeHostSingleThreadClient* single_thread_client,
                     LayerTreeHost::InitParams* params)
-      : LayerTreeHost(
-            params,
-            CompositorMode::SINGLE_THREADED,
-            base::MakeUnique<StrictMock<MockLayerTree>>(params, this)) {
+      : LayerTreeHost(params, CompositorMode::SINGLE_THREADED) {
     InitializeSingleThreaded(single_thread_client,
                              base::ThreadTaskRunnerHandle::Get());
   }
 
   MOCK_METHOD0(SetNeedsCommit, void());
   MOCK_METHOD0(SetNeedsUpdateLayers, void());
+  MOCK_METHOD0(SetNeedsFullTreeSync, void());
 };
 
 class LayerTest : public testing::Test {
@@ -137,14 +126,11 @@
 
     layer_tree_host_.reset(
         new StrictMock<MockLayerTreeHost>(&single_thread_client_, &params));
-    layer_tree_ = static_cast<StrictMock<MockLayerTree>*>(
-        layer_tree_host_->GetLayerTree());
   }
 
   void TearDown() override {
     Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-    Mock::VerifyAndClearExpectations(layer_tree_);
-    EXPECT_CALL(*layer_tree_, SetNeedsFullTreeSync()).Times(AnyNumber());
+    EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AnyNumber());
     parent_ = nullptr;
     child1_ = nullptr;
     child2_ = nullptr;
@@ -153,11 +139,10 @@
     grand_child2_ = nullptr;
     grand_child3_ = nullptr;
 
-    layer_tree_->SetRootLayer(nullptr);
+    layer_tree_host_->SetRootLayer(nullptr);
     animation_host_->SetMutatorHostClient(nullptr);
     layer_tree_host_ = nullptr;
     animation_host_ = nullptr;
-    layer_tree_ = nullptr;
   }
 
   void VerifyTestTreeInitialState() const {
@@ -191,8 +176,8 @@
     grand_child2_ = Layer::Create();
     grand_child3_ = Layer::Create();
 
-    EXPECT_CALL(*layer_tree_, SetNeedsFullTreeSync()).Times(AnyNumber());
-    layer_tree_->SetRootLayer(parent_);
+    EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AnyNumber());
+    layer_tree_host_->SetRootLayer(parent_);
 
     parent_->AddChild(child1_);
     parent_->AddChild(child2_);
@@ -201,7 +186,7 @@
     child1_->AddChild(grand_child2_);
     child2_->AddChild(grand_child3_);
 
-    Mock::VerifyAndClearExpectations(layer_tree_);
+    Mock::VerifyAndClearExpectations(layer_tree_host_.get());
 
     VerifyTestTreeInitialState();
   }
@@ -214,7 +199,6 @@
   FakeLayerTreeHostClient fake_client_;
   std::unique_ptr<StrictMock<MockLayerTreeHost>> layer_tree_host_;
   std::unique_ptr<AnimationHost> animation_host_;
-  StrictMock<MockLayerTree>* layer_tree_;
   scoped_refptr<Layer> parent_;
   scoped_refptr<Layer> child1_;
   scoped_refptr<Layer> child2_;
@@ -241,14 +225,14 @@
 }
 
 TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
-  EXPECT_CALL(*layer_tree_, SetNeedsFullTreeSync()).Times(AtLeast(1));
+  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1));
   scoped_refptr<Layer> root = Layer::Create();
   scoped_refptr<Layer> child = Layer::Create();
   scoped_refptr<Layer> child2 = Layer::Create();
   scoped_refptr<Layer> grand_child = Layer::Create();
   scoped_refptr<Layer> dummy_layer1 = Layer::Create();
 
-  layer_tree_->SetRootLayer(root);
+  layer_tree_host_->SetRootLayer(root);
   root->AddChild(child);
   root->AddChild(child2);
   child->AddChild(grand_child);
@@ -268,7 +252,7 @@
   std::unique_ptr<LayerImpl> dummy_layer1_impl =
       LayerImpl::Create(host_impl_.active_tree(), dummy_layer1->id());
 
-  EXPECT_CALL(*layer_tree_, SetNeedsFullTreeSync()).Times(1);
+  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(1);
   EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetMaskLayer(dummy_layer1.get()));
   EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
       root->PushPropertiesTo(root_impl.get());
@@ -366,7 +350,7 @@
   gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
   EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
   root->SetPosition(arbitrary_point_f);
-  TransformNode* node = layer_tree_->property_trees()->transform_tree.Node(
+  TransformNode* node = layer_tree_host_->property_trees()->transform_tree.Node(
       root->transform_tree_index());
   EXPECT_TRUE(node->transform_changed);
   EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
@@ -374,33 +358,33 @@
       child->PushPropertiesTo(child_impl.get());
       child2->PushPropertiesTo(child2_impl.get());
       grand_child->PushPropertiesTo(grand_child_impl.get());
-      layer_tree_->property_trees()->ResetAllChangeTracking());
+      layer_tree_host_->property_trees()->ResetAllChangeTracking());
   EXPECT_FALSE(node->transform_changed);
 
   EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
   child->SetPosition(arbitrary_point_f);
-  node = layer_tree_->property_trees()->transform_tree.Node(
+  node = layer_tree_host_->property_trees()->transform_tree.Node(
       child->transform_tree_index());
   EXPECT_TRUE(node->transform_changed);
   // child2 is not in the subtree of child, but its scroll parent is. So, its
   // to_screen will be effected by change in position of child2.
-  layer_tree_->property_trees()->transform_tree.UpdateTransforms(
+  layer_tree_host_->property_trees()->transform_tree.UpdateTransforms(
       child2->transform_tree_index());
-  node = layer_tree_->property_trees()->transform_tree.Node(
+  node = layer_tree_host_->property_trees()->transform_tree.Node(
       child2->transform_tree_index());
   EXPECT_TRUE(node->transform_changed);
   EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
       child->PushPropertiesTo(child_impl.get());
       grand_child->PushPropertiesTo(grand_child_impl.get());
-      layer_tree_->property_trees()->ResetAllChangeTracking());
-  node = layer_tree_->property_trees()->transform_tree.Node(
+      layer_tree_host_->property_trees()->ResetAllChangeTracking());
+  node = layer_tree_host_->property_trees()->transform_tree.Node(
       child->transform_tree_index());
   EXPECT_FALSE(node->transform_changed);
 
   gfx::Point3F arbitrary_point_3f = gfx::Point3F(0.125f, 0.25f, 0.f);
   EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
   root->SetTransformOrigin(arbitrary_point_3f);
-  node = layer_tree_->property_trees()->transform_tree.Node(
+  node = layer_tree_host_->property_trees()->transform_tree.Node(
       root->transform_tree_index());
   EXPECT_TRUE(node->transform_changed);
   EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
@@ -408,13 +392,13 @@
       child->PushPropertiesTo(child_impl.get());
       child2->PushPropertiesTo(child2_impl.get());
       grand_child->PushPropertiesTo(grand_child_impl.get());
-      layer_tree_->property_trees()->ResetAllChangeTracking());
+      layer_tree_host_->property_trees()->ResetAllChangeTracking());
 
   gfx::Transform arbitrary_transform;
   arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f);
   EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
   root->SetTransform(arbitrary_transform);
-  node = layer_tree_->property_trees()->transform_tree.Node(
+  node = layer_tree_host_->property_trees()->transform_tree.Node(
       root->transform_tree_index());
   EXPECT_TRUE(node->transform_changed);
 }
@@ -427,7 +411,7 @@
   ASSERT_EQ(0U, parent->children().size());
   EXPECT_FALSE(child->parent());
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(parent));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));
   EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->AddChild(child));
 
   ASSERT_EQ(1U, parent->children().size());
@@ -439,12 +423,12 @@
 }
 
 TEST_F(LayerTest, AddSameChildTwice) {
-  EXPECT_CALL(*layer_tree_, SetNeedsFullTreeSync()).Times(AtLeast(1));
+  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1));
 
   scoped_refptr<Layer> parent = Layer::Create();
   scoped_refptr<Layer> child = Layer::Create();
 
-  layer_tree_->SetRootLayer(parent);
+  layer_tree_host_->SetRootLayer(parent);
 
   ASSERT_EQ(0u, parent->children().size());
 
@@ -464,7 +448,7 @@
   scoped_refptr<Layer> child3 = Layer::Create();
   scoped_refptr<Layer> child4 = Layer::Create();
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(parent));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));
 
   ASSERT_EQ(0U, parent->children().size());
 
@@ -499,7 +483,7 @@
   EXPECT_EQ(child4, parent->children()[3]);
   EXPECT_EQ(parent.get(), child4->parent());
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(nullptr));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr));
 }
 
 TEST_F(LayerTest, InsertChildPastEndOfList) {
@@ -528,7 +512,7 @@
   scoped_refptr<Layer> child1 = Layer::Create();
   scoped_refptr<Layer> child2 = Layer::Create();
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(parent));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));
 
   ASSERT_EQ(0U, parent->children().size());
 
@@ -548,7 +532,7 @@
   EXPECT_EQ(child2, parent->children()[0]);
   EXPECT_EQ(child1, parent->children()[1]);
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(nullptr));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr));
 }
 
 TEST_F(LayerTest, ReplaceChildWithNewChild) {
@@ -605,7 +589,7 @@
   scoped_refptr<Layer> child1 = Layer::Create();
   scoped_refptr<Layer> child2 = Layer::Create();
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(parent));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));
 
   ASSERT_EQ(0U, parent->children().size());
 
@@ -624,9 +608,10 @@
 
   EXPECT_SET_NEEDS_COMMIT(1, child2 = nullptr);
 
-  EXPECT_TRUE(layer_tree_->LayerNeedsPushPropertiesForTesting(child1.get()));
+  EXPECT_TRUE(
+      layer_tree_host_->LayerNeedsPushPropertiesForTesting(child1.get()));
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(nullptr));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr));
 }
 
 TEST_F(LayerTest, DeleteRemovedScrollChild) {
@@ -634,7 +619,7 @@
   scoped_refptr<Layer> child1 = Layer::Create();
   scoped_refptr<Layer> child2 = Layer::Create();
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(parent));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));
 
   ASSERT_EQ(0U, parent->children().size());
 
@@ -653,9 +638,10 @@
 
   EXPECT_SET_NEEDS_COMMIT(1, child1 = nullptr);
 
-  EXPECT_TRUE(layer_tree_->LayerNeedsPushPropertiesForTesting(child2.get()));
+  EXPECT_TRUE(
+      layer_tree_host_->LayerNeedsPushPropertiesForTesting(child2.get()));
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(nullptr));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr));
 }
 
 TEST_F(LayerTest, ReplaceChildWithSameChild) {
@@ -664,7 +650,7 @@
   // SetNeedsFullTreeSync / SetNeedsCommit should not be called because its the
   // same child.
   EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
-  EXPECT_CALL(*layer_tree_, SetNeedsFullTreeSync()).Times(0);
+  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(0);
   parent_->ReplaceChild(child2_.get(), child2_);
 
   VerifyTestTreeInitialState();
@@ -699,7 +685,8 @@
   EXPECT_EQ(old_parent.get(), child1->parent());
   EXPECT_FALSE(child2->parent());
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(new_parent));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
+                                  layer_tree_host_->SetRootLayer(new_parent));
 
   EXPECT_SET_NEEDS_FULL_TREE_SYNC(
       AtLeast(1), new_parent->SetChildren(new_children));
@@ -708,7 +695,7 @@
   EXPECT_EQ(new_parent.get(), child1->parent());
   EXPECT_EQ(new_parent.get(), child2->parent());
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(nullptr));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr));
 }
 
 TEST_F(LayerTest, HasAncestor) {
@@ -736,7 +723,7 @@
   CreateSimpleTestTree();
 
   // For this test we don't care about SetNeedsFullTreeSync calls.
-  EXPECT_CALL(*layer_tree_, SetNeedsFullTreeSync()).Times(AnyNumber());
+  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AnyNumber());
 
   scoped_refptr<Layer> child4 = Layer::Create();
 
@@ -794,7 +781,8 @@
   //      SetNeedsDisplay.
 
   scoped_refptr<Layer> test_layer = Layer::Create();
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(test_layer));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
+                                  layer_tree_host_->SetRootLayer(test_layer));
   EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true));
 
   gfx::Size test_bounds = gfx::Size(501, 508);
@@ -845,7 +833,8 @@
 
 TEST_F(LayerTest, TestSettingMainThreadScrollingReason) {
   scoped_refptr<Layer> test_layer = Layer::Create();
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(test_layer));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
+                                  layer_tree_host_->SetRootLayer(test_layer));
   EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true));
 
   // sanity check of initial test condition
@@ -897,7 +886,8 @@
 
 TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) {
   scoped_refptr<Layer> test_layer = Layer::Create();
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(test_layer));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
+                                  layer_tree_host_->SetRootLayer(test_layer));
   EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true));
 
   scoped_refptr<Layer> dummy_layer1 = Layer::Create();
@@ -946,7 +936,7 @@
   EXPECT_FALSE(test_layer->NeedsDisplayForTesting());
 
   // As layers are removed from the tree, they will cause a tree sync.
-  EXPECT_CALL(*layer_tree_, SetNeedsFullTreeSync()).Times((AnyNumber()));
+  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times((AnyNumber()));
 }
 
 TEST_F(LayerTest, PushPropertiesAccumulatesUpdateRect) {
@@ -954,7 +944,8 @@
   std::unique_ptr<LayerImpl> impl_layer =
       LayerImpl::Create(host_impl_.active_tree(), 1);
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(test_layer));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
+                                  layer_tree_host_->SetRootLayer(test_layer));
 
   host_impl_.active_tree()->SetRootLayerForTesting(std::move(impl_layer));
   host_impl_.active_tree()->BuildLayerListForTesting();
@@ -985,7 +976,8 @@
   std::unique_ptr<LayerImpl> impl_layer =
       LayerImpl::Create(host_impl_.active_tree(), 1);
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(test_layer));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
+                                  layer_tree_host_->SetRootLayer(test_layer));
 
   gfx::Transform transform;
   transform.Rotate(45.0);
@@ -1003,7 +995,8 @@
   std::unique_ptr<LayerImpl> impl_layer =
       LayerImpl::Create(host_impl_.active_tree(), 1);
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(test_layer));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
+                                  layer_tree_host_->SetRootLayer(test_layer));
 
   EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetOpacity(0.5f));
 
@@ -1084,16 +1077,15 @@
   auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<LayerTreeHost> layer_tree_host =
       factory.Create(animation_host.get());
-  LayerTree* layer_tree = layer_tree_host->GetLayerTree();
   // Setting the root layer should set the host pointer for all layers in the
   // tree.
-  layer_tree->SetRootLayer(parent.get());
+  layer_tree_host->SetRootLayer(parent.get());
 
   AssertLayerTreeHostMatchesForSubtree(parent.get(), layer_tree_host.get());
 
   // Clearing the root layer should also clear out the host pointers for all
   // layers in the tree.
-  layer_tree->SetRootLayer(nullptr);
+  layer_tree_host->SetRootLayer(nullptr);
 
   AssertLayerTreeHostMatchesForSubtree(parent.get(), nullptr);
 }
@@ -1105,9 +1097,8 @@
   auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<LayerTreeHost> layer_tree_host =
       factory.Create(animation_host.get());
-  LayerTree* layer_tree = layer_tree_host->GetLayerTree();
 
-  layer_tree->SetRootLayer(parent.get());
+  layer_tree_host->SetRootLayer(parent.get());
 
   EXPECT_EQ(parent->GetLayerTreeHostForTesting(), layer_tree_host.get());
 
@@ -1124,7 +1115,7 @@
   parent->AddChild(child);
   AssertLayerTreeHostMatchesForSubtree(parent.get(), layer_tree_host.get());
 
-  layer_tree->SetRootLayer(nullptr);
+  layer_tree_host->SetRootLayer(nullptr);
 }
 
 TEST_F(LayerLayerTreeHostTest, ChangeHost) {
@@ -1140,7 +1131,7 @@
   auto animation_host1 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<LayerTreeHost> first_layer_tree_host =
       factory.Create(animation_host1.get());
-  first_layer_tree_host->GetLayerTree()->SetRootLayer(parent.get());
+  first_layer_tree_host->SetRootLayer(parent.get());
 
   AssertLayerTreeHostMatchesForSubtree(parent.get(),
                                        first_layer_tree_host.get());
@@ -1150,12 +1141,12 @@
   auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<LayerTreeHost> second_layer_tree_host =
       factory.Create(animation_host2.get());
-  second_layer_tree_host->GetLayerTree()->SetRootLayer(parent.get());
+  second_layer_tree_host->SetRootLayer(parent.get());
 
   AssertLayerTreeHostMatchesForSubtree(parent.get(),
                                        second_layer_tree_host.get());
 
-  second_layer_tree_host->GetLayerTree()->SetRootLayer(nullptr);
+  second_layer_tree_host->SetRootLayer(nullptr);
 }
 
 TEST_F(LayerLayerTreeHostTest, ChangeHostInSubtree) {
@@ -1174,7 +1165,7 @@
   auto animation_host1 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<LayerTreeHost> first_layer_tree_host =
       factory.Create(animation_host1.get());
-  first_layer_tree_host->GetLayerTree()->SetRootLayer(first_parent.get());
+  first_layer_tree_host->SetRootLayer(first_parent.get());
 
   AssertLayerTreeHostMatchesForSubtree(first_parent.get(),
                                        first_layer_tree_host.get());
@@ -1184,7 +1175,7 @@
   auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<LayerTreeHost> second_layer_tree_host =
       factory.Create(animation_host2.get());
-  second_layer_tree_host->GetLayerTree()->SetRootLayer(second_parent.get());
+  second_layer_tree_host->SetRootLayer(second_parent.get());
 
   second_parent->AddChild(second_child);
 
@@ -1195,8 +1186,8 @@
             second_grand_child->GetLayerTreeHostForTesting());
 
   // Test over, cleanup time.
-  first_layer_tree_host->GetLayerTree()->SetRootLayer(nullptr);
-  second_layer_tree_host->GetLayerTree()->SetRootLayer(nullptr);
+  first_layer_tree_host->SetRootLayer(nullptr);
+  second_layer_tree_host->SetRootLayer(nullptr);
 }
 
 TEST_F(LayerLayerTreeHostTest, ReplaceMaskLayer) {
@@ -1212,7 +1203,7 @@
   auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<LayerTreeHost> layer_tree_host =
       factory.Create(animation_host.get());
-  layer_tree_host->GetLayerTree()->SetRootLayer(parent.get());
+  layer_tree_host->SetRootLayer(parent.get());
 
   AssertLayerTreeHostMatchesForSubtree(parent.get(), layer_tree_host.get());
 
@@ -1222,7 +1213,7 @@
   EXPECT_EQ(nullptr, mask_child->GetLayerTreeHostForTesting());
 
   // Test over, cleanup time.
-  layer_tree_host->GetLayerTree()->SetRootLayer(nullptr);
+  layer_tree_host->SetRootLayer(nullptr);
 }
 
 TEST_F(LayerLayerTreeHostTest, DestroyHostWithNonNullRootLayer) {
@@ -1233,7 +1224,7 @@
   auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<LayerTreeHost> layer_tree_host =
       factory.Create(animation_host.get());
-  layer_tree_host->GetLayerTree()->SetRootLayer(root);
+  layer_tree_host->SetRootLayer(root);
 }
 
 TEST_F(LayerTest, SafeOpaqueBackgroundColor) {
@@ -1241,10 +1232,9 @@
   auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<LayerTreeHost> layer_tree_host =
       factory.Create(animation_host.get());
-  LayerTree* layer_tree = layer_tree_host->GetLayerTree();
 
   scoped_refptr<Layer> layer = Layer::Create();
-  layer_tree->SetRootLayer(layer);
+  layer_tree_host->SetRootLayer(layer);
 
   for (int contents_opaque = 0; contents_opaque < 2; ++contents_opaque) {
     for (int layer_opaque = 0; layer_opaque < 2; ++layer_opaque) {
@@ -1252,11 +1242,11 @@
         layer->SetContentsOpaque(!!contents_opaque);
         layer->SetBackgroundColor(layer_opaque ? SK_ColorRED
                                                : SK_ColorTRANSPARENT);
-        layer_tree->set_background_color(host_opaque ? SK_ColorRED
-                                                     : SK_ColorTRANSPARENT);
+        layer_tree_host->set_background_color(
+            host_opaque ? SK_ColorRED : SK_ColorTRANSPARENT);
 
-        layer_tree->property_trees()->needs_rebuild = true;
-        layer_tree_host->GetLayerTree()->BuildPropertyTreesForTesting();
+        layer_tree_host->property_trees()->needs_rebuild = true;
+        layer_tree_host->BuildPropertyTreesForTesting();
         SkColor safe_color = layer->SafeOpaqueBackgroundColor();
         if (contents_opaque) {
           EXPECT_EQ(SkColorGetA(safe_color), 255u)
@@ -1388,7 +1378,7 @@
 
 TEST_F(LayerTest, AnimationSchedulesLayerUpdate) {
   scoped_refptr<Layer> layer = Layer::Create();
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(layer));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(layer));
 
   LayerInternalsForTest layer_internals(layer.get());
 
@@ -1414,7 +1404,8 @@
   std::unique_ptr<LayerImpl> impl_layer =
       LayerImpl::Create(host_impl_.active_tree(), 1);
 
-  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_->SetRootLayer(test_layer));
+  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
+                                  layer_tree_host_->SetRootLayer(test_layer));
 
   EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
 
diff --git a/cc/layers/painted_scrollbar_layer.cc b/cc/layers/painted_scrollbar_layer.cc
index 164a75ee..d89445b 100644
--- a/cc/layers/painted_scrollbar_layer.cc
+++ b/cc/layers/painted_scrollbar_layer.cc
@@ -170,13 +170,13 @@
 }
 
 void PaintedScrollbarLayer::UpdateInternalContentScale() {
-  float scale = GetLayerTree()->device_scale_factor();
+  float scale = layer_tree_host()->device_scale_factor();
   if (layer_tree_host()
           ->GetSettings()
           .layer_transforms_should_scale_layer_contents) {
     gfx::Transform transform;
     transform = draw_property_utils::ScreenSpaceTransform(
-        this, GetLayerTree()->property_trees()->transform_tree);
+        this, layer_tree_host()->property_trees()->transform_tree);
 
     gfx::Vector2dF transform_scales =
         MathUtil::ComputeTransform2dScaleComponents(transform, scale);
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc
index 625fca63..9a5acf5 100644
--- a/cc/layers/picture_layer.cc
+++ b/cc/layers/picture_layer.cc
@@ -60,7 +60,7 @@
   scoped_refptr<RasterSource> raster_source =
       recording_source_->CreateRasterSource(can_use_lcd_text);
   layer_impl->set_gpu_raster_max_texture_size(
-      GetLayerTree()->device_viewport_size());
+      layer_tree_host()->device_viewport_size());
   layer_impl->UpdateRasterSource(raster_source, &last_updated_invalidation_,
                                  nullptr);
   DCHECK(last_updated_invalidation_.IsEmpty());
@@ -83,7 +83,7 @@
 }
 
 void PictureLayer::SetNeedsDisplayRect(const gfx::Rect& layer_rect) {
-  DCHECK(!layer_tree_host() || !GetLayerTree()->in_paint_layer_contents());
+  DCHECK(!layer_tree_host() || !layer_tree_host()->in_paint_layer_contents());
   if (recording_source_)
     recording_source_->SetNeedsDisplayRect(layer_rect);
   Layer::SetNeedsDisplayRect(layer_rect);
diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc
index 8cbadc9..cae3445 100644
--- a/cc/layers/picture_layer_unittest.cc
+++ b/cc/layers/picture_layer_unittest.cc
@@ -42,7 +42,7 @@
   auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(
       &host_client, &task_graph_runner, animation_host.get());
-  host->GetLayerTree()->SetRootLayer(layer);
+  host->SetRootLayer(layer);
   layer->SetIsDrawable(true);
   layer->SavePaintProperties();
   layer->Update();
@@ -86,7 +86,7 @@
   auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(
       &host_client, &task_graph_runner, animation_host.get());
-  host->GetLayerTree()->SetRootLayer(layer);
+  host->SetRootLayer(layer);
   layer->SetIsDrawable(true);
   layer->SavePaintProperties();
 
@@ -130,7 +130,7 @@
   auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(
       &host_client, &task_graph_runner, animation_host.get());
-  host->GetLayerTree()->SetRootLayer(layer);
+  host->SetRootLayer(layer);
   layer->SetIsDrawable(true);
   layer->SavePaintProperties();
 
@@ -174,7 +174,7 @@
   auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(
       &host_client, &task_graph_runner, animation_host.get());
-  host->GetLayerTree()->SetRootLayer(layer);
+  host->SetRootLayer(layer);
   layer->SetIsDrawable(true);
   layer->SavePaintProperties();
   layer->Update();
@@ -256,7 +256,7 @@
   auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(
       &host_client, &task_graph_runner, animation_host.get());
-  host->GetLayerTree()->SetRootLayer(layer);
+  host->SetRootLayer(layer);
 
   // Update layers to initialize the recording source.
   gfx::Size layer_bounds(200, 200);
@@ -328,7 +328,7 @@
   host_client2.SetLayerTreeHost(host2.get());
 
   // The PictureLayer is put in one LayerTreeHost.
-  host1->GetLayerTree()->SetRootLayer(layer);
+  host1->SetRootLayer(layer);
   // Do a main frame, record the picture layers.
   EXPECT_EQ(0, layer->update_count());
   layer->SetNeedsDisplay();
@@ -343,8 +343,8 @@
   EXPECT_EQ(2, host1->SourceFrameNumber());
 
   // Then moved to another LayerTreeHost.
-  host1->GetLayerTree()->SetRootLayer(nullptr);
-  host2->GetLayerTree()->SetRootLayer(layer);
+  host1->SetRootLayer(nullptr);
+  host2->SetRootLayer(layer);
 
   // Do a main frame, record the picture layers. The frame number has changed
   // non-monotonically.
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc
index 82a29c4..2cc8c05 100644
--- a/cc/layers/scrollbar_layer_unittest.cc
+++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -131,7 +131,6 @@
         std::move(fake_ui_resource_manager));
     layer_tree_host_->InitializeSingleThreaded(
         &single_thread_client_, base::ThreadTaskRunnerHandle::Get());
-    layer_tree_ = layer_tree_host_->GetLayerTree();
     layer_tree_host_->SetVisible(true);
     fake_client_.SetLayerTreeHost(layer_tree_host_.get());
   }
@@ -171,7 +170,6 @@
   LayerTreeSettings layer_tree_settings_;
   std::unique_ptr<AnimationHost> animation_host_;
   std::unique_ptr<FakeLayerTreeHost> layer_tree_host_;
-  LayerTree* layer_tree_;
   int scrollbar_layer_id_;
 };
 
@@ -233,7 +231,7 @@
   scroll_layer->SetBounds(gfx::Size(100, 200));
   content_layer->SetBounds(gfx::Size(100, 200));
 
-  layer_tree_->SetRootLayer(layer_tree_root);
+  layer_tree_host_->SetRootLayer(layer_tree_root);
   layer_tree_root->AddChild(scroll_layer);
   scroll_layer->AddChild(content_layer);
   layer_tree_root->AddChild(scrollbar_layer);
@@ -301,7 +299,7 @@
   root_layer->SetBounds(gfx::Size(100, 50));
   content_layer->SetBounds(gfx::Size(100, 50));
 
-  layer_tree_->SetRootLayer(root_clip_layer);
+  layer_tree_host_->SetRootLayer(root_clip_layer);
   root_clip_layer->AddChild(root_layer);
   root_layer->AddChild(content_layer);
   root_layer->AddChild(scrollbar_layer);
@@ -340,7 +338,7 @@
   root_layer->SetBounds(gfx::Size(100, 50));
   content_layer->SetBounds(gfx::Size(100, 50));
 
-  layer_tree_->SetRootLayer(root_clip_layer);
+  layer_tree_host_->SetRootLayer(root_clip_layer);
   root_clip_layer->AddChild(root_layer);
   root_layer->AddChild(content_layer);
   root_layer->AddChild(scrollbar_layer);
@@ -415,7 +413,7 @@
   root_clip_layer->SetBounds(gfx::Size(50, 20));
   root_layer->SetBounds(gfx::Size(50, 100));
 
-  layer_tree_->SetRootLayer(root_clip_layer);
+  layer_tree_host_->SetRootLayer(root_clip_layer);
   root_clip_layer->AddChild(root_layer);
   root_layer->AddChild(scrollbar_layer);
 
@@ -535,7 +533,7 @@
   scroll_layer->AddChild(child1);
   scroll_layer->InsertChild(child2, 1);
   layer_tree_root->AddChild(scroll_layer);
-  layer_tree_->SetRootLayer(layer_tree_root);
+  layer_tree_host_->SetRootLayer(layer_tree_root);
 
   // Choose layer bounds to give max_scroll_offset = (8, 8).
   layer_tree_root->SetBounds(gfx::Size(2, 2));
@@ -588,7 +586,7 @@
   scroll_layer->AddChild(child1);
   scroll_layer->InsertChild(scrollbar_layer, 1);
   layer_tree_root->AddChild(scroll_layer);
-  layer_tree_->SetRootLayer(layer_tree_root);
+  layer_tree_host_->SetRootLayer(layer_tree_root);
 
   // Choose layer bounds to give max_scroll_offset = (8, 8).
   layer_tree_root->SetBounds(gfx::Size(2, 2));
@@ -597,18 +595,18 @@
   // Building property trees twice shouldn't change the size of
   // PropertyTrees::always_use_active_tree_opacity_effect_ids.
   layer_tree_host_->BuildPropertyTreesForTesting();
-  EXPECT_EQ(layer_tree_->property_trees()
+  EXPECT_EQ(layer_tree_host_->property_trees()
                 ->always_use_active_tree_opacity_effect_ids.size(),
             1u);
-  layer_tree_->property_trees()->needs_rebuild = true;
+  layer_tree_host_->property_trees()->needs_rebuild = true;
   layer_tree_host_->BuildPropertyTreesForTesting();
-  EXPECT_EQ(layer_tree_->property_trees()
+  EXPECT_EQ(layer_tree_host_->property_trees()
                 ->always_use_active_tree_opacity_effect_ids.size(),
             1u);
 
   // A solid color scrollbar layer's opacity is initialized to 0 on main thread
   layer_tree_host_->UpdateLayers();
-  EffectNode* node = layer_tree_->property_trees()->effect_tree.Node(
+  EffectNode* node = layer_tree_host_->property_trees()->effect_tree.Node(
       scrollbar_layer->effect_tree_index());
   EXPECT_EQ(node->opacity, 0.f);
 
@@ -671,7 +669,7 @@
   scroll_layer->AddChild(child1);
   scroll_layer->InsertChild(scrollbar_layer, 1);
   layer_tree_root->AddChild(scroll_layer);
-  layer_tree_->SetRootLayer(layer_tree_root);
+  layer_tree_host_->SetRootLayer(layer_tree_root);
 
   layer_tree_root->SetBounds(gfx::Size(2, 2));
   scroll_layer->SetBounds(gfx::Size(10, 10));
@@ -822,7 +820,7 @@
     layer_tree_root->AddChild(content_layer);
     layer_tree_root->AddChild(scrollbar_layer);
 
-    layer_tree_->SetRootLayer(layer_tree_root);
+    layer_tree_host_->SetRootLayer(layer_tree_root);
 
     scrollbar_layer->SetIsDrawable(true);
     scrollbar_layer->SetBounds(gfx::Size(100, 100));
@@ -881,7 +879,7 @@
   layer_tree_root->AddChild(content_layer);
   layer_tree_root->AddChild(scrollbar_layer);
 
-  layer_tree_->SetRootLayer(layer_tree_root);
+  layer_tree_host_->SetRootLayer(layer_tree_root);
 
   scrollbar_layer->SetIsDrawable(true);
   scrollbar_layer->SetBounds(gfx::Size(100, 15));
@@ -1041,7 +1039,7 @@
     layer_tree_root->AddChild(content_layer);
     layer_tree_root->AddChild(scrollbar_layer);
 
-    layer_tree_->SetRootLayer(layer_tree_root);
+    layer_tree_host_->SetRootLayer(layer_tree_root);
 
     scrollbar_layer->SetIsDrawable(true);
     scrollbar_layer->SetBounds(gfx::Size(100, 15));
@@ -1054,7 +1052,7 @@
     EXPECT_EQ(scrollbar_layer->GetLayerTreeHostForTesting(),
               layer_tree_host_.get());
 
-    layer_tree_->SetDeviceScaleFactor(test_scale);
+    layer_tree_host_->SetDeviceScaleFactor(test_scale);
 
     scrollbar_layer->SavePaintProperties();
     scrollbar_layer->Update();
@@ -1110,7 +1108,7 @@
 
     layer_tree_root->AddChild(scrollbar_layer);
 
-    layer_tree_->SetRootLayer(layer_tree_root);
+    layer_tree_host_->SetRootLayer(layer_tree_root);
 
     scrollbar_layer->SetBounds(scrollbar_rect.size());
     scrollbar_layer->SetPosition(gfx::PointF(scrollbar_rect.origin()));
@@ -1118,7 +1116,7 @@
     scrollbar_layer->fake_scrollbar()->set_track_rect(scrollbar_rect);
     scrollbar_layer->set_visible_layer_rect(scrollbar_rect);
 
-    layer_tree_->SetDeviceScaleFactor(test_scale);
+    layer_tree_host_->SetDeviceScaleFactor(test_scale);
 
     gfx::Rect screen_space_clip_rect;
     scrollbar_layer->SavePaintProperties();
diff --git a/cc/layers/surface_layer_unittest.cc b/cc/layers/surface_layer_unittest.cc
index fe0798e..52766d5c 100644
--- a/cc/layers/surface_layer_unittest.cc
+++ b/cc/layers/surface_layer_unittest.cc
@@ -39,13 +39,12 @@
     animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
     layer_tree_host_ = FakeLayerTreeHost::Create(
         &fake_client_, &task_graph_runner_, animation_host_.get());
-    layer_tree_ = layer_tree_host_->GetLayerTree();
-    layer_tree_->SetViewportSize(gfx::Size(10, 10));
+    layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
   }
 
   void TearDown() override {
     if (layer_tree_host_) {
-      layer_tree_->SetRootLayer(nullptr);
+      layer_tree_host_->SetRootLayer(nullptr);
       layer_tree_host_ = nullptr;
     }
   }
@@ -54,7 +53,6 @@
   TestTaskGraphRunner task_graph_runner_;
   std::unique_ptr<AnimationHost> animation_host_;
   std::unique_ptr<FakeLayerTreeHost> layer_tree_host_;
-  LayerTree* layer_tree_;
 };
 
 class TestSurfaceReferenceFactory : public SequenceSurfaceReferenceFactory {
@@ -105,7 +103,7 @@
   layer->SetSurfaceInfo(info);
   layer_tree_host_->GetSurfaceSequenceGenerator()->set_frame_sink_id(
       FrameSinkId(1, 1));
-  layer_tree_->SetRootLayer(layer);
+  layer_tree_host_->SetRootLayer(layer);
 
   auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
   std::unique_ptr<FakeLayerTreeHost> layer_tree_host2 =
@@ -140,7 +138,7 @@
   EXPECT_TRUE(required_seq.count(expected1));
   EXPECT_TRUE(required_seq.count(expected2));
 
-  layer_tree_->SetRootLayer(nullptr);
+  layer_tree_host_->SetRootLayer(nullptr);
   layer_tree_host_.reset();
 
   // Layer was removed so sequence from first LayerTreeHost should be
@@ -172,7 +170,7 @@
     // Layer hasn't been added to tree so no SurfaceSequence generated yet.
     EXPECT_EQ(0u, required_set_.size());
 
-    layer_tree()->SetRootLayer(layer_);
+    layer_tree_host()->SetRootLayer(layer_);
 
     // Should have SurfaceSequence from first tree.
     SurfaceSequence expected(kArbitraryFrameSinkId, 1u);
@@ -182,7 +180,7 @@
     EXPECT_TRUE(required_set_.count(expected));
 
     gfx::Size bounds(100, 100);
-    layer_tree()->SetViewportSize(bounds);
+    layer_tree_host()->SetViewportSize(bounds);
 
     blank_layer_ = SolidColorLayer::Create();
     blank_layer_->SetIsDrawable(true);
@@ -220,7 +218,7 @@
     switch (commit_count_) {
       case 1:
         // Remove SurfaceLayer from tree to cause SwapPromise to be created.
-        layer_tree()->SetRootLayer(blank_layer_);
+        layer_tree_host()->SetRootLayer(blank_layer_);
         break;
       case 2:
         EndTest();
@@ -259,7 +257,7 @@
     switch (commit_count_) {
       case 1:
         // Remove SurfaceLayer from tree to cause SwapPromise to be created.
-        layer_tree()->SetRootLayer(blank_layer_);
+        layer_tree_host()->SetRootLayer(blank_layer_);
         break;
       case 2:
         layer_tree_host()->SetNeedsCommit();
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc
index 0d98d5f..998c629 100644
--- a/cc/layers/texture_layer_unittest.cc
+++ b/cc/layers/texture_layer_unittest.cc
@@ -218,9 +218,8 @@
     animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
     layer_tree_host_ = MockLayerTreeHost::Create(
         &fake_client_, &task_graph_runner_, animation_host_.get());
-    layer_tree_ = layer_tree_host_->GetLayerTree();
     EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
-    layer_tree_->SetViewportSize(gfx::Size(10, 10));
+    layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
     Mock::VerifyAndClearExpectations(layer_tree_host_.get());
   }
 
@@ -229,14 +228,13 @@
     EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
 
     animation_host_->SetMutatorHostClient(nullptr);
-    layer_tree_->SetRootLayer(nullptr);
+    layer_tree_host_->SetRootLayer(nullptr);
     layer_tree_host_ = nullptr;
     animation_host_ = nullptr;
   }
 
   std::unique_ptr<MockLayerTreeHost> layer_tree_host_;
   std::unique_ptr<AnimationHost> animation_host_;
-  LayerTree* layer_tree_;
   FakeImplTaskRunnerProvider task_runner_provider_;
   FakeLayerTreeHostClient fake_client_;
   TestSharedBitmapManager shared_bitmap_manager_;
@@ -249,7 +247,7 @@
 TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
   scoped_refptr<TextureLayer> test_layer =
       TextureLayer::CreateForMailbox(nullptr);
-  EXPECT_SET_NEEDS_COMMIT(1, layer_tree_->SetRootLayer(test_layer));
+  EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
 
   // Test properties that should call SetNeedsCommit.  All properties need to
   // be set to new values in order for SetNeedsCommit to be called.
@@ -289,7 +287,7 @@
   ASSERT_TRUE(test_layer.get());
 
   EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
-  layer_tree_->SetRootLayer(test_layer);
+  layer_tree_host_->SetRootLayer(test_layer);
   Mock::VerifyAndClearExpectations(layer_tree_host_.get());
 
   EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
@@ -758,8 +756,8 @@
     layer_->SetBounds(bounds);
 
     root_->AddChild(layer_);
-    layer_tree()->SetRootLayer(root_);
-    layer_tree()->SetViewportSize(bounds);
+    layer_tree_host()->SetRootLayer(root_);
+    layer_tree_host()->SetViewportSize(bounds);
     SetMailbox('1');
     EXPECT_EQ(0, callback_count_);
 
@@ -817,8 +815,8 @@
     layer_->SetBounds(bounds);
 
     root_->AddChild(layer_);
-    layer_tree()->SetRootLayer(root_);
-    layer_tree()->SetViewportSize(bounds);
+    layer_tree_host()->SetRootLayer(root_);
+    layer_tree_host()->SetViewportSize(bounds);
     SetMailbox('1');
 
     PostSetNeedsCommitToMainThread();
@@ -881,7 +879,6 @@
     TextureLayerTest::SetUp();
     layer_tree_host_ = MockLayerTreeHost::Create(
         &fake_client_, &task_graph_runner_, animation_host_.get());
-    layer_tree_ = layer_tree_host_->GetLayerTree();
     host_impl_.SetVisible(true);
     EXPECT_TRUE(host_impl_.InitializeRenderer(compositor_frame_sink_.get()));
   }
@@ -1111,7 +1108,7 @@
     texture_layer_->SetIsDrawable(true);
     root->AddChild(texture_layer_);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeTest::SetupTree();
   }
 
@@ -1202,7 +1199,7 @@
     texture_layer_->SetIsDrawable(true);
     parent_layer_->AddChild(texture_layer_);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeTest::SetupTree();
   }
 
@@ -1299,7 +1296,7 @@
     texture_layer->SetBounds(gfx::Size(10, 10));
     texture_layer->SetIsDrawable(true);
 
-    layer_tree()->root_layer()->AddChild(texture_layer);
+    layer_tree_host()->root_layer()->AddChild(texture_layer);
     texture_layer_id_ = texture_layer->id();
   }
 
@@ -1373,8 +1370,8 @@
     layer_->SetBounds(bounds);
 
     root_->AddChild(layer_);
-    layer_tree()->SetRootLayer(root_);
-    layer_tree()->SetViewportSize(bounds);
+    layer_tree_host()->SetRootLayer(root_);
+    layer_tree_host()->SetViewportSize(bounds);
   }
 
   void BeginTest() override {
@@ -1443,8 +1440,8 @@
     layer_->SetBounds(bounds);
 
     root_->AddChild(layer_);
-    layer_tree()->SetRootLayer(root_);
-    layer_tree()->SetViewportSize(bounds);
+    layer_tree_host()->SetRootLayer(root_);
+    layer_tree_host()->SetViewportSize(bounds);
   }
 
   void BeginTest() override {
diff --git a/cc/layers/ui_resource_layer.cc b/cc/layers/ui_resource_layer.cc
index 3ec7af8..c2ed214 100644
--- a/cc/layers/ui_resource_layer.cc
+++ b/cc/layers/ui_resource_layer.cc
@@ -76,7 +76,7 @@
 
 void UIResourceLayer::SetBitmap(const SkBitmap& bitmap) {
   bitmap_ = bitmap;
-  if (!GetLayerTree())
+  if (!layer_tree_host())
     return;
   SetUIResourceIdInternal(
       layer_tree_host()->GetUIResourceManager()->GetOrCreateUIResource(bitmap));
@@ -103,7 +103,7 @@
 
   layer_impl->SetUIResourceId(resource_id_);
   if (resource_id_) {
-    DCHECK(GetLayerTree());
+    DCHECK(layer_tree_host());
 
     gfx::Size image_size =
         layer_tree_host()->GetUIResourceManager()->GetUIResourceSize(
diff --git a/cc/output/bsp_tree_perftest.cc b/cc/output/bsp_tree_perftest.cc
index 2413058e..a6f2ab67 100644
--- a/cc/output/bsp_tree_perftest.cc
+++ b/cc/output/bsp_tree_perftest.cc
@@ -44,11 +44,11 @@
 
   void SetupTree() override {
     gfx::Size viewport = gfx::Size(720, 1038);
-    layer_tree()->SetViewportSize(viewport);
+    layer_tree_host()->SetViewportSize(viewport);
     scoped_refptr<Layer> root =
         ParseTreeFromJson(json_, &content_layer_client_);
     ASSERT_TRUE(root.get());
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     content_layer_client_.set_bounds(viewport);
   }
 
diff --git a/cc/resources/DEPS b/cc/resources/DEPS
new file mode 100644
index 0000000..7502d902
--- /dev/null
+++ b/cc/resources/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+mojo/public/cpp/bindings/struct_traits.h",
+]
diff --git a/cc/resources/texture_mailbox.h b/cc/resources/texture_mailbox.h
index a8d1f79..bcb40c5 100644
--- a/cc/resources/texture_mailbox.h
+++ b/cc/resources/texture_mailbox.h
@@ -13,10 +13,16 @@
 #include "base/memory/shared_memory.h"
 #include "cc/base/cc_export.h"
 #include "gpu/command_buffer/common/mailbox_holder.h"
+#include "mojo/public/cpp/bindings/struct_traits.h"
 #include "ui/gfx/color_space.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace cc {
+
+namespace mojom {
+class TextureMailboxDataView;
+}
+
 class SharedBitmap;
 
 // TODO(skaslev, danakj) Rename this class more apropriately since now it
@@ -93,6 +99,9 @@
 #endif
 
  private:
+  friend struct mojo::StructTraits<mojom::TextureMailboxDataView,
+                                   TextureMailbox>;
+
   gpu::MailboxHolder mailbox_holder_;
   SharedBitmap* shared_bitmap_;
   gfx::Size size_in_pixels_;
diff --git a/cc/test/fake_layer_tree_host.cc b/cc/test/fake_layer_tree_host.cc
index d15255e..c821b004 100644
--- a/cc/test/fake_layer_tree_host.cc
+++ b/cc/test/fake_layer_tree_host.cc
@@ -9,30 +9,14 @@
 #include "cc/animation/animation_host.h"
 #include "cc/layers/layer.h"
 #include "cc/test/test_task_graph_runner.h"
-#include "cc/trees/layer_tree.h"
 #include "cc/trees/mutator_host.h"
 
 namespace cc {
 
-namespace {
-
-class FakeLayerTree : public LayerTree {
- public:
-  FakeLayerTree(MutatorHost* mutator_host, LayerTreeHost* layer_tree_host)
-      : LayerTree(mutator_host, layer_tree_host) {}
-
-  void SetNeedsFullTreeSync() override {}
-};
-
-}  // namespace
-
 FakeLayerTreeHost::FakeLayerTreeHost(FakeLayerTreeHostClient* client,
                                      LayerTreeHost::InitParams* params,
                                      CompositorMode mode)
-    : LayerTreeHost(
-          params,
-          mode,
-          base::MakeUnique<FakeLayerTree>(params->mutator_host, this)),
+    : LayerTreeHost(params, mode),
       client_(client),
       host_impl_(*params->settings,
                  &task_runner_provider_,
@@ -87,24 +71,20 @@
 LayerImpl* FakeLayerTreeHost::CommitAndCreateLayerImplTree() {
   TreeSynchronizer::SynchronizeTrees(root_layer(), active_tree());
   active_tree()->SetPropertyTrees(property_trees());
-  TreeSynchronizer::PushLayerProperties(root_layer()->GetLayerTree(),
+  TreeSynchronizer::PushLayerProperties(root_layer()->layer_tree_host(),
                                         active_tree());
-  layer_tree_->mutator_host()->PushPropertiesTo(host_impl_.mutator_host());
+  mutator_host()->PushPropertiesTo(host_impl_.mutator_host());
 
   active_tree()->property_trees()->scroll_tree.PushScrollUpdatesFromMainThread(
       property_trees(), active_tree());
 
-  if (layer_tree_->page_scale_layer() &&
-      layer_tree_->inner_viewport_scroll_layer()) {
+  if (page_scale_layer() && inner_viewport_scroll_layer()) {
     active_tree()->SetViewportLayersFromIds(
-        layer_tree_->overscroll_elasticity_layer()
-            ? layer_tree_->overscroll_elasticity_layer()->id()
-            : Layer::INVALID_ID,
-        layer_tree_->page_scale_layer()->id(),
-        layer_tree_->inner_viewport_scroll_layer()->id(),
-        layer_tree_->outer_viewport_scroll_layer()
-            ? layer_tree_->outer_viewport_scroll_layer()->id()
-            : Layer::INVALID_ID);
+        overscroll_elasticity_layer() ? overscroll_elasticity_layer()->id()
+                                      : Layer::INVALID_ID,
+        page_scale_layer()->id(), inner_viewport_scroll_layer()->id(),
+        outer_viewport_scroll_layer() ? outer_viewport_scroll_layer()->id()
+                                      : Layer::INVALID_ID);
   }
 
   active_tree()->UpdatePropertyTreesForBoundsDelta();
@@ -114,9 +94,9 @@
 LayerImpl* FakeLayerTreeHost::CommitAndCreatePendingTree() {
   TreeSynchronizer::SynchronizeTrees(root_layer(), pending_tree());
   pending_tree()->SetPropertyTrees(property_trees());
-  TreeSynchronizer::PushLayerProperties(root_layer()->GetLayerTree(),
+  TreeSynchronizer::PushLayerProperties(root_layer()->layer_tree_host(),
                                         pending_tree());
-  layer_tree_->mutator_host()->PushPropertiesTo(host_impl_.mutator_host());
+  mutator_host()->PushPropertiesTo(host_impl_.mutator_host());
 
   pending_tree()->property_trees()->scroll_tree.PushScrollUpdatesFromMainThread(
       property_trees(), pending_tree());
diff --git a/cc/test/fake_layer_tree_host.h b/cc/test/fake_layer_tree_host.h
index 2aa30c6..0586804 100644
--- a/cc/test/fake_layer_tree_host.h
+++ b/cc/test/fake_layer_tree_host.h
@@ -46,17 +46,7 @@
 
   void SetNeedsCommit() override;
   void SetNeedsUpdateLayers() override {}
-
-  void SetRootLayer(scoped_refptr<Layer> root_layer) {
-    layer_tree_->SetRootLayer(root_layer);
-  }
-  Layer* root_layer() const { return layer_tree_->root_layer(); }
-  PropertyTrees* property_trees() const {
-    return layer_tree_->property_trees();
-  }
-  void BuildPropertyTreesForTesting() {
-    layer_tree_->BuildPropertyTreesForTesting();
-  }
+  void SetNeedsFullTreeSync() override {}
 
   LayerImpl* CommitAndCreateLayerImplTree();
   LayerImpl* CommitAndCreatePendingTree();
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc
index 6b5ff6a36..b59c54d 100644
--- a/cc/test/layer_tree_pixel_test.cc
+++ b/cc/test/layer_tree_pixel_test.cc
@@ -102,7 +102,7 @@
 
 void LayerTreePixelTest::BeginTest() {
   Layer* target =
-      readback_target_ ? readback_target_ : layer_tree()->root_layer();
+      readback_target_ ? readback_target_ : layer_tree_host()->root_layer();
   target->RequestCopyOfOutput(CreateCopyOutputRequest());
   PostSetNeedsCommitToMainThread();
 }
@@ -215,7 +215,7 @@
   scoped_refptr<Layer> root = Layer::Create();
   root->SetBounds(content_root_->bounds());
   root->AddChild(content_root_);
-  layer_tree()->SetRootLayer(root);
+  layer_tree_host()->SetRootLayer(root);
   LayerTreeTest::SetupTree();
 }
 
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 149a01ba..e3dc1e1 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -67,9 +67,8 @@
 
   inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true);
   outer_scroll_layer->SetIsContainerForFixedPositionLayers(true);
-  host->GetLayerTree()->RegisterViewportLayers(
-      overscroll_elasticity_layer, page_scale_layer,
-      inner_viewport_scroll_layer, outer_scroll_layer);
+  host->RegisterViewportLayers(overscroll_elasticity_layer, page_scale_layer,
+                               inner_viewport_scroll_layer, outer_scroll_layer);
 }
 
 void CreateVirtualViewportLayers(Layer* root_layer,
@@ -634,17 +633,17 @@
 }
 
 void LayerTreeTest::SetupTree() {
-  if (!layer_tree()->root_layer()) {
+  if (!layer_tree_host()->root_layer()) {
     scoped_refptr<Layer> root_layer = Layer::Create();
     root_layer->SetBounds(gfx::Size(1, 1));
-    layer_tree()->SetRootLayer(root_layer);
+    layer_tree_host()->SetRootLayer(root_layer);
   }
 
-  gfx::Size root_bounds = layer_tree()->root_layer()->bounds();
-  gfx::Size device_root_bounds =
-      gfx::ScaleToCeiledSize(root_bounds, layer_tree()->device_scale_factor());
-  layer_tree()->SetViewportSize(device_root_bounds);
-  layer_tree()->root_layer()->SetIsDrawable(true);
+  gfx::Size root_bounds = layer_tree_host()->root_layer()->bounds();
+  gfx::Size device_root_bounds = gfx::ScaleToCeiledSize(
+      root_bounds, layer_tree_host()->device_scale_factor());
+  layer_tree_host()->SetViewportSize(device_root_bounds);
+  layer_tree_host()->root_layer()->SetIsDrawable(true);
 }
 
 void LayerTreeTest::Timeout() {
@@ -702,7 +701,7 @@
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   if (layer_tree_host_)
     DispatchSetNeedsRedrawRect(
-        gfx::Rect(layer_tree_host_->GetLayerTree()->device_viewport_size()));
+        gfx::Rect(layer_tree_host_->device_viewport_size()));
 }
 
 void LayerTreeTest::DispatchSetNeedsRedrawRect(const gfx::Rect& damage_rect) {
@@ -813,8 +812,8 @@
 }
 
 void LayerTreeTest::DestroyLayerTreeHost() {
-  if (layer_tree_host_ && layer_tree_host_->GetLayerTree()->root_layer())
-    layer_tree_host_->GetLayerTree()->root_layer()->SetLayerTreeHost(NULL);
+  if (layer_tree_host_ && layer_tree_host_->root_layer())
+    layer_tree_host_->root_layer()->SetLayerTreeHost(NULL);
   layer_tree_host_ = nullptr;
 }
 
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h
index fbe9996f..625f47b 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -122,7 +122,6 @@
   bool TestEnded() const { return ended_; }
 
   LayerTreeHost* layer_tree_host();
-  LayerTree* layer_tree() { return layer_tree_host()->GetLayerTree(); }
   SharedBitmapManager* shared_bitmap_manager() const {
     return shared_bitmap_manager_.get();
   }
diff --git a/cc/test/push_properties_counting_layer.cc b/cc/test/push_properties_counting_layer.cc
index f2acf553..053b7db7 100644
--- a/cc/test/push_properties_counting_layer.cc
+++ b/cc/test/push_properties_counting_layer.cc
@@ -5,6 +5,7 @@
 #include "cc/test/push_properties_counting_layer.h"
 
 #include "cc/test/push_properties_counting_layer_impl.h"
+#include "cc/trees/layer_tree_host.h"
 
 namespace cc {
 
@@ -38,7 +39,7 @@
 void PushPropertiesCountingLayer::AddPushPropertiesCount() {
   push_properties_count_++;
   if (persist_needs_push_properties_) {
-    GetLayerTree()->AddLayerShouldPushProperties(this);
+    layer_tree_host()->AddLayerShouldPushProperties(this);
   }
 }
 
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index af6f8e6..7ee8b0b0 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -14,7 +14,6 @@
 #include "cc/layers/layer_impl.h"
 #include "cc/trees/clip_node.h"
 #include "cc/trees/effect_node.h"
-#include "cc/trees/layer_tree.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "cc/trees/property_tree.h"
 #include "cc/trees/property_tree_builder.h"
@@ -765,12 +764,12 @@
   return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree);
 }
 
-void FindLayersThatNeedUpdates(LayerTree* layer_tree,
+void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host,
                                const PropertyTrees* property_trees,
                                LayerList* update_layer_list) {
   const TransformTree& transform_tree = property_trees->transform_tree;
   const EffectTree& effect_tree = property_trees->effect_tree;
-  for (auto* layer : *layer_tree) {
+  for (auto* layer : *layer_tree_host) {
     if (!IsRootLayer(layer) &&
         LayerShouldBeSkipped(layer, transform_tree, effect_tree))
       continue;
diff --git a/cc/trees/draw_property_utils.h b/cc/trees/draw_property_utils.h
index 4e9e022..4f19d14 100644
--- a/cc/trees/draw_property_utils.h
+++ b/cc/trees/draw_property_utils.h
@@ -18,7 +18,7 @@
 
 class Layer;
 class LayerImpl;
-class LayerTree;
+class LayerTreeHost;
 class RenderSurfaceImpl;
 class EffectTree;
 class TransformTree;
@@ -62,7 +62,7 @@
 void CC_EXPORT UpdatePropertyTrees(PropertyTrees* property_trees,
                                    bool can_render_to_separate_surface);
 
-void CC_EXPORT FindLayersThatNeedUpdates(LayerTree* layer_tree,
+void CC_EXPORT FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host,
                                          const PropertyTrees* property_trees,
                                          LayerList* update_layer_list);
 
diff --git a/cc/trees/layer_tree.cc b/cc/trees/layer_tree.cc
deleted file mode 100644
index c545a12..0000000
--- a/cc/trees/layer_tree.cc
+++ /dev/null
@@ -1,511 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/trees/layer_tree.h"
-
-#include "base/auto_reset.h"
-#include "base/time/time.h"
-#include "cc/input/page_scale_animation.h"
-#include "cc/layers/heads_up_display_layer.h"
-#include "cc/layers/heads_up_display_layer_impl.h"
-#include "cc/layers/layer.h"
-#include "cc/trees/layer_tree_host.h"
-#include "cc/trees/layer_tree_host_common.h"
-#include "cc/trees/layer_tree_impl.h"
-#include "cc/trees/mutator_host.h"
-#include "cc/trees/property_tree_builder.h"
-
-namespace cc {
-
-LayerTree::LayerTree(MutatorHost* mutator_host, LayerTreeHost* layer_tree_host)
-    : event_listener_properties_(),
-      mutator_host_(mutator_host),
-      layer_tree_host_(layer_tree_host) {
-  DCHECK(mutator_host_);
-  DCHECK(layer_tree_host_);
-  mutator_host_->SetMutatorHostClient(this);
-}
-
-LayerTree::~LayerTree() {
-  mutator_host_->SetMutatorHostClient(nullptr);
-
-  // We must clear any pointers into the layer tree prior to destroying it.
-  RegisterViewportLayers(nullptr, nullptr, nullptr, nullptr);
-
-  if (root_layer_) {
-    root_layer_->SetLayerTreeHost(nullptr);
-
-    // The root layer must be destroyed before the layer tree. We've made a
-    // contract with our animation controllers that the animation_host will
-    // outlive them, and we must make good.
-    root_layer_ = nullptr;
-  }
-}
-
-void LayerTree::SetRootLayer(scoped_refptr<Layer> root_layer) {
-  if (root_layer_.get() == root_layer.get())
-    return;
-
-  if (root_layer_.get())
-    root_layer_->SetLayerTreeHost(nullptr);
-  root_layer_ = root_layer;
-  if (root_layer_.get()) {
-    DCHECK(!root_layer_->parent());
-    root_layer_->SetLayerTreeHost(layer_tree_host_);
-  }
-
-  if (hud_layer_.get())
-    hud_layer_->RemoveFromParent();
-
-  // Reset gpu rasterization tracking.
-  // This flag is sticky until a new tree comes along.
-  layer_tree_host_->ResetGpuRasterizationTracking();
-
-  SetNeedsFullTreeSync();
-}
-
-void LayerTree::RegisterViewportLayers(
-    scoped_refptr<Layer> overscroll_elasticity_layer,
-    scoped_refptr<Layer> page_scale_layer,
-    scoped_refptr<Layer> inner_viewport_scroll_layer,
-    scoped_refptr<Layer> outer_viewport_scroll_layer) {
-  DCHECK(!inner_viewport_scroll_layer ||
-         inner_viewport_scroll_layer != outer_viewport_scroll_layer);
-  overscroll_elasticity_layer_ = overscroll_elasticity_layer;
-  page_scale_layer_ = page_scale_layer;
-  inner_viewport_scroll_layer_ = inner_viewport_scroll_layer;
-  outer_viewport_scroll_layer_ = outer_viewport_scroll_layer;
-}
-
-void LayerTree::RegisterSelection(const LayerSelection& selection) {
-  if (selection_ == selection)
-    return;
-
-  selection_ = selection;
-  SetNeedsCommit();
-}
-
-void LayerTree::SetHaveScrollEventHandlers(bool have_event_handlers) {
-  if (have_scroll_event_handlers_ == have_event_handlers)
-    return;
-
-  have_scroll_event_handlers_ = have_event_handlers;
-  SetNeedsCommit();
-}
-
-void LayerTree::SetEventListenerProperties(EventListenerClass event_class,
-                                           EventListenerProperties properties) {
-  const size_t index = static_cast<size_t>(event_class);
-  if (event_listener_properties_[index] == properties)
-    return;
-
-  event_listener_properties_[index] = properties;
-  SetNeedsCommit();
-}
-
-void LayerTree::SetViewportSize(const gfx::Size& device_viewport_size) {
-  if (device_viewport_size_ == device_viewport_size)
-    return;
-
-  device_viewport_size_ = device_viewport_size;
-
-  SetPropertyTreesNeedRebuild();
-  SetNeedsCommit();
-}
-
-void LayerTree::SetBrowserControlsHeight(float height, bool shrink) {
-  if (top_controls_height_ == height &&
-      browser_controls_shrink_blink_size_ == shrink)
-    return;
-
-  top_controls_height_ = height;
-  browser_controls_shrink_blink_size_ = shrink;
-  SetNeedsCommit();
-}
-
-void LayerTree::SetBrowserControlsShownRatio(float ratio) {
-  if (top_controls_shown_ratio_ == ratio)
-    return;
-
-  top_controls_shown_ratio_ = ratio;
-  SetNeedsCommit();
-}
-
-void LayerTree::SetBottomControlsHeight(float height) {
-  if (bottom_controls_height_ == height)
-    return;
-
-  bottom_controls_height_ = height;
-  SetNeedsCommit();
-}
-
-void LayerTree::SetPageScaleFactorAndLimits(float page_scale_factor,
-                                            float min_page_scale_factor,
-                                            float max_page_scale_factor) {
-  if (page_scale_factor_ == page_scale_factor &&
-      min_page_scale_factor_ == min_page_scale_factor &&
-      max_page_scale_factor_ == max_page_scale_factor)
-    return;
-
-  page_scale_factor_ = page_scale_factor;
-  min_page_scale_factor_ = min_page_scale_factor;
-  max_page_scale_factor_ = max_page_scale_factor;
-  SetPropertyTreesNeedRebuild();
-  SetNeedsCommit();
-}
-
-void LayerTree::StartPageScaleAnimation(const gfx::Vector2d& target_offset,
-                                        bool use_anchor,
-                                        float scale,
-                                        base::TimeDelta duration) {
-  pending_page_scale_animation_.reset(new PendingPageScaleAnimation(
-      target_offset, use_anchor, scale, duration));
-
-  SetNeedsCommit();
-}
-
-bool LayerTree::HasPendingPageScaleAnimation() const {
-  return !!pending_page_scale_animation_.get();
-}
-
-void LayerTree::SetDeviceScaleFactor(float device_scale_factor) {
-  if (device_scale_factor_ == device_scale_factor)
-    return;
-  device_scale_factor_ = device_scale_factor;
-
-  property_trees_.needs_rebuild = true;
-  SetNeedsCommit();
-}
-
-void LayerTree::SetPaintedDeviceScaleFactor(float painted_device_scale_factor) {
-  if (painted_device_scale_factor_ == painted_device_scale_factor)
-    return;
-  painted_device_scale_factor_ = painted_device_scale_factor;
-
-  SetNeedsCommit();
-}
-
-void LayerTree::SetDeviceColorSpace(const gfx::ColorSpace& device_color_space) {
-  if (device_color_space_ == device_color_space)
-    return;
-  device_color_space_ = device_color_space;
-  LayerTreeHostCommon::CallFunctionForEveryLayer(
-      this, [](Layer* layer) { layer->SetNeedsDisplay(); });
-}
-
-void LayerTree::RegisterLayer(Layer* layer) {
-  DCHECK(!LayerById(layer->id()));
-  DCHECK(!in_paint_layer_contents_);
-  layer_id_map_[layer->id()] = layer;
-  if (layer->element_id()) {
-    mutator_host_->RegisterElement(layer->element_id(),
-                                   ElementListType::ACTIVE);
-  }
-}
-
-void LayerTree::UnregisterLayer(Layer* layer) {
-  DCHECK(LayerById(layer->id()));
-  DCHECK(!in_paint_layer_contents_);
-  if (layer->element_id()) {
-    mutator_host_->UnregisterElement(layer->element_id(),
-                                     ElementListType::ACTIVE);
-  }
-  RemoveLayerShouldPushProperties(layer);
-  layer_id_map_.erase(layer->id());
-}
-
-Layer* LayerTree::LayerById(int id) const {
-  LayerIdMap::const_iterator iter = layer_id_map_.find(id);
-  return iter != layer_id_map_.end() ? iter->second : nullptr;
-}
-
-size_t LayerTree::NumLayers() const {
-  return layer_id_map_.size();
-}
-
-bool LayerTree::UpdateLayers(const LayerList& update_layer_list,
-                             bool* content_is_suitable_for_gpu) {
-  base::AutoReset<bool> painting(&in_paint_layer_contents_, true);
-  bool did_paint_content = false;
-  for (const auto& layer : update_layer_list) {
-    did_paint_content |= layer->Update();
-    *content_is_suitable_for_gpu &= layer->IsSuitableForGpuRasterization();
-  }
-  return did_paint_content;
-}
-
-void LayerTree::AddLayerShouldPushProperties(Layer* layer) {
-  layers_that_should_push_properties_.insert(layer);
-}
-
-void LayerTree::RemoveLayerShouldPushProperties(Layer* layer) {
-  layers_that_should_push_properties_.erase(layer);
-}
-
-std::unordered_set<Layer*>& LayerTree::LayersThatShouldPushProperties() {
-  return layers_that_should_push_properties_;
-}
-
-bool LayerTree::LayerNeedsPushPropertiesForTesting(Layer* layer) const {
-  return layers_that_should_push_properties_.find(layer) !=
-         layers_that_should_push_properties_.end();
-}
-
-void LayerTree::SetNeedsMetaInfoRecomputation(bool needs_recomputation) {
-  needs_meta_info_recomputation_ = needs_recomputation;
-}
-
-void LayerTree::SetPageScaleFromImplSide(float page_scale) {
-  DCHECK(layer_tree_host_->CommitRequested());
-  page_scale_factor_ = page_scale;
-  SetPropertyTreesNeedRebuild();
-}
-
-void LayerTree::SetElasticOverscrollFromImplSide(
-    gfx::Vector2dF elastic_overscroll) {
-  DCHECK(layer_tree_host_->CommitRequested());
-  elastic_overscroll_ = elastic_overscroll;
-}
-
-void LayerTree::UpdateHudLayer(bool show_hud_info) {
-  if (show_hud_info) {
-    if (!hud_layer_.get()) {
-      hud_layer_ = HeadsUpDisplayLayer::Create();
-    }
-
-    if (root_layer_.get() && !hud_layer_->parent())
-      root_layer_->AddChild(hud_layer_);
-  } else if (hud_layer_.get()) {
-    hud_layer_->RemoveFromParent();
-    hud_layer_ = nullptr;
-  }
-}
-
-void LayerTree::SetNeedsFullTreeSync() {
-  needs_full_tree_sync_ = true;
-  needs_meta_info_recomputation_ = true;
-
-  property_trees_.needs_rebuild = true;
-  SetNeedsCommit();
-}
-
-void LayerTree::SetNeedsCommit() {
-  layer_tree_host_->SetNeedsCommit();
-}
-
-const LayerTreeSettings& LayerTree::GetSettings() const {
-  return layer_tree_host_->GetSettings();
-}
-
-void LayerTree::SetPropertyTreesNeedRebuild() {
-  property_trees_.needs_rebuild = true;
-  layer_tree_host_->SetNeedsUpdateLayers();
-}
-
-void LayerTree::PushPropertiesTo(LayerTreeImpl* tree_impl) {
-  tree_impl->set_needs_full_tree_sync(needs_full_tree_sync_);
-  needs_full_tree_sync_ = false;
-
-  if (hud_layer_.get()) {
-    LayerImpl* hud_impl = tree_impl->LayerById(hud_layer_->id());
-    tree_impl->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl));
-  } else {
-    tree_impl->set_hud_layer(nullptr);
-  }
-
-  tree_impl->set_background_color(background_color_);
-  tree_impl->set_has_transparent_background(has_transparent_background_);
-  tree_impl->set_have_scroll_event_handlers(have_scroll_event_handlers_);
-  tree_impl->set_event_listener_properties(
-      EventListenerClass::kTouchStartOrMove,
-      event_listener_properties(EventListenerClass::kTouchStartOrMove));
-  tree_impl->set_event_listener_properties(
-      EventListenerClass::kMouseWheel,
-      event_listener_properties(EventListenerClass::kMouseWheel));
-  tree_impl->set_event_listener_properties(
-      EventListenerClass::kTouchEndOrCancel,
-      event_listener_properties(EventListenerClass::kTouchEndOrCancel));
-
-  if (page_scale_layer_ && inner_viewport_scroll_layer_) {
-    tree_impl->SetViewportLayersFromIds(
-        overscroll_elasticity_layer_ ? overscroll_elasticity_layer_->id()
-                                     : Layer::INVALID_ID,
-        page_scale_layer_->id(), inner_viewport_scroll_layer_->id(),
-        outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
-                                     : Layer::INVALID_ID);
-    DCHECK(inner_viewport_scroll_layer_->IsContainerForFixedPositionLayers());
-  } else {
-    tree_impl->ClearViewportLayers();
-  }
-
-  tree_impl->RegisterSelection(selection_);
-
-  bool property_trees_changed_on_active_tree =
-      tree_impl->IsActiveTree() && tree_impl->property_trees()->changed;
-  // Property trees may store damage status. We preserve the sync tree damage
-  // status by pushing the damage status from sync tree property trees to main
-  // thread property trees or by moving it onto the layers.
-  if (root_layer_ && property_trees_changed_on_active_tree) {
-    if (property_trees_.sequence_number ==
-        tree_impl->property_trees()->sequence_number)
-      tree_impl->property_trees()->PushChangeTrackingTo(&property_trees_);
-    else
-      tree_impl->MoveChangeTrackingToLayers();
-  }
-  // Setting property trees must happen before pushing the page scale.
-  tree_impl->SetPropertyTrees(&property_trees_);
-
-  tree_impl->PushPageScaleFromMainThread(
-      page_scale_factor_, min_page_scale_factor_, max_page_scale_factor_);
-
-  tree_impl->set_browser_controls_shrink_blink_size(
-      browser_controls_shrink_blink_size_);
-  tree_impl->set_top_controls_height(top_controls_height_);
-  tree_impl->set_bottom_controls_height(bottom_controls_height_);
-  tree_impl->PushBrowserControlsFromMainThread(top_controls_shown_ratio_);
-  tree_impl->elastic_overscroll()->PushFromMainThread(elastic_overscroll_);
-  if (tree_impl->IsActiveTree())
-    tree_impl->elastic_overscroll()->PushPendingToActive();
-
-  tree_impl->set_painted_device_scale_factor(painted_device_scale_factor_);
-
-  tree_impl->SetDeviceColorSpace(device_color_space_);
-
-  if (pending_page_scale_animation_) {
-    tree_impl->SetPendingPageScaleAnimation(
-        std::move(pending_page_scale_animation_));
-  }
-
-  DCHECK(!tree_impl->ViewportSizeInvalid());
-
-  tree_impl->set_has_ever_been_drawn(false);
-}
-
-Layer* LayerTree::LayerByElementId(ElementId element_id) const {
-  ElementLayersMap::const_iterator iter = element_layers_map_.find(element_id);
-  return iter != element_layers_map_.end() ? iter->second : nullptr;
-}
-
-void LayerTree::RegisterElement(ElementId element_id,
-                                ElementListType list_type,
-                                Layer* layer) {
-  if (layer->element_id()) {
-    element_layers_map_[layer->element_id()] = layer;
-  }
-
-  mutator_host_->RegisterElement(element_id, list_type);
-}
-
-void LayerTree::UnregisterElement(ElementId element_id,
-                                  ElementListType list_type,
-                                  Layer* layer) {
-  mutator_host_->UnregisterElement(element_id, list_type);
-
-  if (layer->element_id()) {
-    element_layers_map_.erase(layer->element_id());
-  }
-}
-
-static void SetElementIdForTesting(Layer* layer) {
-  layer->SetElementId(LayerIdToElementIdForTesting(layer->id()));
-}
-
-void LayerTree::SetElementIdsForTesting() {
-  LayerTreeHostCommon::CallFunctionForEveryLayer(this, SetElementIdForTesting);
-}
-
-void LayerTree::BuildPropertyTreesForTesting() {
-  PropertyTreeBuilder::PreCalculateMetaInformation(root_layer());
-  gfx::Transform identity_transform;
-  PropertyTreeBuilder::BuildPropertyTrees(
-      root_layer(), page_scale_layer(), inner_viewport_scroll_layer(),
-      outer_viewport_scroll_layer(), overscroll_elasticity_layer(),
-      elastic_overscroll(), page_scale_factor(), device_scale_factor(),
-      gfx::Rect(device_viewport_size()), identity_transform, property_trees());
-}
-
-bool LayerTree::IsElementInList(ElementId element_id,
-                                ElementListType list_type) const {
-  return list_type == ElementListType::ACTIVE && LayerByElementId(element_id);
-}
-
-void LayerTree::SetMutatorsNeedCommit() {
-  layer_tree_host_->SetNeedsCommit();
-}
-
-void LayerTree::SetMutatorsNeedRebuildPropertyTrees() {
-  property_trees_.needs_rebuild = true;
-}
-
-void LayerTree::SetElementFilterMutated(ElementId element_id,
-                                        ElementListType list_type,
-                                        const FilterOperations& filters) {
-  Layer* layer = LayerByElementId(element_id);
-  DCHECK(layer);
-  layer->OnFilterAnimated(filters);
-}
-
-void LayerTree::SetElementOpacityMutated(ElementId element_id,
-                                         ElementListType list_type,
-                                         float opacity) {
-  Layer* layer = LayerByElementId(element_id);
-  DCHECK(layer);
-  layer->OnOpacityAnimated(opacity);
-}
-
-void LayerTree::SetElementTransformMutated(ElementId element_id,
-                                           ElementListType list_type,
-                                           const gfx::Transform& transform) {
-  Layer* layer = LayerByElementId(element_id);
-  DCHECK(layer);
-  layer->OnTransformAnimated(transform);
-}
-
-void LayerTree::SetElementScrollOffsetMutated(
-    ElementId element_id,
-    ElementListType list_type,
-    const gfx::ScrollOffset& scroll_offset) {
-  Layer* layer = LayerByElementId(element_id);
-  DCHECK(layer);
-  layer->OnScrollOffsetAnimated(scroll_offset);
-}
-
-void LayerTree::ElementIsAnimatingChanged(ElementId element_id,
-                                          ElementListType list_type,
-                                          const PropertyAnimationState& mask,
-                                          const PropertyAnimationState& state) {
-  Layer* layer = LayerByElementId(element_id);
-  if (layer)
-    layer->OnIsAnimatingChanged(mask, state);
-}
-
-gfx::ScrollOffset LayerTree::GetScrollOffsetForAnimation(
-    ElementId element_id) const {
-  Layer* layer = LayerByElementId(element_id);
-  DCHECK(layer);
-  return layer->ScrollOffsetForAnimation();
-}
-
-LayerListIterator<Layer> LayerTree::begin() const {
-  return LayerListIterator<Layer>(root_layer_.get());
-}
-
-LayerListIterator<Layer> LayerTree::end() const {
-  return LayerListIterator<Layer>(nullptr);
-}
-
-LayerListReverseIterator<Layer> LayerTree::rbegin() {
-  return LayerListReverseIterator<Layer>(root_layer_.get());
-}
-
-LayerListReverseIterator<Layer> LayerTree::rend() {
-  return LayerListReverseIterator<Layer>(nullptr);
-}
-
-void LayerTree::SetNeedsDisplayOnAllLayers() {
-  for (auto* layer : *this)
-    layer->SetNeedsDisplay();
-}
-
-}  // namespace cc
diff --git a/cc/trees/layer_tree.h b/cc/trees/layer_tree.h
deleted file mode 100644
index 7f874120..0000000
--- a/cc/trees/layer_tree.h
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_TREES_LAYER_TREE_H_
-#define CC_TREES_LAYER_TREE_H_
-
-#include <memory>
-#include <unordered_map>
-#include <unordered_set>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "cc/base/cc_export.h"
-#include "cc/input/event_listener_properties.h"
-#include "cc/input/layer_selection_bound.h"
-#include "cc/layers/layer_collections.h"
-#include "cc/layers/layer_list_iterator.h"
-#include "cc/trees/mutator_host_client.h"
-#include "cc/trees/property_tree.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/color_space.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace base {
-class TimeDelta;
-}  // namespace base
-
-namespace cc {
-class HeadsUpDisplayLayer;
-class Layer;
-class LayerTreeHost;
-class LayerTreeImpl;
-class LayerTreeSettings;
-class MutatorHost;
-struct PendingPageScaleAnimation;
-
-class CC_EXPORT LayerTree : public MutatorHostClient {
- public:
-  using LayerSet = std::unordered_set<Layer*>;
-  using LayerIdMap = std::unordered_map<int, Layer*>;
-
-  LayerTree(MutatorHost* mutator_host, LayerTreeHost* layer_tree_host);
-  virtual ~LayerTree();
-
-  void SetRootLayer(scoped_refptr<Layer> root_layer);
-  Layer* root_layer() { return root_layer_.get(); }
-  const Layer* root_layer() const { return root_layer_.get(); }
-
-  void RegisterViewportLayers(scoped_refptr<Layer> overscroll_elasticity_layer,
-                              scoped_refptr<Layer> page_scale_layer,
-                              scoped_refptr<Layer> inner_viewport_scroll_layer,
-                              scoped_refptr<Layer> outer_viewport_scroll_layer);
-
-  Layer* overscroll_elasticity_layer() const {
-    return overscroll_elasticity_layer_.get();
-  }
-  Layer* page_scale_layer() const { return page_scale_layer_.get(); }
-  Layer* inner_viewport_scroll_layer() const {
-    return inner_viewport_scroll_layer_.get();
-  }
-  Layer* outer_viewport_scroll_layer() const {
-    return outer_viewport_scroll_layer_.get();
-  }
-
-  void RegisterSelection(const LayerSelection& selection);
-  const LayerSelection& selection() const { return selection_; }
-
-  void SetHaveScrollEventHandlers(bool have_event_handlers);
-  bool have_scroll_event_handlers() const {
-    return have_scroll_event_handlers_;
-  }
-
-  void SetEventListenerProperties(EventListenerClass event_class,
-                                  EventListenerProperties event_properties);
-  EventListenerProperties event_listener_properties(
-      EventListenerClass event_class) const {
-    return event_listener_properties_[static_cast<size_t>(event_class)];
-  }
-
-  void SetViewportSize(const gfx::Size& device_viewport_size);
-  gfx::Size device_viewport_size() const { return device_viewport_size_; }
-
-  void SetBrowserControlsHeight(float height, bool shrink);
-  void SetBrowserControlsShownRatio(float ratio);
-  void SetBottomControlsHeight(float height);
-
-  void SetPageScaleFactorAndLimits(float page_scale_factor,
-                                   float min_page_scale_factor,
-                                   float max_page_scale_factor);
-  float page_scale_factor() const { return page_scale_factor_; }
-  float min_page_scale_factor() const { return min_page_scale_factor_; }
-  float max_page_scale_factor() const { return max_page_scale_factor_; }
-
-  void set_background_color(SkColor color) { background_color_ = color; }
-  SkColor background_color() const { return background_color_; }
-
-  void set_has_transparent_background(bool transparent) {
-    has_transparent_background_ = transparent;
-  }
-  bool has_transparent_background() const {
-    return has_transparent_background_;
-  }
-
-  void StartPageScaleAnimation(const gfx::Vector2d& target_offset,
-                               bool use_anchor,
-                               float scale,
-                               base::TimeDelta duration);
-  bool HasPendingPageScaleAnimation() const;
-
-  void SetDeviceScaleFactor(float device_scale_factor);
-  float device_scale_factor() const { return device_scale_factor_; }
-
-  void SetPaintedDeviceScaleFactor(float painted_device_scale_factor);
-  float painted_device_scale_factor() const {
-    return painted_device_scale_factor_;
-  }
-
-  void SetDeviceColorSpace(const gfx::ColorSpace& device_color_space);
-  const gfx::ColorSpace& device_color_space() const {
-    return device_color_space_;
-  }
-
-  // Used externally by blink for setting the PropertyTrees when
-  // |settings_.use_layer_lists| is true. This is a SPV2 setting.
-  PropertyTrees* property_trees() { return &property_trees_; }
-
-  void SetNeedsDisplayOnAllLayers();
-
-  void SetNeedsCommit();
-
-  const LayerTreeSettings& GetSettings() const;
-
-  // Methods which should only be used internally in cc ------------------
-  void RegisterLayer(Layer* layer);
-  void UnregisterLayer(Layer* layer);
-  Layer* LayerById(int id) const;
-
-  size_t NumLayers() const;
-
-  bool UpdateLayers(const LayerList& update_layer_list,
-                    bool* content_is_suitable_for_gpu);
-  bool in_paint_layer_contents() const { return in_paint_layer_contents_; }
-
-  void AddLayerShouldPushProperties(Layer* layer);
-  void RemoveLayerShouldPushProperties(Layer* layer);
-  std::unordered_set<Layer*>& LayersThatShouldPushProperties();
-  bool LayerNeedsPushPropertiesForTesting(Layer* layer) const;
-
-  virtual void SetNeedsMetaInfoRecomputation(
-      bool needs_meta_info_recomputation);
-  bool needs_meta_info_recomputation() const {
-    return needs_meta_info_recomputation_;
-  }
-
-  void SetPageScaleFromImplSide(float page_scale);
-  void SetElasticOverscrollFromImplSide(gfx::Vector2dF elastic_overscroll);
-  gfx::Vector2dF elastic_overscroll() const { return elastic_overscroll_; }
-
-  void UpdateHudLayer(bool show_hud_info);
-  HeadsUpDisplayLayer* hud_layer() const { return hud_layer_.get(); }
-
-  virtual void SetNeedsFullTreeSync();
-  bool needs_full_tree_sync() const { return needs_full_tree_sync_; }
-
-  void SetPropertyTreesNeedRebuild();
-
-  void PushPropertiesTo(LayerTreeImpl* tree_impl);
-
-  MutatorHost* mutator_host() const { return mutator_host_; }
-
-  Layer* LayerByElementId(ElementId element_id) const;
-  void RegisterElement(ElementId element_id,
-                       ElementListType list_type,
-                       Layer* layer);
-  void UnregisterElement(ElementId element_id,
-                         ElementListType list_type,
-                         Layer* layer);
-  void SetElementIdsForTesting();
-
-  void BuildPropertyTreesForTesting();
-
-  // Layer iterators.
-  LayerListIterator<Layer> begin() const;
-  LayerListIterator<Layer> end() const;
-  LayerListReverseIterator<Layer> rbegin();
-  LayerListReverseIterator<Layer> rend();
-  // ---------------------------------------------------------------------
-
- private:
-  // MutatorHostClient implementation.
-  bool IsElementInList(ElementId element_id,
-                       ElementListType list_type) const override;
-  void SetMutatorsNeedCommit() override;
-  void SetMutatorsNeedRebuildPropertyTrees() override;
-  void SetElementFilterMutated(ElementId element_id,
-                               ElementListType list_type,
-                               const FilterOperations& filters) override;
-  void SetElementOpacityMutated(ElementId element_id,
-                                ElementListType list_type,
-                                float opacity) override;
-  void SetElementTransformMutated(ElementId element_id,
-                                  ElementListType list_type,
-                                  const gfx::Transform& transform) override;
-  void SetElementScrollOffsetMutated(
-      ElementId element_id,
-      ElementListType list_type,
-      const gfx::ScrollOffset& scroll_offset) override;
-
-  void ElementIsAnimatingChanged(ElementId element_id,
-                                 ElementListType list_type,
-                                 const PropertyAnimationState& mask,
-                                 const PropertyAnimationState& state) override;
-
-  void ScrollOffsetAnimationFinished() override {}
-  gfx::ScrollOffset GetScrollOffsetForAnimation(
-      ElementId element_id) const override;
-
-  scoped_refptr<Layer> root_layer_;
-
-  scoped_refptr<Layer> overscroll_elasticity_layer_;
-  scoped_refptr<Layer> page_scale_layer_;
-  scoped_refptr<Layer> inner_viewport_scroll_layer_;
-  scoped_refptr<Layer> outer_viewport_scroll_layer_;
-
-  float top_controls_height_ = 0.f;
-  float top_controls_shown_ratio_ = 0.f;
-  bool browser_controls_shrink_blink_size_ = false;
-
-  float bottom_controls_height_ = 0.f;
-
-  float device_scale_factor_ = 1.f;
-  float painted_device_scale_factor_ = 1.f;
-  float page_scale_factor_ = 1.f;
-  float min_page_scale_factor_ = 1.f;
-  float max_page_scale_factor_ = 1.f;
-  gfx::ColorSpace device_color_space_;
-
-  SkColor background_color_ = SK_ColorWHITE;
-  bool has_transparent_background_ = false;
-
-  LayerSelection selection_;
-
-  gfx::Size device_viewport_size_;
-
-  bool have_scroll_event_handlers_ = false;
-  EventListenerProperties event_listener_properties_[static_cast<size_t>(
-      EventListenerClass::kNumClasses)];
-
-  std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation_;
-
-  PropertyTrees property_trees_;
-
-  bool needs_full_tree_sync_ = true;
-  bool needs_meta_info_recomputation_ = true;
-
-  gfx::Vector2dF elastic_overscroll_;
-
-  scoped_refptr<HeadsUpDisplayLayer> hud_layer_;
-
-  // Set of layers that need to push properties.
-  LayerSet layers_that_should_push_properties_;
-
-  // Layer id to Layer map.
-  LayerIdMap layer_id_map_;
-
-  using ElementLayersMap = std::unordered_map<ElementId, Layer*, ElementIdHash>;
-  ElementLayersMap element_layers_map_;
-
-  bool in_paint_layer_contents_ = false;
-
-  MutatorHost* mutator_host_;
-  LayerTreeHost* layer_tree_host_;
-
-  DISALLOW_COPY_AND_ASSIGN(LayerTree);
-};
-
-}  // namespace cc
-
-#endif  // CC_TREES_LAYER_TREE_H_
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index b849f50..efc38ca 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -14,6 +14,7 @@
 #include <unordered_map>
 
 #include "base/atomic_sequence_num.h"
+#include "base/auto_reset.h"
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/location.h"
@@ -90,36 +91,22 @@
   return layer_tree_host;
 }
 
-LayerTreeHost::LayerTreeHost(InitParams* params,
-                                               CompositorMode mode)
-    : LayerTreeHost(
-          params,
-          mode,
-          base::MakeUnique<LayerTree>(params->mutator_host, this)) {}
-
-LayerTreeHost::LayerTreeHost(
-    InitParams* params,
-    CompositorMode mode,
-    std::unique_ptr<LayerTree> layer_tree)
+LayerTreeHost::LayerTreeHost(InitParams* params, CompositorMode mode)
     : micro_benchmark_controller_(this),
-      layer_tree_(std::move(layer_tree)),
       compositor_mode_(mode),
       ui_resource_manager_(base::MakeUnique<UIResourceManager>()),
       client_(params->client),
-      source_frame_number_(0),
       rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
       settings_(*params->settings),
       debug_state_(settings_.initial_debug_state),
-      visible_(false),
-      has_gpu_rasterization_trigger_(false),
-      content_is_suitable_for_gpu_rasterization_(true),
-      gpu_rasterization_histogram_recorded_(false),
-      did_complete_scale_animation_(false),
       id_(s_layer_tree_host_sequence_number.GetNext() + 1),
       task_graph_runner_(params->task_graph_runner),
+      event_listener_properties_(),
+      mutator_host_(params->mutator_host),
       image_worker_task_runner_(params->image_worker_task_runner) {
   DCHECK(task_graph_runner_);
-  DCHECK(layer_tree_);
+
+  mutator_host_->SetMutatorHostClient(this);
 
   rendering_stats_instrumentation_->set_record_rendering_stats(
       debug_state_.RecordRenderingStats());
@@ -168,8 +155,7 @@
   proxy_ = std::move(proxy);
   proxy_->Start();
 
-  layer_tree_->mutator_host()->SetSupportsScrollAnimations(
-      proxy_->SupportsImplScrolling());
+  mutator_host_->SetSupportsScrollAnimations(proxy_->SupportsImplScrolling());
 }
 
 LayerTreeHost::~LayerTreeHost() {
@@ -178,8 +164,20 @@
   CHECK(!inside_main_frame_);
   TRACE_EVENT0("cc", "LayerTreeHostInProcess::~LayerTreeHostInProcess");
 
-  // Clear any references into the LayerTreeHostInProcess.
-  layer_tree_.reset();
+  // Clear any references into the LayerTreeHost.
+  mutator_host_->SetMutatorHostClient(nullptr);
+
+  // We must clear any pointers into the layer tree prior to destroying it.
+  RegisterViewportLayers(nullptr, nullptr, nullptr, nullptr);
+
+  if (root_layer_) {
+    root_layer_->SetLayerTreeHost(nullptr);
+
+    // The root layer must be destroyed before the layer tree. We've made a
+    // contract with our animation controllers that the animation_host will
+    // outlive them, and we must make good.
+    root_layer_ = nullptr;
+  }
 
   if (proxy_) {
     DCHECK(task_runner_provider_->IsMainThread());
@@ -198,14 +196,6 @@
   return source_frame_number_;
 }
 
-LayerTree* LayerTreeHost::GetLayerTree() {
-  return layer_tree_.get();
-}
-
-const LayerTree* LayerTreeHost::GetLayerTree() const {
-  return layer_tree_.get();
-}
-
 UIResourceManager* LayerTreeHost::GetUIResourceManager() const {
   return ui_resource_manager_.get();
 }
@@ -281,9 +271,9 @@
   TRACE_EVENT_IS_NEW_TRACE(&is_new_trace);
   if (is_new_trace &&
       frame_viewer_instrumentation::IsTracingLayerTreeSnapshots() &&
-      layer_tree_->root_layer()) {
+      root_layer()) {
     LayerTreeHostCommon::CallFunctionForEveryLayer(
-        layer_tree_.get(), [](Layer* layer) { layer->DidBeginTracing(); });
+        this, [](Layer* layer) { layer->DidBeginTracing(); });
   }
 
   LayerTreeImpl* sync_tree = host_impl->sync_tree();
@@ -299,10 +289,10 @@
 
   sync_tree->set_source_frame_number(SourceFrameNumber());
 
-  if (layer_tree_->needs_full_tree_sync())
-    TreeSynchronizer::SynchronizeTrees(layer_tree_->root_layer(), sync_tree);
+  if (needs_full_tree_sync_)
+    TreeSynchronizer::SynchronizeTrees(root_layer(), sync_tree);
 
-  layer_tree_->PushPropertiesTo(sync_tree);
+  PushPropertiesTo(sync_tree);
 
   sync_tree->PassSwapPromises(swap_promise_manager_.TakeSwapPromises());
 
@@ -311,8 +301,8 @@
       content_is_suitable_for_gpu_rasterization_);
   RecordGpuRasterizationHistogram();
 
-  host_impl->SetViewportSize(layer_tree_->device_viewport_size());
-  sync_tree->SetDeviceScaleFactor(layer_tree_->device_scale_factor());
+  host_impl->SetViewportSize(device_viewport_size_);
+  sync_tree->SetDeviceScaleFactor(device_scale_factor_);
   host_impl->SetDebugState(debug_state_);
 
   sync_tree->set_ui_resource_request_queue(
@@ -321,12 +311,12 @@
   {
     TRACE_EVENT0("cc", "LayerTreeHostInProcess::PushProperties");
 
-    TreeSynchronizer::PushLayerProperties(layer_tree_.get(), sync_tree);
+    TreeSynchronizer::PushLayerProperties(this, sync_tree);
 
     // This must happen after synchronizing property trees and after pushing
     // properties, which updates the clobber_active_value flag.
     sync_tree->property_trees()->scroll_tree.PushScrollUpdatesFromMainThread(
-        layer_tree_->property_trees(), sync_tree);
+        property_trees(), sync_tree);
 
     // This must happen after synchronizing property trees and after push
     // properties, which updates property tree indices, but before animation
@@ -337,11 +327,11 @@
 
     TRACE_EVENT0("cc", "LayerTreeHostInProcess::AnimationHost::PushProperties");
     DCHECK(host_impl->mutator_host());
-    layer_tree_->mutator_host()->PushPropertiesTo(host_impl->mutator_host());
+    mutator_host_->PushPropertiesTo(host_impl->mutator_host());
   }
 
   micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl);
-  layer_tree_->property_trees()->ResetAllChangeTracking();
+  property_trees_.ResetAllChangeTracking();
 }
 
 void LayerTreeHost::WillCommit() {
@@ -406,7 +396,7 @@
 
   const bool supports_impl_scrolling = task_runner_provider_->HasImplThread();
   std::unique_ptr<MutatorHost> mutator_host_impl =
-      layer_tree_->mutator_host()->CreateImplInstance(supports_impl_scrolling);
+      mutator_host_->CreateImplInstance(supports_impl_scrolling);
 
   std::unique_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create(
       settings_, client, task_runner_provider_.get(),
@@ -472,7 +462,7 @@
 void LayerTreeHost::SetAnimationEvents(
     std::unique_ptr<MutatorEvents> events) {
   DCHECK(task_runner_provider_->IsMainThread());
-  layer_tree_->mutator_host()->SetAnimationEvents(std::move(events));
+  mutator_host_->SetAnimationEvents(std::move(events));
 }
 
 void LayerTreeHost::SetDebugState(
@@ -511,8 +501,8 @@
   DCHECK(CommitRequested());
   if (page_scale_delta == 1.f)
     return;
-  float page_scale = layer_tree_->page_scale_factor() * page_scale_delta;
-  layer_tree_->SetPageScaleFromImplSide(page_scale);
+  float page_scale = page_scale_factor_ * page_scale_delta;
+  SetPageScaleFromImplSide(page_scale);
 }
 
 void LayerTreeHost::SetVisible(bool visible) {
@@ -562,20 +552,20 @@
 }
 
 bool LayerTreeHost::UpdateLayers() {
-  if (!layer_tree_->root_layer()) {
-    layer_tree_->property_trees()->clear();
+  if (!root_layer()) {
+    property_trees_.clear();
     return false;
   }
-  DCHECK(!layer_tree_->root_layer()->parent());
+  DCHECK(!root_layer()->parent());
   base::ElapsedTimer timer;
 
-  bool result = DoUpdateLayers(layer_tree_->root_layer());
+  bool result = DoUpdateLayers(root_layer());
   micro_benchmark_controller_.DidUpdateLayers();
 
   if (const char* client_name = GetClientNameForMetrics()) {
-    std::string histogram_name = base::StringPrintf(
-        "Compositing.%s.LayersUpdateTime.%d", client_name,
-        GetLayersUpdateTimeHistogramBucket(layer_tree_->NumLayers()));
+    std::string histogram_name =
+        base::StringPrintf("Compositing.%s.LayersUpdateTime.%d", client_name,
+                           GetLayersUpdateTimeHistogramBucket(NumLayers()));
     base::Histogram::FactoryGet(histogram_name, 0, 10000000, 50,
                                 base::HistogramBase::kUmaTargetedHistogramFlag)
         ->Add(timer.Elapsed().InMicroseconds());
@@ -618,19 +608,18 @@
   TRACE_EVENT1("cc", "LayerTreeHostInProcess::DoUpdateLayers",
                "source_frame_number", SourceFrameNumber());
 
-  layer_tree_->UpdateHudLayer(debug_state_.ShowHudInfo());
+  UpdateHudLayer(debug_state_.ShowHudInfo());
   UpdateHudLayer();
 
   Layer* root_scroll =
       PropertyTreeBuilder::FindFirstScrollableLayer(root_layer);
-  Layer* page_scale_layer = layer_tree_->page_scale_layer();
+  Layer* page_scale_layer = page_scale_layer_.get();
   if (!page_scale_layer && root_scroll)
     page_scale_layer = root_scroll->parent();
 
-  if (layer_tree_->hud_layer()) {
-    layer_tree_->hud_layer()->PrepareForCalculateDrawProperties(
-        layer_tree_->device_viewport_size(),
-        layer_tree_->device_scale_factor());
+  if (hud_layer_) {
+    hud_layer_->PrepareForCalculateDrawProperties(device_viewport_size_,
+                                                  device_scale_factor_);
   }
 
   gfx::Transform identity_transform;
@@ -644,19 +633,15 @@
         "LayerTreeHostInProcessCommon::ComputeVisibleRectsWithPropertyTrees");
     PropertyTreeBuilder::PreCalculateMetaInformation(root_layer);
     bool can_render_to_separate_surface = true;
-    PropertyTrees* property_trees = layer_tree_->property_trees();
+    PropertyTrees* property_trees = &property_trees_;
     if (!settings_.use_layer_lists) {
       // If use_layer_lists is set, then the property trees should have been
       // built by the client already.
       PropertyTreeBuilder::BuildPropertyTrees(
-          root_layer, page_scale_layer,
-          layer_tree_->inner_viewport_scroll_layer(),
-          layer_tree_->outer_viewport_scroll_layer(),
-          layer_tree_->overscroll_elasticity_layer(),
-          layer_tree_->elastic_overscroll(), layer_tree_->page_scale_factor(),
-          layer_tree_->device_scale_factor(),
-          gfx::Rect(layer_tree_->device_viewport_size()), identity_transform,
-          property_trees);
+          root_layer, page_scale_layer, inner_viewport_scroll_layer(),
+          outer_viewport_scroll_layer(), overscroll_elasticity_layer(),
+          elastic_overscroll_, page_scale_factor_, device_scale_factor_,
+          gfx::Rect(device_viewport_size_), identity_transform, property_trees);
       TRACE_EVENT_INSTANT1(
           "cc", "LayerTreeHostInProcess::UpdateLayers_BuiltPropertyTrees",
           TRACE_EVENT_SCOPE_THREAD, "property_trees",
@@ -669,16 +654,16 @@
     }
     draw_property_utils::UpdatePropertyTrees(property_trees,
                                              can_render_to_separate_surface);
-    draw_property_utils::FindLayersThatNeedUpdates(
-        layer_tree_.get(), property_trees, &update_layer_list);
+    draw_property_utils::FindLayersThatNeedUpdates(this, property_trees,
+                                                   &update_layer_list);
   }
 
   for (const auto& layer : update_layer_list)
     layer->SavePaintProperties();
 
   bool content_is_suitable_for_gpu = true;
-  bool did_paint_content = layer_tree_->UpdateLayers(
-      update_layer_list, &content_is_suitable_for_gpu);
+  bool did_paint_content =
+      UpdateLayers(update_layer_list, &content_is_suitable_for_gpu);
 
   if (content_is_suitable_for_gpu) {
     ++num_consecutive_frames_suitable_for_gpu_;
@@ -705,16 +690,16 @@
   // Preemptively apply the scroll offset and scale delta here before sending
   // it to the client.  If the client comes back and sets it to the same
   // value, then the layer can early out without needing a full commit.
-  if (layer_tree_->inner_viewport_scroll_layer()) {
-    layer_tree_->inner_viewport_scroll_layer()->SetScrollOffsetFromImplSide(
+  if (inner_viewport_scroll_layer_) {
+    inner_viewport_scroll_layer_->SetScrollOffsetFromImplSide(
         gfx::ScrollOffsetWithDelta(
-            layer_tree_->inner_viewport_scroll_layer()->scroll_offset(),
+            inner_viewport_scroll_layer_->scroll_offset(),
             inner_viewport_scroll_delta));
   }
 
   ApplyPageScaleDeltaFromImplSide(info->page_scale_delta);
-  layer_tree_->SetElasticOverscrollFromImplSide(
-      layer_tree_->elastic_overscroll() + info->elastic_overscroll_delta);
+  SetElasticOverscrollFromImplSide(elastic_overscroll_ +
+                                   info->elastic_overscroll_delta);
   // TODO(ccameron): pass the elastic overscroll here so that input events
   // may be translated appropriately.
   client_->ApplyViewportDeltas(inner_viewport_scroll_delta, gfx::Vector2dF(),
@@ -733,9 +718,9 @@
     swap_promise_manager_.QueueSwapPromise(std::move(swap_promise));
   }
 
-  if (layer_tree_->root_layer()) {
+  if (root_layer_) {
     for (size_t i = 0; i < info->scrolls.size(); ++i) {
-      Layer* layer = layer_tree_->LayerById(info->scrolls[i].layer_id);
+      Layer* layer = LayerById(info->scrolls[i].layer_id);
       if (!layer)
         continue;
       layer->SetScrollOffsetFromImplSide(gfx::ScrollOffsetWithDelta(
@@ -743,7 +728,7 @@
       SetNeedsUpdateLayers();
     }
     for (size_t i = 0; i < info->scrollbars.size(); ++i) {
-      Layer* layer = layer_tree_->LayerById(info->scrollbars[i].layer_id);
+      Layer* layer = LayerById(info->scrollbars[i].layer_id);
       if (!layer)
         continue;
       layer->SetScrollbarsHiddenFromImplSide(info->scrollbars[i].hidden);
@@ -771,14 +756,13 @@
 }
 
 void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time) {
-  MutatorHost* mutator_host = layer_tree_->mutator_host();
-  std::unique_ptr<MutatorEvents> events = mutator_host->CreateEvents();
+  std::unique_ptr<MutatorEvents> events = mutator_host_->CreateEvents();
 
-  if (mutator_host->TickAnimations(monotonic_time))
-    mutator_host->UpdateAnimationState(true, events.get());
+  if (mutator_host_->TickAnimations(monotonic_time))
+    mutator_host_->UpdateAnimationState(true, events.get());
 
   if (!events->IsEmpty())
-    layer_tree_->property_trees()->needs_rebuild = true;
+    property_trees_.needs_rebuild = true;
 }
 
 int LayerTreeHost::ScheduleMicroBenchmark(
@@ -812,4 +796,466 @@
   return compositor_mode_ == CompositorMode::THREADED;
 }
 
+void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
+  if (root_layer_.get() == root_layer.get())
+    return;
+
+  if (root_layer_.get())
+    root_layer_->SetLayerTreeHost(nullptr);
+  root_layer_ = root_layer;
+  if (root_layer_.get()) {
+    DCHECK(!root_layer_->parent());
+    root_layer_->SetLayerTreeHost(this);
+  }
+
+  if (hud_layer_.get())
+    hud_layer_->RemoveFromParent();
+
+  // Reset gpu rasterization tracking.
+  // This flag is sticky until a new tree comes along.
+  ResetGpuRasterizationTracking();
+
+  SetNeedsFullTreeSync();
+}
+
+void LayerTreeHost::RegisterViewportLayers(
+    scoped_refptr<Layer> overscroll_elasticity_layer,
+    scoped_refptr<Layer> page_scale_layer,
+    scoped_refptr<Layer> inner_viewport_scroll_layer,
+    scoped_refptr<Layer> outer_viewport_scroll_layer) {
+  DCHECK(!inner_viewport_scroll_layer ||
+         inner_viewport_scroll_layer != outer_viewport_scroll_layer);
+  overscroll_elasticity_layer_ = overscroll_elasticity_layer;
+  page_scale_layer_ = page_scale_layer;
+  inner_viewport_scroll_layer_ = inner_viewport_scroll_layer;
+  outer_viewport_scroll_layer_ = outer_viewport_scroll_layer;
+}
+
+void LayerTreeHost::RegisterSelection(const LayerSelection& selection) {
+  if (selection_ == selection)
+    return;
+
+  selection_ = selection;
+  SetNeedsCommit();
+}
+
+void LayerTreeHost::SetHaveScrollEventHandlers(bool have_event_handlers) {
+  if (have_scroll_event_handlers_ == have_event_handlers)
+    return;
+
+  have_scroll_event_handlers_ = have_event_handlers;
+  SetNeedsCommit();
+}
+
+void LayerTreeHost::SetEventListenerProperties(
+    EventListenerClass event_class,
+    EventListenerProperties properties) {
+  const size_t index = static_cast<size_t>(event_class);
+  if (event_listener_properties_[index] == properties)
+    return;
+
+  event_listener_properties_[index] = properties;
+  SetNeedsCommit();
+}
+
+void LayerTreeHost::SetViewportSize(const gfx::Size& device_viewport_size) {
+  if (device_viewport_size_ == device_viewport_size)
+    return;
+
+  device_viewport_size_ = device_viewport_size;
+
+  SetPropertyTreesNeedRebuild();
+  SetNeedsCommit();
+}
+
+void LayerTreeHost::SetBrowserControlsHeight(float height, bool shrink) {
+  if (top_controls_height_ == height &&
+      browser_controls_shrink_blink_size_ == shrink)
+    return;
+
+  top_controls_height_ = height;
+  browser_controls_shrink_blink_size_ = shrink;
+  SetNeedsCommit();
+}
+
+void LayerTreeHost::SetBrowserControlsShownRatio(float ratio) {
+  if (top_controls_shown_ratio_ == ratio)
+    return;
+
+  top_controls_shown_ratio_ = ratio;
+  SetNeedsCommit();
+}
+
+void LayerTreeHost::SetBottomControlsHeight(float height) {
+  if (bottom_controls_height_ == height)
+    return;
+
+  bottom_controls_height_ = height;
+  SetNeedsCommit();
+}
+
+void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor,
+                                                float min_page_scale_factor,
+                                                float max_page_scale_factor) {
+  if (page_scale_factor_ == page_scale_factor &&
+      min_page_scale_factor_ == min_page_scale_factor &&
+      max_page_scale_factor_ == max_page_scale_factor)
+    return;
+
+  page_scale_factor_ = page_scale_factor;
+  min_page_scale_factor_ = min_page_scale_factor;
+  max_page_scale_factor_ = max_page_scale_factor;
+  SetPropertyTreesNeedRebuild();
+  SetNeedsCommit();
+}
+
+void LayerTreeHost::StartPageScaleAnimation(const gfx::Vector2d& target_offset,
+                                            bool use_anchor,
+                                            float scale,
+                                            base::TimeDelta duration) {
+  pending_page_scale_animation_.reset(new PendingPageScaleAnimation(
+      target_offset, use_anchor, scale, duration));
+
+  SetNeedsCommit();
+}
+
+bool LayerTreeHost::HasPendingPageScaleAnimation() const {
+  return !!pending_page_scale_animation_.get();
+}
+
+void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor) {
+  if (device_scale_factor_ == device_scale_factor)
+    return;
+  device_scale_factor_ = device_scale_factor;
+
+  property_trees_.needs_rebuild = true;
+  SetNeedsCommit();
+}
+
+void LayerTreeHost::SetPaintedDeviceScaleFactor(
+    float painted_device_scale_factor) {
+  if (painted_device_scale_factor_ == painted_device_scale_factor)
+    return;
+  painted_device_scale_factor_ = painted_device_scale_factor;
+
+  SetNeedsCommit();
+}
+
+void LayerTreeHost::SetDeviceColorSpace(
+    const gfx::ColorSpace& device_color_space) {
+  if (device_color_space_ == device_color_space)
+    return;
+  device_color_space_ = device_color_space;
+  LayerTreeHostCommon::CallFunctionForEveryLayer(
+      this, [](Layer* layer) { layer->SetNeedsDisplay(); });
+}
+
+void LayerTreeHost::RegisterLayer(Layer* layer) {
+  DCHECK(!LayerById(layer->id()));
+  DCHECK(!in_paint_layer_contents_);
+  layer_id_map_[layer->id()] = layer;
+  if (layer->element_id()) {
+    mutator_host_->RegisterElement(layer->element_id(),
+                                   ElementListType::ACTIVE);
+  }
+}
+
+void LayerTreeHost::UnregisterLayer(Layer* layer) {
+  DCHECK(LayerById(layer->id()));
+  DCHECK(!in_paint_layer_contents_);
+  if (layer->element_id()) {
+    mutator_host_->UnregisterElement(layer->element_id(),
+                                     ElementListType::ACTIVE);
+  }
+  RemoveLayerShouldPushProperties(layer);
+  layer_id_map_.erase(layer->id());
+}
+
+Layer* LayerTreeHost::LayerById(int id) const {
+  auto iter = layer_id_map_.find(id);
+  return iter != layer_id_map_.end() ? iter->second : nullptr;
+}
+
+size_t LayerTreeHost::NumLayers() const {
+  return layer_id_map_.size();
+}
+
+bool LayerTreeHost::UpdateLayers(const LayerList& update_layer_list,
+                                 bool* content_is_suitable_for_gpu) {
+  base::AutoReset<bool> painting(&in_paint_layer_contents_, true);
+  bool did_paint_content = false;
+  for (const auto& layer : update_layer_list) {
+    did_paint_content |= layer->Update();
+    *content_is_suitable_for_gpu &= layer->IsSuitableForGpuRasterization();
+  }
+  return did_paint_content;
+}
+
+void LayerTreeHost::AddLayerShouldPushProperties(Layer* layer) {
+  layers_that_should_push_properties_.insert(layer);
+}
+
+void LayerTreeHost::RemoveLayerShouldPushProperties(Layer* layer) {
+  layers_that_should_push_properties_.erase(layer);
+}
+
+std::unordered_set<Layer*>& LayerTreeHost::LayersThatShouldPushProperties() {
+  return layers_that_should_push_properties_;
+}
+
+bool LayerTreeHost::LayerNeedsPushPropertiesForTesting(Layer* layer) const {
+  return layers_that_should_push_properties_.find(layer) !=
+         layers_that_should_push_properties_.end();
+}
+
+void LayerTreeHost::SetNeedsMetaInfoRecomputation(bool needs_recomputation) {
+  needs_meta_info_recomputation_ = needs_recomputation;
+}
+
+void LayerTreeHost::SetPageScaleFromImplSide(float page_scale) {
+  DCHECK(CommitRequested());
+  page_scale_factor_ = page_scale;
+  SetPropertyTreesNeedRebuild();
+}
+
+void LayerTreeHost::SetElasticOverscrollFromImplSide(
+    gfx::Vector2dF elastic_overscroll) {
+  DCHECK(CommitRequested());
+  elastic_overscroll_ = elastic_overscroll;
+}
+
+void LayerTreeHost::UpdateHudLayer(bool show_hud_info) {
+  if (show_hud_info) {
+    if (!hud_layer_.get()) {
+      hud_layer_ = HeadsUpDisplayLayer::Create();
+    }
+
+    if (root_layer_.get() && !hud_layer_->parent())
+      root_layer_->AddChild(hud_layer_);
+  } else if (hud_layer_.get()) {
+    hud_layer_->RemoveFromParent();
+    hud_layer_ = nullptr;
+  }
+}
+
+void LayerTreeHost::SetNeedsFullTreeSync() {
+  needs_full_tree_sync_ = true;
+  needs_meta_info_recomputation_ = true;
+
+  property_trees_.needs_rebuild = true;
+  SetNeedsCommit();
+}
+
+void LayerTreeHost::SetPropertyTreesNeedRebuild() {
+  property_trees_.needs_rebuild = true;
+  SetNeedsUpdateLayers();
+}
+
+void LayerTreeHost::PushPropertiesTo(LayerTreeImpl* tree_impl) {
+  tree_impl->set_needs_full_tree_sync(needs_full_tree_sync_);
+  needs_full_tree_sync_ = false;
+
+  if (hud_layer_.get()) {
+    LayerImpl* hud_impl = tree_impl->LayerById(hud_layer_->id());
+    tree_impl->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl));
+  } else {
+    tree_impl->set_hud_layer(nullptr);
+  }
+
+  tree_impl->set_background_color(background_color_);
+  tree_impl->set_has_transparent_background(has_transparent_background_);
+  tree_impl->set_have_scroll_event_handlers(have_scroll_event_handlers_);
+  tree_impl->set_event_listener_properties(
+      EventListenerClass::kTouchStartOrMove,
+      event_listener_properties(EventListenerClass::kTouchStartOrMove));
+  tree_impl->set_event_listener_properties(
+      EventListenerClass::kMouseWheel,
+      event_listener_properties(EventListenerClass::kMouseWheel));
+  tree_impl->set_event_listener_properties(
+      EventListenerClass::kTouchEndOrCancel,
+      event_listener_properties(EventListenerClass::kTouchEndOrCancel));
+
+  if (page_scale_layer_ && inner_viewport_scroll_layer_) {
+    tree_impl->SetViewportLayersFromIds(
+        overscroll_elasticity_layer_ ? overscroll_elasticity_layer_->id()
+                                     : Layer::INVALID_ID,
+        page_scale_layer_->id(), inner_viewport_scroll_layer_->id(),
+        outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id()
+                                     : Layer::INVALID_ID);
+    DCHECK(inner_viewport_scroll_layer_->IsContainerForFixedPositionLayers());
+  } else {
+    tree_impl->ClearViewportLayers();
+  }
+
+  tree_impl->RegisterSelection(selection_);
+
+  bool property_trees_changed_on_active_tree =
+      tree_impl->IsActiveTree() && tree_impl->property_trees()->changed;
+  // Property trees may store damage status. We preserve the sync tree damage
+  // status by pushing the damage status from sync tree property trees to main
+  // thread property trees or by moving it onto the layers.
+  if (root_layer_ && property_trees_changed_on_active_tree) {
+    if (property_trees_.sequence_number ==
+        tree_impl->property_trees()->sequence_number)
+      tree_impl->property_trees()->PushChangeTrackingTo(&property_trees_);
+    else
+      tree_impl->MoveChangeTrackingToLayers();
+  }
+  // Setting property trees must happen before pushing the page scale.
+  tree_impl->SetPropertyTrees(&property_trees_);
+
+  tree_impl->PushPageScaleFromMainThread(
+      page_scale_factor_, min_page_scale_factor_, max_page_scale_factor_);
+
+  tree_impl->set_browser_controls_shrink_blink_size(
+      browser_controls_shrink_blink_size_);
+  tree_impl->set_top_controls_height(top_controls_height_);
+  tree_impl->set_bottom_controls_height(bottom_controls_height_);
+  tree_impl->PushBrowserControlsFromMainThread(top_controls_shown_ratio_);
+  tree_impl->elastic_overscroll()->PushFromMainThread(elastic_overscroll_);
+  if (tree_impl->IsActiveTree())
+    tree_impl->elastic_overscroll()->PushPendingToActive();
+
+  tree_impl->set_painted_device_scale_factor(painted_device_scale_factor_);
+
+  tree_impl->SetDeviceColorSpace(device_color_space_);
+
+  if (pending_page_scale_animation_) {
+    tree_impl->SetPendingPageScaleAnimation(
+        std::move(pending_page_scale_animation_));
+  }
+
+  DCHECK(!tree_impl->ViewportSizeInvalid());
+
+  tree_impl->set_has_ever_been_drawn(false);
+}
+
+Layer* LayerTreeHost::LayerByElementId(ElementId element_id) const {
+  auto iter = element_layers_map_.find(element_id);
+  return iter != element_layers_map_.end() ? iter->second : nullptr;
+}
+
+void LayerTreeHost::RegisterElement(ElementId element_id,
+                                    ElementListType list_type,
+                                    Layer* layer) {
+  if (layer->element_id()) {
+    element_layers_map_[layer->element_id()] = layer;
+  }
+
+  mutator_host_->RegisterElement(element_id, list_type);
+}
+
+void LayerTreeHost::UnregisterElement(ElementId element_id,
+                                      ElementListType list_type,
+                                      Layer* layer) {
+  mutator_host_->UnregisterElement(element_id, list_type);
+
+  if (layer->element_id()) {
+    element_layers_map_.erase(layer->element_id());
+  }
+}
+
+static void SetElementIdForTesting(Layer* layer) {
+  layer->SetElementId(LayerIdToElementIdForTesting(layer->id()));
+}
+
+void LayerTreeHost::SetElementIdsForTesting() {
+  LayerTreeHostCommon::CallFunctionForEveryLayer(this, SetElementIdForTesting);
+}
+
+void LayerTreeHost::BuildPropertyTreesForTesting() {
+  PropertyTreeBuilder::PreCalculateMetaInformation(root_layer());
+  gfx::Transform identity_transform;
+  PropertyTreeBuilder::BuildPropertyTrees(
+      root_layer(), page_scale_layer(), inner_viewport_scroll_layer(),
+      outer_viewport_scroll_layer(), overscroll_elasticity_layer(),
+      elastic_overscroll(), page_scale_factor(), device_scale_factor(),
+      gfx::Rect(device_viewport_size()), identity_transform, property_trees());
+}
+
+bool LayerTreeHost::IsElementInList(ElementId element_id,
+                                    ElementListType list_type) const {
+  return list_type == ElementListType::ACTIVE && LayerByElementId(element_id);
+}
+
+void LayerTreeHost::SetMutatorsNeedCommit() {
+  SetNeedsCommit();
+}
+
+void LayerTreeHost::SetMutatorsNeedRebuildPropertyTrees() {
+  property_trees_.needs_rebuild = true;
+}
+
+void LayerTreeHost::SetElementFilterMutated(ElementId element_id,
+                                            ElementListType list_type,
+                                            const FilterOperations& filters) {
+  Layer* layer = LayerByElementId(element_id);
+  DCHECK(layer);
+  layer->OnFilterAnimated(filters);
+}
+
+void LayerTreeHost::SetElementOpacityMutated(ElementId element_id,
+                                             ElementListType list_type,
+                                             float opacity) {
+  Layer* layer = LayerByElementId(element_id);
+  DCHECK(layer);
+  layer->OnOpacityAnimated(opacity);
+}
+
+void LayerTreeHost::SetElementTransformMutated(
+    ElementId element_id,
+    ElementListType list_type,
+    const gfx::Transform& transform) {
+  Layer* layer = LayerByElementId(element_id);
+  DCHECK(layer);
+  layer->OnTransformAnimated(transform);
+}
+
+void LayerTreeHost::SetElementScrollOffsetMutated(
+    ElementId element_id,
+    ElementListType list_type,
+    const gfx::ScrollOffset& scroll_offset) {
+  Layer* layer = LayerByElementId(element_id);
+  DCHECK(layer);
+  layer->OnScrollOffsetAnimated(scroll_offset);
+}
+
+void LayerTreeHost::ElementIsAnimatingChanged(
+    ElementId element_id,
+    ElementListType list_type,
+    const PropertyAnimationState& mask,
+    const PropertyAnimationState& state) {
+  Layer* layer = LayerByElementId(element_id);
+  if (layer)
+    layer->OnIsAnimatingChanged(mask, state);
+}
+
+gfx::ScrollOffset LayerTreeHost::GetScrollOffsetForAnimation(
+    ElementId element_id) const {
+  Layer* layer = LayerByElementId(element_id);
+  DCHECK(layer);
+  return layer->ScrollOffsetForAnimation();
+}
+
+LayerListIterator<Layer> LayerTreeHost::begin() const {
+  return LayerListIterator<Layer>(root_layer_.get());
+}
+
+LayerListIterator<Layer> LayerTreeHost::end() const {
+  return LayerListIterator<Layer>(nullptr);
+}
+
+LayerListReverseIterator<Layer> LayerTreeHost::rbegin() {
+  return LayerListReverseIterator<Layer>(root_layer_.get());
+}
+
+LayerListReverseIterator<Layer> LayerTreeHost::rend() {
+  return LayerListReverseIterator<Layer>(nullptr);
+}
+
+void LayerTreeHost::SetNeedsDisplayOnAllLayers() {
+  for (auto* layer : *this)
+    layer->SetNeedsDisplay();
+}
+
 }  // namespace cc
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index 7beade4..05c0601 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -36,9 +36,9 @@
 #include "cc/surfaces/surface_reference_owner.h"
 #include "cc/surfaces/surface_sequence_generator.h"
 #include "cc/trees/compositor_mode.h"
-#include "cc/trees/layer_tree.h"
 #include "cc/trees/layer_tree_host_client.h"
 #include "cc/trees/layer_tree_settings.h"
+#include "cc/trees/mutator_host.h"
 #include "cc/trees/proxy.h"
 #include "cc/trees/swap_promise_manager.h"
 #include "cc/trees/target_property.h"
@@ -46,22 +46,24 @@
 #include "ui/gfx/geometry/rect.h"
 
 namespace cc {
-class MutatorEvents;
+class HeadsUpDisplayLayer;
 class Layer;
 class LayerTreeHostClient;
 class LayerTreeHostImpl;
 class LayerTreeHostImplClient;
 class LayerTreeHostSingleThreadClient;
 class LayerTreeMutator;
+class MutatorEvents;
 class MutatorHost;
+struct PendingPageScaleAnimation;
 class RenderingStatsInstrumentation;
 class TaskGraphRunner;
 class UIResourceManager;
 struct RenderingStats;
 struct ScrollAndScaleSet;
 
-class CC_EXPORT LayerTreeHost
-    : public NON_EXPORTED_BASE(SurfaceReferenceOwner) {
+class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner),
+                                public NON_EXPORTED_BASE(MutatorHostClient) {
  public:
   // TODO(sad): InitParams should be a movable type so that it can be
   // std::move()d to the Create* functions.
@@ -94,11 +96,6 @@
   // update(commit) pushed to the compositor thread.
   int SourceFrameNumber() const;
 
-  // Returns the LayerTree that holds the main frame state pushed to the
-  // LayerTreeImpl on commit.
-  LayerTree* GetLayerTree();
-  const LayerTree* GetLayerTree() const;
-
   // Returns the UIResourceManager used to create UIResources for
   // UIResourceLayers pushed to the LayerTree.
   UIResourceManager* GetUIResourceManager() const;
@@ -235,8 +232,143 @@
   // Calling this will reset it back to not suitable state.
   void ResetGpuRasterizationTracking();
 
-  // SurfaceReferenceOwner implementation.
-  SurfaceSequenceGenerator* GetSurfaceSequenceGenerator() override;
+  void SetRootLayer(scoped_refptr<Layer> root_layer);
+  Layer* root_layer() { return root_layer_.get(); }
+  const Layer* root_layer() const { return root_layer_.get(); }
+
+  void RegisterViewportLayers(scoped_refptr<Layer> overscroll_elasticity_layer,
+                              scoped_refptr<Layer> page_scale_layer,
+                              scoped_refptr<Layer> inner_viewport_scroll_layer,
+                              scoped_refptr<Layer> outer_viewport_scroll_layer);
+
+  Layer* overscroll_elasticity_layer() const {
+    return overscroll_elasticity_layer_.get();
+  }
+  Layer* page_scale_layer() const { return page_scale_layer_.get(); }
+  Layer* inner_viewport_scroll_layer() const {
+    return inner_viewport_scroll_layer_.get();
+  }
+  Layer* outer_viewport_scroll_layer() const {
+    return outer_viewport_scroll_layer_.get();
+  }
+
+  void RegisterSelection(const LayerSelection& selection);
+  const LayerSelection& selection() const { return selection_; }
+
+  void SetHaveScrollEventHandlers(bool have_event_handlers);
+  bool have_scroll_event_handlers() const {
+    return have_scroll_event_handlers_;
+  }
+
+  void SetEventListenerProperties(EventListenerClass event_class,
+                                  EventListenerProperties event_properties);
+  EventListenerProperties event_listener_properties(
+      EventListenerClass event_class) const {
+    return event_listener_properties_[static_cast<size_t>(event_class)];
+  }
+
+  void SetViewportSize(const gfx::Size& device_viewport_size);
+  gfx::Size device_viewport_size() const { return device_viewport_size_; }
+
+  void SetBrowserControlsHeight(float height, bool shrink);
+  void SetBrowserControlsShownRatio(float ratio);
+  void SetBottomControlsHeight(float height);
+
+  void SetPageScaleFactorAndLimits(float page_scale_factor,
+                                   float min_page_scale_factor,
+                                   float max_page_scale_factor);
+  float page_scale_factor() const { return page_scale_factor_; }
+  float min_page_scale_factor() const { return min_page_scale_factor_; }
+  float max_page_scale_factor() const { return max_page_scale_factor_; }
+
+  void set_background_color(SkColor color) { background_color_ = color; }
+  SkColor background_color() const { return background_color_; }
+
+  void set_has_transparent_background(bool transparent) {
+    has_transparent_background_ = transparent;
+  }
+  bool has_transparent_background() const {
+    return has_transparent_background_;
+  }
+
+  void StartPageScaleAnimation(const gfx::Vector2d& target_offset,
+                               bool use_anchor,
+                               float scale,
+                               base::TimeDelta duration);
+  bool HasPendingPageScaleAnimation() const;
+
+  void SetDeviceScaleFactor(float device_scale_factor);
+  float device_scale_factor() const { return device_scale_factor_; }
+
+  void SetPaintedDeviceScaleFactor(float painted_device_scale_factor);
+  float painted_device_scale_factor() const {
+    return painted_device_scale_factor_;
+  }
+
+  void SetDeviceColorSpace(const gfx::ColorSpace& device_color_space);
+  const gfx::ColorSpace& device_color_space() const {
+    return device_color_space_;
+  }
+
+  // Used externally by blink for setting the PropertyTrees when
+  // |settings_.use_layer_lists| is true. This is a SPV2 setting.
+  PropertyTrees* property_trees() { return &property_trees_; }
+
+  void SetNeedsDisplayOnAllLayers();
+
+  void RegisterLayer(Layer* layer);
+  void UnregisterLayer(Layer* layer);
+  Layer* LayerById(int id) const;
+
+  size_t NumLayers() const;
+
+  bool UpdateLayers(const LayerList& update_layer_list,
+                    bool* content_is_suitable_for_gpu);
+  bool in_paint_layer_contents() const { return in_paint_layer_contents_; }
+
+  void AddLayerShouldPushProperties(Layer* layer);
+  void RemoveLayerShouldPushProperties(Layer* layer);
+  std::unordered_set<Layer*>& LayersThatShouldPushProperties();
+  bool LayerNeedsPushPropertiesForTesting(Layer* layer) const;
+
+  virtual void SetNeedsMetaInfoRecomputation(
+      bool needs_meta_info_recomputation);
+  bool needs_meta_info_recomputation() const {
+    return needs_meta_info_recomputation_;
+  }
+
+  void SetPageScaleFromImplSide(float page_scale);
+  void SetElasticOverscrollFromImplSide(gfx::Vector2dF elastic_overscroll);
+  gfx::Vector2dF elastic_overscroll() const { return elastic_overscroll_; }
+
+  void UpdateHudLayer(bool show_hud_info);
+  HeadsUpDisplayLayer* hud_layer() const { return hud_layer_.get(); }
+
+  virtual void SetNeedsFullTreeSync();
+  bool needs_full_tree_sync() const { return needs_full_tree_sync_; }
+
+  void SetPropertyTreesNeedRebuild();
+
+  void PushPropertiesTo(LayerTreeImpl* tree_impl);
+
+  MutatorHost* mutator_host() const { return mutator_host_; }
+
+  Layer* LayerByElementId(ElementId element_id) const;
+  void RegisterElement(ElementId element_id,
+                       ElementListType list_type,
+                       Layer* layer);
+  void UnregisterElement(ElementId element_id,
+                         ElementListType list_type,
+                         Layer* layer);
+  void SetElementIdsForTesting();
+
+  void BuildPropertyTreesForTesting();
+
+  // Layer iterators.
+  LayerListIterator<Layer> begin() const;
+  LayerListIterator<Layer> end() const;
+  LayerListReverseIterator<Layer> rbegin();
+  LayerListReverseIterator<Layer> rend();
 
   // LayerTreeHostInProcess interface to Proxy.
   void WillBeginMainFrame();
@@ -286,11 +418,38 @@
   bool IsSingleThreaded() const;
   bool IsThreaded() const;
 
+  // SurfaceReferenceOwner implementation.
+  SurfaceSequenceGenerator* GetSurfaceSequenceGenerator() override;
+
+  // MutatorHostClient implementation.
+  bool IsElementInList(ElementId element_id,
+                       ElementListType list_type) const override;
+  void SetMutatorsNeedCommit() override;
+  void SetMutatorsNeedRebuildPropertyTrees() override;
+  void SetElementFilterMutated(ElementId element_id,
+                               ElementListType list_type,
+                               const FilterOperations& filters) override;
+  void SetElementOpacityMutated(ElementId element_id,
+                                ElementListType list_type,
+                                float opacity) override;
+  void SetElementTransformMutated(ElementId element_id,
+                                  ElementListType list_type,
+                                  const gfx::Transform& transform) override;
+  void SetElementScrollOffsetMutated(
+      ElementId element_id,
+      ElementListType list_type,
+      const gfx::ScrollOffset& scroll_offset) override;
+
+  void ElementIsAnimatingChanged(ElementId element_id,
+                                 ElementListType list_type,
+                                 const PropertyAnimationState& mask,
+                                 const PropertyAnimationState& state) override;
+
+  void ScrollOffsetAnimationFinished() override {}
+  gfx::ScrollOffset GetScrollOffsetForAnimation(
+      ElementId element_id) const override;
+
  protected:
-  // Allow tests to inject the LayerTree.
-  LayerTreeHost(InitParams* params,
-                CompositorMode mode,
-                std::unique_ptr<LayerTree> layer_tree);
   LayerTreeHost(InitParams* params, CompositorMode mode);
 
   void InitializeThreaded(
@@ -317,8 +476,6 @@
 
   MicroBenchmarkController micro_benchmark_controller_;
 
-  std::unique_ptr<LayerTree> layer_tree_;
-
   base::WeakPtr<InputHandler> input_handler_weak_ptr_;
 
  private:
@@ -339,8 +496,6 @@
 
   void CalculateLCDTextMetricsCallback(Layer* layer);
 
-  void SetPropertyTreesNeedRebuild();
-
   const CompositorMode compositor_mode_;
 
   std::unique_ptr<UIResourceManager> ui_resource_manager_;
@@ -349,7 +504,7 @@
   std::unique_ptr<Proxy> proxy_;
   std::unique_ptr<TaskRunnerProvider> task_runner_provider_;
 
-  int source_frame_number_;
+  int source_frame_number_ = 0U;
   std::unique_ptr<RenderingStatsInstrumentation>
       rendering_stats_instrumentation_;
 
@@ -366,15 +521,15 @@
   const LayerTreeSettings settings_;
   LayerTreeDebugState debug_state_;
 
-  bool visible_;
+  bool visible_ = false;
 
-  bool has_gpu_rasterization_trigger_;
-  bool content_is_suitable_for_gpu_rasterization_;
-  bool gpu_rasterization_histogram_recorded_;
+  bool has_gpu_rasterization_trigger_ = false;
+  bool content_is_suitable_for_gpu_rasterization_ = true;
+  bool gpu_rasterization_histogram_recorded_ = false;
 
   // If set, then page scale animation has completed, but the client hasn't been
   // notified about it yet.
-  bool did_complete_scale_animation_;
+  bool did_complete_scale_animation_ = false;
 
   int id_;
   bool next_commit_forces_redraw_ = false;
@@ -388,6 +543,60 @@
   SurfaceSequenceGenerator surface_sequence_generator_;
   uint32_t num_consecutive_frames_suitable_for_gpu_ = 0;
 
+  scoped_refptr<Layer> root_layer_;
+
+  scoped_refptr<Layer> overscroll_elasticity_layer_;
+  scoped_refptr<Layer> page_scale_layer_;
+  scoped_refptr<Layer> inner_viewport_scroll_layer_;
+  scoped_refptr<Layer> outer_viewport_scroll_layer_;
+
+  float top_controls_height_ = 0.f;
+  float top_controls_shown_ratio_ = 0.f;
+  bool browser_controls_shrink_blink_size_ = false;
+
+  float bottom_controls_height_ = 0.f;
+
+  float device_scale_factor_ = 1.f;
+  float painted_device_scale_factor_ = 1.f;
+  float page_scale_factor_ = 1.f;
+  float min_page_scale_factor_ = 1.f;
+  float max_page_scale_factor_ = 1.f;
+  gfx::ColorSpace device_color_space_;
+
+  SkColor background_color_ = SK_ColorWHITE;
+  bool has_transparent_background_ = false;
+
+  LayerSelection selection_;
+
+  gfx::Size device_viewport_size_;
+
+  bool have_scroll_event_handlers_ = false;
+  EventListenerProperties event_listener_properties_[static_cast<size_t>(
+      EventListenerClass::kNumClasses)];
+
+  std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation_;
+
+  PropertyTrees property_trees_;
+
+  bool needs_full_tree_sync_ = true;
+  bool needs_meta_info_recomputation_ = true;
+
+  gfx::Vector2dF elastic_overscroll_;
+
+  scoped_refptr<HeadsUpDisplayLayer> hud_layer_;
+
+  // Set of layers that need to push properties.
+  std::unordered_set<Layer*> layers_that_should_push_properties_;
+
+  // Layer id to Layer map.
+  std::unordered_map<int, Layer*> layer_id_map_;
+
+  std::unordered_map<ElementId, Layer*, ElementIdHash> element_layers_map_;
+
+  bool in_paint_layer_contents_ = false;
+
+  MutatorHost* mutator_host_;
+
   scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner_;
 
   DISALLOW_COPY_AND_ASSIGN(LayerTreeHost);
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index e7c1f0f..d9c7194 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -573,7 +573,7 @@
   LayerList update_layer_list;
   bool can_render_to_separate_surface = true;
   PropertyTrees* property_trees =
-      inputs->root_layer->GetLayerTree()->property_trees();
+      inputs->root_layer->layer_tree_host()->property_trees();
   Layer* overscroll_elasticity_layer = nullptr;
   gfx::Vector2dF elastic_overscroll;
   PropertyTreeBuilder::BuildPropertyTrees(
@@ -586,7 +586,8 @@
   draw_property_utils::UpdatePropertyTrees(property_trees,
                                            can_render_to_separate_surface);
   draw_property_utils::FindLayersThatNeedUpdates(
-      inputs->root_layer->GetLayerTree(), property_trees, &update_layer_list);
+      inputs->root_layer->layer_tree_host(), property_trees,
+      &update_layer_list);
 }
 
 void LayerTreeHostCommon::CalculateDrawProperties(
@@ -646,7 +647,7 @@
 }
 
 PropertyTrees* GetPropertyTrees(Layer* layer) {
-  return layer->GetLayerTree()->property_trees();
+  return layer->layer_tree_host()->property_trees();
 }
 
 PropertyTrees* GetPropertyTrees(LayerImpl* layer) {
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h
index cdf5569..de96d95 100644
--- a/cc/trees/layer_tree_host_common.h
+++ b/cc/trees/layer_tree_host_common.h
@@ -127,7 +127,7 @@
       CalcDrawPropsImplInputsForTesting* inputs);
 
   template <typename Function>
-  static void CallFunctionForEveryLayer(LayerTree* layer,
+  static void CallFunctionForEveryLayer(LayerTreeHost* host,
                                         const Function& function);
 
   template <typename Function>
@@ -183,7 +183,7 @@
 };
 
 template <typename Function>
-void LayerTreeHostCommon::CallFunctionForEveryLayer(LayerTree* host,
+void LayerTreeHostCommon::CallFunctionForEveryLayer(LayerTreeHost* host,
                                                     const Function& function) {
   for (auto* layer : *host) {
     function(layer);
diff --git a/cc/trees/layer_tree_host_common_perftest.cc b/cc/trees/layer_tree_host_common_perftest.cc
index 23f7c4f..132872c 100644
--- a/cc/trees/layer_tree_host_common_perftest.cc
+++ b/cc/trees/layer_tree_host_common_perftest.cc
@@ -48,11 +48,11 @@
 
   void SetupTree() override {
     gfx::Size viewport = gfx::Size(720, 1038);
-    layer_tree()->SetViewportSize(viewport);
+    layer_tree_host()->SetViewportSize(viewport);
     scoped_refptr<Layer> root =
         ParseTreeFromJson(json_, &content_layer_client_);
     ASSERT_TRUE(root.get());
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     content_layer_client_.set_bounds(viewport);
   }
 
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 09b1dfc..96939835 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -188,28 +188,28 @@
   const LayerList* GetUpdateLayerList() { return &update_layer_list_; }
 
   void ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(Layer* root_layer) {
-    DCHECK(root_layer->GetLayerTree());
+    DCHECK(root_layer->layer_tree_host());
     PropertyTreeBuilder::PreCalculateMetaInformation(root_layer);
 
     bool can_render_to_separate_surface = true;
 
     const Layer* page_scale_layer =
-        root_layer->GetLayerTree()->page_scale_layer();
+        root_layer->layer_tree_host()->page_scale_layer();
     Layer* inner_viewport_scroll_layer =
-        root_layer->GetLayerTree()->inner_viewport_scroll_layer();
+        root_layer->layer_tree_host()->inner_viewport_scroll_layer();
     Layer* outer_viewport_scroll_layer =
-        root_layer->GetLayerTree()->outer_viewport_scroll_layer();
+        root_layer->layer_tree_host()->outer_viewport_scroll_layer();
     const Layer* overscroll_elasticity_layer =
-        root_layer->GetLayerTree()->overscroll_elasticity_layer();
+        root_layer->layer_tree_host()->overscroll_elasticity_layer();
     gfx::Vector2dF elastic_overscroll =
-        root_layer->GetLayerTree()->elastic_overscroll();
+        root_layer->layer_tree_host()->elastic_overscroll();
     float page_scale_factor = 1.f;
     float device_scale_factor = 1.f;
     gfx::Size device_viewport_size =
         gfx::Size(root_layer->bounds().width() * device_scale_factor,
                   root_layer->bounds().height() * device_scale_factor);
     PropertyTrees* property_trees =
-        root_layer->GetLayerTree()->property_trees();
+        root_layer->layer_tree_host()->property_trees();
     update_layer_list_.clear();
     PropertyTreeBuilder::BuildPropertyTrees(
         root_layer, page_scale_layer, inner_viewport_scroll_layer,
@@ -219,7 +219,7 @@
     draw_property_utils::UpdatePropertyTrees(property_trees,
                                              can_render_to_separate_surface);
     draw_property_utils::FindLayersThatNeedUpdates(
-        root_layer->GetLayerTree(), property_trees, &update_layer_list_);
+        root_layer->layer_tree_host(), property_trees, &update_layer_list_);
   }
 
   void ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(
@@ -5007,12 +5007,11 @@
   host()->SetRootLayer(root);
 
   int nonexistent_id = -1;
-  LayerTree* layer_tree = host()->GetLayerTree();
-  EXPECT_EQ(root.get(), layer_tree->LayerById(root->id()));
-  EXPECT_EQ(child.get(), layer_tree->LayerById(child->id()));
-  EXPECT_EQ(grand_child.get(), layer_tree->LayerById(grand_child->id()));
-  EXPECT_EQ(mask_layer.get(), layer_tree->LayerById(mask_layer->id()));
-  EXPECT_FALSE(layer_tree->LayerById(nonexistent_id));
+  EXPECT_EQ(root.get(), host()->LayerById(root->id()));
+  EXPECT_EQ(child.get(), host()->LayerById(child->id()));
+  EXPECT_EQ(grand_child.get(), host()->LayerById(grand_child->id()));
+  EXPECT_EQ(mask_layer.get(), host()->LayerById(mask_layer->id()));
+  EXPECT_FALSE(host()->LayerById(nonexistent_id));
 }
 
 TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) {
@@ -7319,8 +7318,7 @@
   scroller->AddChild(sticky_pos);
   host()->SetRootLayer(root);
   scroller->SetScrollClipLayerId(root->id());
-  host()->GetLayerTree()->RegisterViewportLayers(nullptr, root, scroller,
-                                                 nullptr);
+  host()->RegisterViewportLayers(nullptr, root, scroller, nullptr);
 
   LayerStickyPositionConstraint sticky_position;
   sticky_position.is_sticky = true;
@@ -7393,8 +7391,7 @@
   host()->SetRootLayer(root);
   scroller->SetScrollClipLayerId(root->id());
   outer_viewport->SetScrollClipLayerId(outer_clip->id());
-  host()->GetLayerTree()->RegisterViewportLayers(nullptr, root, scroller,
-                                                 outer_viewport);
+  host()->RegisterViewportLayers(nullptr, root, scroller, outer_viewport);
 
   LayerStickyPositionConstraint sticky_position;
   sticky_position.is_sticky = true;
@@ -7939,7 +7936,8 @@
   container->SetTransform(rotate);
 
   ExecuteCalculateDrawProperties(root.get());
-  TransformTree& tree = root->GetLayerTree()->property_trees()->transform_tree;
+  TransformTree& tree =
+      root->layer_tree_host()->property_trees()->transform_tree;
   gfx::Transform transform;
   tree.ComputeTranslation(fixed_pos->transform_tree_index(),
                           container->transform_tree_index(), &transform);
@@ -8843,8 +8841,8 @@
   outer_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true);
 
   host()->SetRootLayer(root);
-  host()->GetLayerTree()->RegisterViewportLayers(
-      nullptr, root, inner_viewport_scroll_layer, outer_viewport_scroll_layer);
+  host()->RegisterViewportLayers(nullptr, root, inner_viewport_scroll_layer,
+                                 outer_viewport_scroll_layer);
 
   scoped_refptr<Layer> fixed_to_inner = Layer::Create();
   scoped_refptr<Layer> fixed_to_outer = Layer::Create();
@@ -9328,7 +9326,7 @@
   child->AddChild(grandchild);
   grandchild->AddChild(greatgrandchild);
   host()->SetRootLayer(root);
-  host()->GetLayerTree()->SetElementIdsForTesting();
+  host()->SetElementIdsForTesting();
 
   // Check the non-skipped case.
   ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get());
@@ -10466,7 +10464,7 @@
       make_scoped_refptr(new LayerWithForcedDrawsContent());
   root->AddChild(animated);
   host()->SetRootLayer(root);
-  host()->GetLayerTree()->SetElementIdsForTesting();
+  host()->SetElementIdsForTesting();
 
   root->SetBounds(gfx::Size(100, 100));
   root->SetForceRenderSurfaceForTesting(true);
@@ -10491,7 +10489,7 @@
 
   ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get());
 
-  EffectTree& tree = root->GetLayerTree()->property_trees()->effect_tree;
+  EffectTree& tree = root->layer_tree_host()->property_trees()->effect_tree;
   EffectNode* node = tree.Node(animated->effect_tree_index());
   EXPECT_FALSE(node->is_currently_animating_opacity);
   EXPECT_TRUE(node->has_potential_opacity_animation);
@@ -10515,7 +10513,7 @@
       make_scoped_refptr(new LayerWithForcedDrawsContent());
   root->AddChild(animated);
   host()->SetRootLayer(root);
-  host()->GetLayerTree()->SetElementIdsForTesting();
+  host()->SetElementIdsForTesting();
 
   root->SetBounds(gfx::Size(100, 100));
   root->SetForceRenderSurfaceForTesting(true);
@@ -10548,7 +10546,8 @@
 
   ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root.get());
 
-  TransformTree& tree = root->GetLayerTree()->property_trees()->transform_tree;
+  TransformTree& tree =
+      root->layer_tree_host()->property_trees()->transform_tree;
   TransformNode* node = tree.Node(animated->transform_tree_index());
   EXPECT_FALSE(node->is_currently_animating);
   EXPECT_TRUE(node->has_potential_animation);
@@ -10648,8 +10647,7 @@
   parent5->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
   parent5->SetBounds(gfx::Size(10, 10));
 
-  host()->GetLayerTree()->RegisterViewportLayers(nullptr, page_scale_layer,
-                                                 parent2, nullptr);
+  host()->RegisterViewportLayers(nullptr, page_scale_layer, parent2, nullptr);
   ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root1.get());
 
   const int kRootPropertyTreeNodeId = 0;
diff --git a/cc/trees/layer_tree_host_perftest.cc b/cc/trees/layer_tree_host_perftest.cc
index 77f550fc..1a25a13 100644
--- a/cc/trees/layer_tree_host_perftest.cc
+++ b/cc/trees/layer_tree_host_perftest.cc
@@ -138,11 +138,11 @@
 
   void BuildTree() override {
     gfx::Size viewport = gfx::Size(720, 1038);
-    layer_tree()->SetViewportSize(viewport);
+    layer_tree_host()->SetViewportSize(viewport);
     scoped_refptr<Layer> root = ParseTreeFromJson(json_,
                                                   &fake_content_layer_client_);
     ASSERT_TRUE(root.get());
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     fake_content_layer_client_.set_bounds(viewport);
   }
 
@@ -187,7 +187,7 @@
     LayerTreeHostPerfTestJsonReader::BuildTree();
 
     // Find a leaf layer.
-    for (layer_to_invalidate_ = layer_tree()->root_layer();
+    for (layer_to_invalidate_ = layer_tree_host()->root_layer();
          layer_to_invalidate_->children().size();
          layer_to_invalidate_ = layer_to_invalidate_->children()[0].get()) {
     }
@@ -228,7 +228,7 @@
 
   void BuildTree() override {
     LayerTreeHostPerfTestJsonReader::BuildTree();
-    scrollable_ = layer_tree()->root_layer()->children()[1];
+    scrollable_ = layer_tree_host()->root_layer()->children()[1];
     ASSERT_TRUE(scrollable_.get());
   }
 
@@ -264,7 +264,7 @@
 
   void BuildTree() override {
     LayerTreeHostPerfTestJsonReader::BuildTree();
-    tab_contents_ = static_cast<TextureLayer*>(layer_tree()
+    tab_contents_ = static_cast<TextureLayer*>(layer_tree_host()
                                                    ->root_layer()
                                                    ->children()[0]
                                                    ->children()[0]
diff --git a/cc/trees/layer_tree_host_pixeltest_filters.cc b/cc/trees/layer_tree_host_pixeltest_filters.cc
index a4386cbd..5190efd4 100644
--- a/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -171,7 +171,7 @@
   }
 
   void SetupTree() override {
-    layer_tree()->SetDeviceScaleFactor(device_scale_factor_);
+    layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
     LayerTreePixelTest::SetupTree();
   }
 
@@ -1070,7 +1070,7 @@
   }
 
   void SetupTree() override {
-    layer_tree()->SetDeviceScaleFactor(device_scale_factor_);
+    layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
     LayerTreeHostFiltersPixelTest::SetupTree();
   }
 
diff --git a/cc/trees/layer_tree_host_pixeltest_readback.cc b/cc/trees/layer_tree_host_pixeltest_readback.cc
index 1395b5c3..d920a3e 100644
--- a/cc/trees/layer_tree_host_pixeltest_readback.cc
+++ b/cc/trees/layer_tree_host_pixeltest_readback.cc
@@ -89,7 +89,7 @@
   void BeginTest() override {
     if (insert_copy_request_after_frame_count_ == 0) {
       Layer* const target =
-          readback_target_ ? readback_target_ : layer_tree()->root_layer();
+          readback_target_ ? readback_target_ : layer_tree_host()->root_layer();
       target->RequestCopyOfOutput(CreateCopyOutputRequest());
     }
     PostSetNeedsCommitToMainThread();
@@ -99,7 +99,7 @@
     if (insert_copy_request_after_frame_count_ ==
         layer_tree_host()->SourceFrameNumber()) {
       Layer* const target =
-          readback_target_ ? readback_target_ : layer_tree()->root_layer();
+          readback_target_ ? readback_target_ : layer_tree_host()->root_layer();
       target->RequestCopyOfOutput(CreateCopyOutputRequest());
     }
   }
@@ -468,7 +468,7 @@
   }
 
   void SetupTree() override {
-    layer_tree()->SetDeviceScaleFactor(device_scale_factor_);
+    layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
     LayerTreePixelTest::SetupTree();
   }
 
diff --git a/cc/trees/layer_tree_host_pixeltest_scrollbars.cc b/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
index 0c9f24cf..491fb7c 100644
--- a/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
+++ b/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
@@ -27,8 +27,7 @@
   }
 
   void SetupTree() override {
-    layer_tree_host()->GetLayerTree()->SetDeviceScaleFactor(
-        device_scale_factor_);
+    layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
     LayerTreePixelTest::SetupTree();
   }
 
diff --git a/cc/trees/layer_tree_host_pixeltest_tiles.cc b/cc/trees/layer_tree_host_pixeltest_tiles.cc
index f46f8e9..f9e4bbd 100644
--- a/cc/trees/layer_tree_host_pixeltest_tiles.cc
+++ b/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -68,7 +68,7 @@
 
   void DoReadback() {
     Layer* target =
-        readback_target_ ? readback_target_ : layer_tree()->root_layer();
+        readback_target_ ? readback_target_ : layer_tree_host()->root_layer();
     target->RequestCopyOfOutput(CreateCopyOutputRequest());
   }
 
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 0d8dec3..6706ba8 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -272,7 +272,7 @@
     root_layer->SetBounds(gfx::Size(1024, 1024));
     root_layer->SetIsDrawable(true);
 
-    layer_tree()->SetRootLayer(root_layer);
+    layer_tree_host()->SetRootLayer(root_layer);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root_layer->bounds());
   }
@@ -343,7 +343,7 @@
     root_layer->SetBounds(gfx::Size(1024, 1024));
     root_layer->SetIsDrawable(true);
 
-    layer_tree()->SetRootLayer(root_layer);
+    layer_tree_host()->SetRootLayer(root_layer);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root_layer->bounds());
   }
@@ -382,7 +382,7 @@
     client_.set_bounds(root_layer->bounds());
     root_layer->SetIsDrawable(true);
 
-    layer_tree()->SetRootLayer(root_layer);
+    layer_tree_host()->SetRootLayer(root_layer);
     LayerTreeHostTest::SetupTree();
   }
 
@@ -700,7 +700,7 @@
   void SetupTree() override {
     scoped_refptr<Layer> root = Layer::Create();
     root->SetBounds(gfx::Size(10, 10));
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostTest::SetupTree();
   }
 
@@ -722,8 +722,8 @@
   }
 
   void DidCommitAndDrawFrame() override {
-    SetBeforeValues(layer_tree()->root_layer());
-    VerifyBeforeValues(layer_tree()->root_layer());
+    SetBeforeValues(layer_tree_host()->root_layer());
+    VerifyBeforeValues(layer_tree_host()->root_layer());
 
     ++index_;
     if (index_ == DONE) {
@@ -731,7 +731,7 @@
       return;
     }
 
-    SetAfterValues(layer_tree()->root_layer());
+    SetAfterValues(layer_tree_host()->root_layer());
   }
 
   void AfterTest() override {}
@@ -795,7 +795,7 @@
     root_ = Layer::Create();
     child_ = Layer::Create();
     root_->AddChild(child_);
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostTest::SetupTree();
   }
 
@@ -927,7 +927,7 @@
     child_ = Layer::Create();
     child_->SetElementId(kTestElementId);
     root_->AddChild(child_);
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostTest::SetupTree();
   }
 
@@ -1032,7 +1032,7 @@
     child_ = Layer::Create();
     grand_child_ = Layer::Create();
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     root_->AddChild(child_);
     child_->AddChild(grand_child_);
 
@@ -1115,7 +1115,7 @@
     // This is to force the child to create a transform and effect node.
     child_->SetForceRenderSurfaceForTesting(true);
     root_->AddChild(child_);
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostTest::SetupTree();
   }
 
@@ -1136,10 +1136,10 @@
       case 2:
         // We rebuild property trees for this case to test the code path of
         // damage status synchronization when property trees are different.
-        layer_tree()->property_trees()->needs_rebuild = true;
+        layer_tree_host()->property_trees()->needs_rebuild = true;
         break;
       default:
-        EXPECT_FALSE(layer_tree()->property_trees()->needs_rebuild);
+        EXPECT_FALSE(layer_tree_host()->property_trees()->needs_rebuild);
     }
   }
 
@@ -1211,7 +1211,7 @@
  protected:
   void SetupTree() override {
     root_ = Layer::Create();
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     blur_filter_.Append(FilterOperation::CreateBlurFilter(0.5f));
     brightness_filter_.Append(FilterOperation::CreateBrightnessFilter(0.25f));
     sepia_filter_.Append(FilterOperation::CreateSepiaFilter(0.75f));
@@ -1221,7 +1221,7 @@
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
 
   void DidCommit() override {
-    EffectTree& effect_tree = layer_tree()->property_trees()->effect_tree;
+    EffectTree& effect_tree = layer_tree_host()->property_trees()->effect_tree;
     EffectNode* node = effect_tree.Node(root_->effect_tree_index());
     switch (layer_tree_host()->SourceFrameNumber()) {
       case 1:
@@ -1321,7 +1321,7 @@
  protected:
   void SetupTree() override {
     root_ = Layer::Create();
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostTest::SetupTree();
   }
 
@@ -1329,7 +1329,7 @@
 
   void DidCommit() override {
     TransformTree& transform_tree =
-        layer_tree()->property_trees()->transform_tree;
+        layer_tree_host()->property_trees()->transform_tree;
     TransformNode* node = transform_tree.Node(root_->transform_tree_index());
     gfx::Transform rotate10;
     rotate10.Rotate(10.f);
@@ -1413,7 +1413,7 @@
 
     root_->AddChild(child_);
     child_->AddChild(grand_child_);
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostTest::SetupTree();
   }
 
@@ -1481,7 +1481,7 @@
     mask_layer->SetBounds(gfx::Size(10, 10));
     child->SetMaskLayer(mask_layer.get());
     root->AddChild(std::move(child));
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostTest::SetupTree();
   }
 
@@ -1496,17 +1496,19 @@
         // Root and mask layer should have the same source frame number as they
         // will be in the layer update list but the child is not as it has empty
         // bounds.
-        EXPECT_EQ(
-            mask_layer->paint_properties().source_frame_number,
-            layer_tree()->root_layer()->paint_properties().source_frame_number);
+        EXPECT_EQ(mask_layer->paint_properties().source_frame_number,
+                  layer_tree_host()
+                      ->root_layer()
+                      ->paint_properties()
+                      .source_frame_number);
         EXPECT_NE(mask_layer->paint_properties().source_frame_number,
-                  layer_tree()
+                  layer_tree_host()
                       ->root_layer()
                       ->child_at(0)
                       ->paint_properties()
                       .source_frame_number);
-        layer_tree()->root_layer()->RemoveAllChildren();
-        layer_tree()->root_layer()->SetMaskLayer(mask_layer.get());
+        layer_tree_host()->root_layer()->RemoveAllChildren();
+        layer_tree_host()->root_layer()->SetMaskLayer(mask_layer.get());
         break;
     }
   }
@@ -1585,8 +1587,8 @@
     root_layer_ = FakePictureLayer::Create(&client_);
     root_layer_->SetIsDrawable(true);
     root_layer_->SetBounds(bounds_);
-    layer_tree()->SetRootLayer(root_layer_);
-    layer_tree()->SetViewportSize(bounds_);
+    layer_tree_host()->SetRootLayer(root_layer_);
+    layer_tree_host()->SetViewportSize(bounds_);
     PostSetNeedsCommitToMainThread();
     client_.set_bounds(root_layer_->bounds());
   }
@@ -1649,8 +1651,8 @@
     transform.Translate(10000.0, 10000.0);
     root_layer_->SetTransform(transform);
     root_layer_->SetBounds(bounds_);
-    layer_tree()->SetRootLayer(root_layer_);
-    layer_tree()->SetViewportSize(bounds_);
+    layer_tree_host()->SetRootLayer(root_layer_);
+    layer_tree_host()->SetViewportSize(bounds_);
 
     PostSetNeedsCommitToMainThread();
     client_.set_bounds(root_layer_->bounds());
@@ -1686,7 +1688,7 @@
   void DidCommitAndDrawFrame() override {
     // On the second commit, resize the viewport.
     if (num_draws_ == 1) {
-      layer_tree()->SetViewportSize(gfx::Size(400, 64));
+      layer_tree_host()->SetViewportSize(gfx::Size(400, 64));
     }
     if (num_draws_ < 2) {
       layer_tree_host()->SetNeedsRedrawRect(invalid_rect_);
@@ -1725,7 +1727,7 @@
     scaled_layer_->SetBounds(gfx::Size(1, 1));
     root_layer_->AddChild(scaled_layer_);
 
-    layer_tree()->SetRootLayer(root_layer_);
+    layer_tree_host()->SetRootLayer(root_layer_);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root_layer_->bounds());
   }
@@ -1781,7 +1783,7 @@
 
     root_layer_->AddChild(scrollbar_);
 
-    layer_tree()->SetRootLayer(root_layer_);
+    layer_tree_host()->SetRootLayer(root_layer_);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root_layer_->bounds());
   }
@@ -1799,7 +1801,7 @@
         // Changing the device scale factor causes a commit. It also changes
         // the content bounds of |scrollbar_|, which should not generate
         // a second commit as a result.
-        layer_tree()->SetDeviceScaleFactor(4.f);
+        layer_tree_host()->SetDeviceScaleFactor(4.f);
         break;
       default:
         // No extra commits.
@@ -1833,7 +1835,7 @@
     child_layer_->SetBounds(gfx::Size(10, 10));
     root_layer_->AddChild(child_layer_);
 
-    layer_tree()->SetRootLayer(root_layer_);
+    layer_tree_host()->SetRootLayer(root_layer_);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root_layer_->bounds());
   }
@@ -1842,7 +1844,7 @@
 
   void DidCommit() override {
     if (layer_tree_host()->SourceFrameNumber() == 1)
-      layer_tree()->SetDeviceScaleFactor(4.f);
+      layer_tree_host()->SetDeviceScaleFactor(4.f);
   }
 
   void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
@@ -1898,8 +1900,8 @@
     child_layer_->SetBounds(gfx::Size(10, 10));
     root_layer_->AddChild(child_layer_);
 
-    layer_tree()->SetRootLayer(root_layer_);
-    layer_tree()->SetDeviceColorSpace(space1_);
+    layer_tree_host()->SetRootLayer(root_layer_);
+    layer_tree_host()->SetDeviceColorSpace(space1_);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root_layer_->bounds());
   }
@@ -1969,19 +1971,19 @@
         break;
       case 2:
         EXPECT_FALSE(child_layer_->NeedsDisplayForTesting());
-        layer_tree()->SetDeviceColorSpace(space2_);
+        layer_tree_host()->SetDeviceColorSpace(space2_);
         EXPECT_TRUE(child_layer_->NeedsDisplayForTesting());
         break;
       case 3:
         // The redundant SetDeviceColorSpace should cause no commit and no
         // damage. Force a commit for the test to continue.
-        layer_tree()->SetDeviceColorSpace(space2_);
+        layer_tree_host()->SetDeviceColorSpace(space2_);
         PostSetNeedsCommitToMainThread();
         EXPECT_FALSE(child_layer_->NeedsDisplayForTesting());
         break;
       case 4:
         EXPECT_FALSE(child_layer_->NeedsDisplayForTesting());
-        layer_tree()->SetDeviceColorSpace(space1_);
+        layer_tree_host()->SetDeviceColorSpace(space1_);
         EXPECT_TRUE(child_layer_->NeedsDisplayForTesting());
         break;
       case 5:
@@ -2017,8 +2019,8 @@
     root_layer_ = FakePictureLayer::Create(&client_);
     root_layer_->SetIsDrawable(true);
     root_layer_->SetBounds(bounds_);
-    layer_tree()->SetRootLayer(root_layer_);
-    layer_tree()->SetViewportSize(bounds_);
+    layer_tree_host()->SetRootLayer(root_layer_);
+    layer_tree_host()->SetViewportSize(bounds_);
     PostSetNeedsCommitToMainThread();
     client_.set_bounds(root_layer_->bounds());
   }
@@ -2112,7 +2114,7 @@
     root_layer_ = FakePictureLayer::Create(&client_);
     root_layer_->SetIsDrawable(true);
     root_layer_->SetBounds(gfx::Size(50, 50));
-    layer_tree()->SetRootLayer(root_layer_);
+    layer_tree_host()->SetRootLayer(root_layer_);
 
     // The initially transparent layer has a larger child layer, which is
     // not initially drawn because of the this (parent) layer.
@@ -2216,7 +2218,7 @@
     child_layer_->SetContentsOpaque(true);
     root_layer_->AddChild(child_layer_);
 
-    layer_tree()->SetRootLayer(root_layer_);
+    layer_tree_host()->SetRootLayer(root_layer_);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root_layer_->bounds());
   }
@@ -2306,17 +2308,17 @@
   LayerTreeHostTestCommit() {}
 
   void BeginTest() override {
-    layer_tree()->SetViewportSize(gfx::Size(20, 20));
-    layer_tree()->set_background_color(SK_ColorGRAY);
-    layer_tree()->SetEventListenerProperties(EventListenerClass::kMouseWheel,
-                                             EventListenerProperties::kPassive);
-    layer_tree()->SetEventListenerProperties(
+    layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
+    layer_tree_host()->set_background_color(SK_ColorGRAY);
+    layer_tree_host()->SetEventListenerProperties(
+        EventListenerClass::kMouseWheel, EventListenerProperties::kPassive);
+    layer_tree_host()->SetEventListenerProperties(
         EventListenerClass::kTouchStartOrMove,
         EventListenerProperties::kBlocking);
-    layer_tree()->SetEventListenerProperties(
+    layer_tree_host()->SetEventListenerProperties(
         EventListenerClass::kTouchEndOrCancel,
         EventListenerProperties::kBlockingAndPassive);
-    layer_tree()->SetHaveScrollEventHandlers(true);
+    layer_tree_host()->SetHaveScrollEventHandlers(true);
 
     PostSetNeedsCommitToMainThread();
   }
@@ -2353,8 +2355,8 @@
       : frame_count_with_pending_tree_(0) {}
 
   void BeginTest() override {
-    layer_tree()->SetViewportSize(gfx::Size(20, 20));
-    layer_tree()->set_background_color(SK_ColorGRAY);
+    layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
+    layer_tree_host()->set_background_color(SK_ColorGRAY);
 
     PostSetNeedsCommitToMainThread();
   }
@@ -2407,8 +2409,8 @@
   LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
 
   void BeginTest() override {
-    layer_tree()->SetViewportSize(gfx::Size(20, 20));
-    layer_tree()->set_background_color(SK_ColorGRAY);
+    layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
+    layer_tree_host()->set_background_color(SK_ColorGRAY);
 
     PostSetNeedsCommitToMainThread();
   }
@@ -2458,7 +2460,7 @@
   void SetupTree() override {
     LayerTreeHostTest::SetupTree();
 
-    Layer* root_layer = layer_tree()->root_layer();
+    Layer* root_layer = layer_tree_host()->root_layer();
 
     scoped_refptr<FakePictureLayer> layer = FakePictureLayer::Create(&client_);
     layer->set_always_update_resources(true);
@@ -2471,7 +2473,7 @@
     CreateVirtualViewportLayers(root_layer, scroll_layer_, root_layer->bounds(),
                                 root_layer->bounds(), layer_tree_host());
 
-    layer_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
+    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
     client_.set_bounds(root_layer->bounds());
   }
 
@@ -2484,7 +2486,7 @@
                            float) override {
     gfx::ScrollOffset offset = scroll_layer_->scroll_offset();
     scroll_layer_->SetScrollOffset(ScrollOffsetWithDelta(offset, scroll_delta));
-    layer_tree()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
+    layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
   }
 
   void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
@@ -2512,8 +2514,8 @@
   void DidCommitAndDrawFrame() override {
     switch (layer_tree_host()->SourceFrameNumber()) {
       case 1:
-        layer_tree()->StartPageScaleAnimation(gfx::Vector2d(), false, 1.25f,
-                                              base::TimeDelta());
+        layer_tree_host()->StartPageScaleAnimation(gfx::Vector2d(), false,
+                                                   1.25f, base::TimeDelta());
         break;
     }
   }
@@ -2567,9 +2569,9 @@
     root_layer_ = FakePictureLayer::Create(&client_);
     child_layer_ = FakePictureLayer::Create(&client_);
 
-    layer_tree()->SetViewportSize(gfx::Size(60, 60));
-    layer_tree()->SetDeviceScaleFactor(1.5);
-    EXPECT_EQ(gfx::Size(60, 60), layer_tree()->device_viewport_size());
+    layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
+    layer_tree_host()->SetDeviceScaleFactor(1.5);
+    EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
 
     root_layer_->AddChild(child_layer_);
 
@@ -2581,7 +2583,7 @@
     child_layer_->SetBounds(gfx::Size(10, 10));
     client_.set_bounds(gfx::Size(10, 10));
 
-    layer_tree()->SetRootLayer(root_layer_);
+    layer_tree_host()->SetRootLayer(root_layer_);
 
     PostSetNeedsCommitToMainThread();
     client_.set_bounds(root_layer_->bounds());
@@ -2665,14 +2667,14 @@
       : num_commit_complete_(0), num_draw_layers_(0) {}
 
   void BeginTest() override {
-    layer_tree()->SetViewportSize(gfx::Size(10, 10));
-    layer_tree()->root_layer()->SetBounds(gfx::Size(10, 10));
+    layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
+    layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
 
     layer_ = FakePictureLayer::Create(&client_);
     layer_->SetBounds(gfx::Size(10, 10));
     layer_->SetPosition(gfx::PointF(0.f, 0.f));
     layer_->SetIsDrawable(true);
-    layer_tree()->root_layer()->AddChild(layer_);
+    layer_tree_host()->root_layer()->AddChild(layer_);
 
     PostSetNeedsCommitToMainThread();
     client_.set_bounds(layer_->bounds());
@@ -2848,7 +2850,7 @@
     root_layer->SetBounds(gfx::Size(10, 10));
     root_layer->SetContentsOpaque(true);
 
-    layer_tree()->SetRootLayer(root_layer);
+    layer_tree_host()->SetRootLayer(root_layer);
 
     // The expectations are based on the assumption that the default
     // LCD settings are:
@@ -2867,11 +2869,11 @@
         break;
       case 2:
         // Change layer opacity that should trigger lcd change.
-        layer_tree()->root_layer()->SetOpacity(.5f);
+        layer_tree_host()->root_layer()->SetOpacity(.5f);
         break;
       case 3:
         // Change layer opacity that should not trigger lcd change.
-        layer_tree()->root_layer()->SetOpacity(1.f);
+        layer_tree_host()->root_layer()->SetOpacity(1.f);
         break;
       case 4:
         EndTest();
@@ -3082,7 +3084,7 @@
     scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
     layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
     layer->SetBounds(gfx::Size(10, 10));
-    layer_tree()->root_layer()->AddChild(layer);
+    layer_tree_host()->root_layer()->AddChild(layer);
     client_.set_bounds(layer->bounds());
   }
 
@@ -3118,7 +3120,7 @@
         // Round 2 done.
         EXPECT_EQ(1, frame_);
         layer_tree_host()->SetNeedsRedrawRect(
-            gfx::Rect(layer_tree()->device_viewport_size()));
+            gfx::Rect(layer_tree_host()->device_viewport_size()));
         break;
     }
   }
@@ -3170,7 +3172,7 @@
 
     root_layer_->AddChild(parent_layer_);
     parent_layer_->AddChild(child_layer_);
-    layer_tree()->SetRootLayer(root_layer_);
+    layer_tree_host()->SetRootLayer(root_layer_);
 
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root_layer_->bounds());
@@ -3404,40 +3406,42 @@
     ++num_commits_;
 
     // The scrollbar layer always needs to be pushed.
-    if (root_->GetLayerTree()) {
-      EXPECT_FALSE(root_->GetLayerTree()->LayerNeedsPushPropertiesForTesting(
+    if (root_->layer_tree_host()) {
+      EXPECT_FALSE(root_->layer_tree_host()->LayerNeedsPushPropertiesForTesting(
           root_.get()));
     }
-    if (child2_->GetLayerTree()) {
-      EXPECT_FALSE(child2_->GetLayerTree()->LayerNeedsPushPropertiesForTesting(
-          child2_.get()));
+    if (child2_->layer_tree_host()) {
+      EXPECT_FALSE(
+          child2_->layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+              child2_.get()));
     }
-    if (leaf_always_pushing_layer_->GetLayerTree()) {
-      EXPECT_TRUE(leaf_always_pushing_layer_->GetLayerTree()
+    if (leaf_always_pushing_layer_->layer_tree_host()) {
+      EXPECT_TRUE(leaf_always_pushing_layer_->layer_tree_host()
                       ->LayerNeedsPushPropertiesForTesting(
                           leaf_always_pushing_layer_.get()));
     }
 
     // child_ and grandchild_ don't persist their need to push properties.
-    if (child_->GetLayerTree()) {
-      EXPECT_FALSE(child_->GetLayerTree()->LayerNeedsPushPropertiesForTesting(
-          child_.get()));
-    }
-    if (grandchild_->GetLayerTree()) {
+    if (child_->layer_tree_host()) {
       EXPECT_FALSE(
-          grandchild_->GetLayerTree()->LayerNeedsPushPropertiesForTesting(
+          child_->layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+              child_.get()));
+    }
+    if (grandchild_->layer_tree_host()) {
+      EXPECT_FALSE(
+          grandchild_->layer_tree_host()->LayerNeedsPushPropertiesForTesting(
               grandchild_.get()));
     }
 
-    if (other_root_->GetLayerTree()) {
+    if (other_root_->layer_tree_host()) {
       EXPECT_FALSE(
-          other_root_->GetLayerTree()->LayerNeedsPushPropertiesForTesting(
+          other_root_->layer_tree_host()->LayerNeedsPushPropertiesForTesting(
               other_root_.get()));
     }
 
     switch (num_commits_) {
       case 1:
-        layer_tree()->SetRootLayer(root_);
+        layer_tree_host()->SetRootLayer(root_);
         // Layers added to the tree get committed.
         ++expected_push_properties_root_;
         ++expected_push_properties_child_;
@@ -3449,12 +3453,12 @@
         // No layers need commit.
         break;
       case 3:
-        layer_tree()->SetRootLayer(other_root_);
+        layer_tree_host()->SetRootLayer(other_root_);
         // Layers added to the tree get committed.
         ++expected_push_properties_other_root_;
         break;
       case 4:
-        layer_tree()->SetRootLayer(root_);
+        layer_tree_host()->SetRootLayer(root_);
         // Layers added to the tree get committed.
         ++expected_push_properties_root_;
         ++expected_push_properties_child_;
@@ -3485,11 +3489,11 @@
         ++expected_push_properties_grandchild_;
         break;
       case 10:
-        layer_tree()->SetViewportSize(gfx::Size(20, 20));
+        layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
         // No layers need commit.
         break;
       case 11:
-        layer_tree()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
+        layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
         // No layers need commit.
         break;
       case 12:
@@ -3528,7 +3532,7 @@
     }
 
     // The leaf layer always pushes.
-    if (leaf_always_pushing_layer_->GetLayerTree())
+    if (leaf_always_pushing_layer_->layer_tree_host())
       ++expected_push_properties_leaf_layer_;
   }
 
@@ -3764,7 +3768,7 @@
 
     root_->AddChild(scrollbar_layer_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostTest::SetupTree();
   }
 
@@ -3782,7 +3786,7 @@
 
         scrollbar_layer_->SetBounds(gfx::Size(30, 30));
 
-        EXPECT_TRUE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             scrollbar_layer_.get()));
         layer_tree_host()->SetNeedsCommit();
 
@@ -3814,7 +3818,7 @@
     child_ = PushPropertiesCountingLayer::Create();
     root_->AddChild(child_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostTest::SetupTree();
   }
 
@@ -3828,9 +3832,9 @@
         // is made during this, however, it needs to be pushed in the upcoming
         // commit.
         EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
         EXPECT_EQ(0, root_->NumDescendantsThatDrawContent());
         root_->reset_push_properties_count();
         child_->reset_push_properties_count();
@@ -3839,19 +3843,20 @@
         EXPECT_EQ(0u, root_->push_properties_count());
         EXPECT_EQ(0u, child_->push_properties_count());
         EXPECT_TRUE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(root_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
         EXPECT_TRUE(
 
-            layer_tree()->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+                child_.get()));
         break;
       }
       case 2:
         EXPECT_EQ(1u, root_->push_properties_count());
         EXPECT_EQ(1u, child_->push_properties_count());
         EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
         EndTest();
         break;
     }
@@ -3917,16 +3922,16 @@
     switch (last_source_frame_number) {
       case 0:
         // All layers will need push properties as we set their layer tree host
-        layer_tree()->SetRootLayer(root_);
+        layer_tree_host()->SetRootLayer(root_);
         EXPECT_TRUE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_TRUE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(child_.get()));
-        EXPECT_TRUE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild1_.get()));
-        EXPECT_TRUE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild2_.get()));
-        EXPECT_TRUE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild3_.get()));
         break;
       case 1:
@@ -3945,74 +3950,74 @@
     int last_source_frame_number = layer_tree_host()->SourceFrameNumber() - 1;
     switch (last_source_frame_number) {
       case 0:
-        layer_tree()->SetRootLayer(root_);
+        layer_tree_host()->SetRootLayer(root_);
         break;
       case 1:
         EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(child_.get()));
-        EXPECT_FALSE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild1_.get()));
-        EXPECT_FALSE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild2_.get()));
-        EXPECT_FALSE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild3_.get()));
 
         grandchild1_->RemoveFromParent();
         grandchild1_->SetPosition(gfx::PointF(1.f, 1.f));
 
         EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(child_.get()));
-        EXPECT_FALSE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild2_.get()));
-        EXPECT_FALSE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild3_.get()));
 
         child_->AddChild(grandchild1_);
 
         EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(child_.get()));
-        EXPECT_TRUE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild1_.get()));
-        EXPECT_FALSE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild2_.get()));
-        EXPECT_FALSE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild3_.get()));
 
         grandchild2_->SetPosition(gfx::PointF(1.f, 1.f));
 
         EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(child_.get()));
-        EXPECT_TRUE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild1_.get()));
-        EXPECT_TRUE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild2_.get()));
-        EXPECT_FALSE(layer_tree()->LayerNeedsPushPropertiesForTesting(
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
             grandchild3_.get()));
 
         // grandchild2_ will still need a push properties.
         grandchild1_->RemoveFromParent();
 
         EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
 
         // grandchild3_ does not need a push properties, so recursing should
         // no longer be needed.
         grandchild2_->RemoveFromParent();
 
         EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree()->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
         EndTest();
         break;
     }
@@ -4025,42 +4030,41 @@
     : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
  protected:
   void DidCommitAndDrawFrame() override {
-    LayerTree* layer_tree = layer_tree_host()->GetLayerTree();
     int last_source_frame_number = layer_tree_host()->SourceFrameNumber() - 1;
     switch (last_source_frame_number) {
       case 0:
-        layer_tree->SetRootLayer(root_);
+        layer_tree_host()->SetRootLayer(root_);
         grandchild1_->set_persist_needs_push_properties(true);
         grandchild2_->set_persist_needs_push_properties(true);
         break;
       case 1:
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild1_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild2_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild3_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild1_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild2_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild3_.get()));
 
         // grandchild2_ will still need a push properties.
         grandchild1_->RemoveFromParent();
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
 
         // grandchild3_ does not need a push properties, so recursing should
         // no longer be needed.
         grandchild2_->RemoveFromParent();
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
         EndTest();
         break;
     }
@@ -4074,23 +4078,22 @@
     : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
  protected:
   void DidCommitAndDrawFrame() override {
-    LayerTree* layer_tree = layer_tree_host()->GetLayerTree();
     int last_source_frame_number = layer_tree_host()->SourceFrameNumber() - 1;
     switch (last_source_frame_number) {
       case 0:
-        layer_tree->SetRootLayer(root_);
+        layer_tree_host()->SetRootLayer(root_);
         break;
       case 1:
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild1_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild2_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild3_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild1_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild2_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild3_.get()));
 
         // Change grandchildren while their parent is not in the tree.
         child_->RemoveFromParent();
@@ -4099,36 +4102,36 @@
         root_->AddChild(child_);
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild1_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild2_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild3_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild1_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild2_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild3_.get()));
 
         grandchild1_->RemoveFromParent();
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
 
         grandchild2_->RemoveFromParent();
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
 
         grandchild3_->RemoveFromParent();
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
 
         EndTest();
         break;
@@ -4143,57 +4146,56 @@
     : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
  protected:
   void DidCommitAndDrawFrame() override {
-    LayerTree* layer_tree = layer_tree_host()->GetLayerTree();
     int last_source_frame_number = layer_tree_host()->SourceFrameNumber() - 1;
     switch (last_source_frame_number) {
       case 0:
-        layer_tree->SetRootLayer(root_);
+        layer_tree_host()->SetRootLayer(root_);
         break;
       case 1:
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild1_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild2_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild3_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild1_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild2_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild3_.get()));
 
         child_->SetPosition(gfx::PointF(1.f, 1.f));
         grandchild1_->SetPosition(gfx::PointF(1.f, 1.f));
         grandchild2_->SetPosition(gfx::PointF(1.f, 1.f));
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild1_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild2_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild3_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild1_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild2_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild3_.get()));
 
         grandchild1_->RemoveFromParent();
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
 
         grandchild2_->RemoveFromParent();
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
 
         child_->RemoveFromParent();
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
 
         EndTest();
         break;
@@ -4208,57 +4210,56 @@
     : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
  protected:
   void DidCommitAndDrawFrame() override {
-    LayerTree* layer_tree = layer_tree_host()->GetLayerTree();
     int last_source_frame_number = layer_tree_host()->SourceFrameNumber() - 1;
     switch (last_source_frame_number) {
       case 0:
-        layer_tree->SetRootLayer(root_);
+        layer_tree_host()->SetRootLayer(root_);
         break;
       case 1:
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild1_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild2_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild3_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild1_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild2_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild3_.get()));
 
         grandchild1_->SetPosition(gfx::PointF(1.f, 1.f));
         grandchild2_->SetPosition(gfx::PointF(1.f, 1.f));
         child_->SetPosition(gfx::PointF(1.f, 1.f));
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild1_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild2_.get()));
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(grandchild3_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild1_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild2_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            grandchild3_.get()));
 
         grandchild1_->RemoveFromParent();
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
 
         grandchild2_->RemoveFromParent();
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
-        EXPECT_TRUE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
+        EXPECT_TRUE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_.get()));
 
         child_->RemoveFromParent();
 
         EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(root_.get()));
+            layer_tree_host()->LayerNeedsPushPropertiesForTesting(root_.get()));
 
         EndTest();
         break;
@@ -4379,7 +4380,7 @@
         VideoLayer::Create(&provider_, media::VIDEO_ROTATION_0);
     video_layer->SetBounds(gfx::Size(10, 10));
     video_layer->SetIsDrawable(true);
-    layer_tree()->root_layer()->AddChild(video_layer);
+    layer_tree_host()->root_layer()->AddChild(video_layer);
 
     invalidate_layer_ = video_layer;
   }
@@ -4409,19 +4410,18 @@
     child_layer_->SetIsDrawable(true);
     parent_layer_->AddChild(child_layer_);
 
-    layer_tree()->SetRootLayer(root_layer_);
+    layer_tree_host()->SetRootLayer(root_layer_);
     LayerTreeHostTest::SetupTree();
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
 
   void DidCommitAndDrawFrame() override {
-    LayerTree* layer_tree = layer_tree_host()->GetLayerTree();
     switch (layer_tree_host()->SourceFrameNumber()) {
       case 1:
         // The layer type used does not need to push properties every frame.
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_layer_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_layer_.get()));
 
         // Change the bounds of the child layer, but make it skipped
         // by CalculateDrawProperties.
@@ -4430,8 +4430,8 @@
         break;
       case 2:
         // The bounds of the child layer were pushed to the impl side.
-        EXPECT_FALSE(
-            layer_tree->LayerNeedsPushPropertiesForTesting(child_layer_.get()));
+        EXPECT_FALSE(layer_tree_host()->LayerNeedsPushPropertiesForTesting(
+            child_layer_.get()));
 
         EndTest();
         break;
@@ -4463,7 +4463,7 @@
     root_layer_ = FakePictureLayer::Create(&client_);
     root_layer_->SetBounds(gfx::Size(10, 10));
 
-    layer_tree()->SetRootLayer(root_layer_);
+    layer_tree_host()->SetRootLayer(root_layer_);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root_layer_->bounds());
   }
@@ -4471,7 +4471,7 @@
   void BeginTest() override {
     // The viewport is empty, but we still need to update layers on the main
     // thread.
-    layer_tree()->SetViewportSize(gfx::Size(0, 0));
+    layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
     PostSetNeedsCommitToMainThread();
   }
 
@@ -4522,10 +4522,10 @@
     content_layer->SetBounds(gfx::Size(10, 10));
     inner_viewport_scroll_layer->AddChild(content_layer);
 
-    layer_tree()->SetRootLayer(root_layer_);
-    layer_tree()->RegisterViewportLayers(overscroll_elasticity_layer,
-                                         page_scale_layer,
-                                         inner_viewport_scroll_layer, nullptr);
+    layer_tree_host()->SetRootLayer(root_layer_);
+    layer_tree_host()->RegisterViewportLayers(
+        overscroll_elasticity_layer, page_scale_layer,
+        inner_viewport_scroll_layer, nullptr);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(content_layer->bounds());
   }
@@ -4796,9 +4796,9 @@
     layer_ = SolidColorLayer::Create();
     layer_->SetIsDrawable(true);
     layer_->SetBounds(gfx::Size(10, 10));
-    layer_tree()->SetRootLayer(layer_);
+    layer_tree_host()->SetRootLayer(layer_);
     gfx::Size bounds(100, 100);
-    layer_tree()->SetViewportSize(bounds);
+    layer_tree_host()->SetViewportSize(bounds);
     PostSetNeedsCommitToMainThread();
   }
 
@@ -4891,9 +4891,9 @@
     layer_ = SolidColorLayer::Create();
     layer_->SetIsDrawable(true);
     layer_->SetBounds(gfx::Size(10, 10));
-    layer_tree()->SetRootLayer(layer_);
+    layer_tree_host()->SetRootLayer(layer_);
     gfx::Size bounds(100, 100);
-    layer_tree()->SetViewportSize(bounds);
+    layer_tree_host()->SetViewportSize(bounds);
     PostSetNeedsCommitToMainThread();
   }
 
@@ -5125,7 +5125,7 @@
     LayerTreeHostTest::SetupTree();
     ui_resource_ =
         FakeScopedUIResource::Create(layer_tree_host()->GetUIResourceManager());
-    client_.set_bounds(layer_tree()->root_layer()->bounds());
+    client_.set_bounds(layer_tree_host()->root_layer()->bounds());
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -5181,7 +5181,7 @@
     layer_ = layer.get();
     layer->SetBounds(gfx::Size(10, 10));
     layer->SetIsDrawable(true);
-    layer_tree()->root_layer()->AddChild(layer);
+    layer_tree_host()->root_layer()->AddChild(layer);
     layer_client_.set_bounds(layer_->bounds());
   }
 
@@ -5235,7 +5235,7 @@
     layer_ = layer.get();
     layer->SetBounds(gfx::Size());
     layer->SetIsDrawable(true);
-    layer_tree()->root_layer()->AddChild(layer);
+    layer_tree_host()->root_layer()->AddChild(layer);
     layer_client_.set_bounds(layer->bounds());
   }
 
@@ -5291,7 +5291,7 @@
     layer_ = layer.get();
     layer->SetBounds(gfx::Size(10, 10));
     layer->SetIsDrawable(true);
-    layer_tree()->root_layer()->AddChild(layer);
+    layer_tree_host()->root_layer()->AddChild(layer);
     layer_client_.set_bounds(layer_->bounds());
   }
 
@@ -5359,7 +5359,7 @@
     layer_ = layer.get();
     layer->SetBounds(gfx::Size(10, 10));
     layer->SetIsDrawable(true);
-    layer_tree()->root_layer()->AddChild(layer);
+    layer_tree_host()->root_layer()->AddChild(layer);
     layer_client_.set_bounds(layer_->bounds());
   }
 
@@ -5442,7 +5442,7 @@
 
     layer->SetBounds(gfx::Size(10, 10));
     layer->SetIsDrawable(true);
-    layer_tree()->root_layer()->AddChild(layer);
+    layer_tree_host()->root_layer()->AddChild(layer);
     layer_client_.set_bounds(layer_->bounds());
   }
 
@@ -5670,7 +5670,7 @@
     child_ = Layer::Create();
     grand_child_ = Layer::Create();
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     root_->AddChild(child_);
     child_->AddChild(grand_child_);
 
@@ -5717,11 +5717,11 @@
       case 2:
         // Setting an empty viewport causes draws to get skipped, so the active
         // tree won't update draw properties.
-        layer_tree()->SetViewportSize(gfx::Size());
+        layer_tree_host()->SetViewportSize(gfx::Size());
         child_->SetForceRenderSurfaceForTesting(false);
         break;
       case 3:
-        layer_tree()->SetViewportSize(root_->bounds());
+        layer_tree_host()->SetViewportSize(root_->bounds());
     }
   }
 
@@ -5783,7 +5783,7 @@
         new TestSwapPromise(&swap_promise_result_[2]));
     layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
         std::move(swap_promise2));
-    layer_tree()->SetNeedsDisplayOnAllLayers();
+    layer_tree_host()->SetNeedsDisplayOnAllLayers();
     layer_tree_host()->SetVisible(false);
     layer_tree_host()->Composite(base::TimeTicks::Now());
 
@@ -5857,7 +5857,7 @@
       : deltas_sent_to_client_(false) {}
 
   void BeginTest() override {
-    layer_tree()->SetRootLayer(nullptr);
+    layer_tree_host()->SetRootLayer(nullptr);
     info_.page_scale_delta = 3.14f;
     info_.top_controls_delta = 2.73f;
 
@@ -5865,7 +5865,7 @@
   }
 
   void BeginMainFrame(const BeginFrameArgs& args) override {
-    EXPECT_EQ(nullptr, layer_tree()->root_layer());
+    EXPECT_EQ(nullptr, layer_tree_host()->root_layer());
 
     layer_tree_host()->ApplyScrollAndScale(&info_);
     EndTest();
@@ -5923,10 +5923,10 @@
     // pinch.
     pinch->AddChild(layer);
 
-    layer_tree()->RegisterViewportLayers(NULL, page_scale_layer, pinch,
-                                         nullptr);
-    layer_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
-    layer_tree()->SetRootLayer(root_clip);
+    layer_tree_host()->RegisterViewportLayers(NULL, page_scale_layer, pinch,
+                                              nullptr);
+    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
+    layer_tree_host()->SetRootLayer(root_clip);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root_clip->bounds());
   }
@@ -6125,7 +6125,7 @@
     layer->SetContentsOpaque(true);
     root->AddChild(layer);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root->bounds());
   }
@@ -6166,9 +6166,9 @@
     client_.set_bounds(root->bounds());
     root->SetContentsOpaque(true);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostTest::SetupTree();
-    layer_tree()->SetViewportSize(viewport_size_);
+    layer_tree_host()->SetViewportSize(viewport_size_);
     client_.set_bounds(root->bounds());
   }
 
@@ -6226,10 +6226,10 @@
     // pinch.
     pinch->AddChild(layer);
 
-    layer_tree()->RegisterViewportLayers(NULL, page_scale_layer, pinch,
-                                         nullptr);
-    layer_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
-    layer_tree()->SetRootLayer(root_clip);
+    layer_tree_host()->RegisterViewportLayers(NULL, page_scale_layer, pinch,
+                                              nullptr);
+    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
+    layer_tree_host()->SetRootLayer(root_clip);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root_clip->bounds());
   }
@@ -6383,13 +6383,13 @@
     root_layer->SetBounds(gfx::Size(1500, 1500));
     root_layer->SetIsDrawable(true);
 
-    layer_tree()->SetRootLayer(root_layer);
+    layer_tree_host()->SetRootLayer(root_layer);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root_layer->bounds());
   }
 
   void BeginTest() override {
-    layer_tree()->SetViewportSize(gfx::Size(16, 16));
+    layer_tree_host()->SetViewportSize(gfx::Size(16, 16));
     PostSetNeedsCommitToMainThread();
   }
 
@@ -6439,7 +6439,7 @@
     root_layer->SetBounds(gfx::Size(150, 150));
     root_layer->SetIsDrawable(true);
 
-    layer_tree()->SetRootLayer(root_layer);
+    layer_tree_host()->SetRootLayer(root_layer);
     LayerTreeHostTest::SetupTree();
     client_.set_bounds(root_layer->bounds());
   }
@@ -6517,7 +6517,7 @@
     root = Layer::Create();
     child = Layer::Create();
     root->AddChild(child);
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostTest::SetupTree();
   }
 
@@ -6612,7 +6612,7 @@
     mask_layer->SetBounds(mask_size);
     mask_layer->SetIsMask(true);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeTest::SetupTree();
     client_.set_bounds(root->bounds());
   }
@@ -6697,7 +6697,7 @@
     mask_layer->SetBounds(scaling_layer_size);
     mask_layer->SetIsMask(true);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeTest::SetupTree();
     client_.set_bounds(root->bounds());
   }
@@ -6747,8 +6747,8 @@
     switch (layer_tree_host()->SourceFrameNumber()) {
       case 1:
         gfx::Size double_root_size(200, 200);
-        layer_tree()->SetViewportSize(double_root_size);
-        layer_tree()->SetDeviceScaleFactor(2.f);
+        layer_tree_host()->SetViewportSize(double_root_size);
+        layer_tree_host()->SetDeviceScaleFactor(2.f);
         break;
     }
   }
@@ -6786,7 +6786,7 @@
     mask_layer->SetBounds(mask_size);
     mask_layer->SetIsMask(true);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeTest::SetupTree();
     client_.set_bounds(root->bounds());
   }
@@ -6835,8 +6835,8 @@
     switch (layer_tree_host()->SourceFrameNumber()) {
       case 1:
         gfx::Size double_root_size(200, 200);
-        layer_tree()->SetViewportSize(double_root_size);
-        layer_tree()->SetDeviceScaleFactor(2.f);
+        layer_tree_host()->SetViewportSize(double_root_size);
+        layer_tree_host()->SetDeviceScaleFactor(2.f);
         break;
     }
   }
@@ -6875,13 +6875,13 @@
     page_scale->AddChild(page_scale_child2);
     page_scale_child1->AddChild(page_scale_grandchild);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeTest::SetupTree();
 
     scoped_refptr<Layer> overscroll_elasticity_layer = nullptr;
     scoped_refptr<Layer> inner_viewport_scroll_layer = nullptr;
     scoped_refptr<Layer> outer_viewport_scroll_layer = nullptr;
-    layer_tree()->RegisterViewportLayers(
+    layer_tree_host()->RegisterViewportLayers(
         overscroll_elasticity_layer, page_scale, inner_viewport_scroll_layer,
         outer_viewport_scroll_layer);
 
@@ -6940,8 +6940,8 @@
 class LayerTreeHostTestPaintedDeviceScaleFactor : public LayerTreeHostTest {
  protected:
   void BeginTest() override {
-    layer_tree()->SetPaintedDeviceScaleFactor(2.0f);
-    EXPECT_EQ(1.0f, layer_tree()->device_scale_factor());
+    layer_tree_host()->SetPaintedDeviceScaleFactor(2.0f);
+    EXPECT_EQ(1.0f, layer_tree_host()->device_scale_factor());
     PostSetNeedsCommitToMainThread();
   }
 
@@ -7005,9 +7005,9 @@
     client_.set_bounds(root->bounds());
     root->SetContentsOpaque(true);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostTest::SetupTree();
-    layer_tree()->SetViewportSize(viewport_size_);
+    layer_tree_host()->SetViewportSize(viewport_size_);
     client_.set_bounds(root->bounds());
   }
 
@@ -7046,7 +7046,7 @@
 class LayerTreeHostTestSubmitFrameMetadata : public LayerTreeHostTest {
  protected:
   void BeginTest() override {
-    layer_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
+    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
     PostSetNeedsCommitToMainThread();
   }
 
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index e1977a44..aee33bb 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -45,7 +45,7 @@
 
   void AttachPlayersToTimeline() {
     animation_host()->AddAnimationTimeline(timeline_.get());
-    layer_tree()->SetElementIdsForTesting();
+    layer_tree_host()->SetElementIdsForTesting();
     timeline_->AttachPlayer(player_.get());
     timeline_->AttachPlayer(player_child_.get());
   }
@@ -166,7 +166,7 @@
 
   void BeginTest() override {
     AttachPlayersToTimeline();
-    player_->AttachElement(layer_tree()->root_layer()->element_id());
+    player_->AttachElement(layer_tree_host()->root_layer()->element_id());
     PostAddInstantAnimationToMainThreadPlayer(player_.get());
   }
 
@@ -206,7 +206,7 @@
 
   void BeginTest() override {
     AttachPlayersToTimeline();
-    player_->AttachElement(layer_tree()->root_layer()->element_id());
+    player_->AttachElement(layer_tree_host()->root_layer()->element_id());
     PostAddAnimationToMainThreadPlayer(player_.get());
   }
 
@@ -244,7 +244,7 @@
 
   void BeginTest() override {
     AttachPlayersToTimeline();
-    player_->AttachElement(layer_tree()->root_layer()->element_id());
+    player_->AttachElement(layer_tree_host()->root_layer()->element_id());
     PostAddAnimationToMainThreadPlayer(player_.get());
   }
 
@@ -286,7 +286,7 @@
     picture_ = FakePictureLayer::Create(&client_);
     picture_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(picture_->bounds());
-    layer_tree()->root_layer()->AddChild(picture_);
+    layer_tree_host()->root_layer()->AddChild(picture_);
 
     AttachPlayersToTimeline();
     player_child_->AttachElement(picture_->element_id());
@@ -350,7 +350,7 @@
     picture_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(picture_->bounds());
 
-    layer_tree()->root_layer()->AddChild(picture_);
+    layer_tree_host()->root_layer()->AddChild(picture_);
 
     AttachPlayersToTimeline();
     player_child_->set_animation_delegate(this);
@@ -406,7 +406,7 @@
  public:
   void BeginTest() override {
     AttachPlayersToTimeline();
-    player_->AttachElement(layer_tree()->root_layer()->element_id());
+    player_->AttachElement(layer_tree_host()->root_layer()->element_id());
     PostAddInstantAnimationToMainThreadPlayer(player_.get());
   }
 
@@ -436,7 +436,7 @@
   void SetupTree() override {
     update_check_layer_ = FakePictureLayer::Create(&client_);
     update_check_layer_->SetOpacity(0.f);
-    layer_tree()->SetRootLayer(update_check_layer_);
+    layer_tree_host()->SetRootLayer(update_check_layer_);
     client_.set_bounds(update_check_layer_->bounds());
     LayerTreeHostAnimationTest::SetupTree();
 
@@ -500,7 +500,7 @@
       player_->AddAnimation(std::move(animation));
 
       // We add the animation *before* attaching the layer to the tree.
-      layer_tree()->root_layer()->AddChild(layer);
+      layer_tree_host()->root_layer()->AddChild(layer);
     }
   }
 
@@ -638,7 +638,7 @@
     picture_ = FakePictureLayer::Create(&client_);
     picture_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(picture_->bounds());
-    layer_tree()->root_layer()->AddChild(picture_);
+    layer_tree_host()->root_layer()->AddChild(picture_);
 
     AttachPlayersToTimeline();
     player_child_->AttachElement(picture_->element_id());
@@ -723,11 +723,11 @@
     LayerTreeHostAnimationTest::SetupTree();
 
     scroll_layer_ = FakePictureLayer::Create(&client_);
-    scroll_layer_->SetScrollClipLayerId(layer_tree()->root_layer()->id());
+    scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
     scroll_layer_->SetBounds(gfx::Size(1000, 1000));
     client_.set_bounds(scroll_layer_->bounds());
     scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
-    layer_tree()->root_layer()->AddChild(scroll_layer_);
+    layer_tree_host()->root_layer()->AddChild(scroll_layer_);
 
     AttachPlayersToTimeline();
     player_child_->AttachElement(scroll_layer_->element_id());
@@ -784,8 +784,8 @@
     scroll_layer_->SetBounds(gfx::Size(10000, 10000));
     client_.set_bounds(scroll_layer_->bounds());
     scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
-    scroll_layer_->SetScrollClipLayerId(layer_tree()->root_layer()->id());
-    layer_tree()->root_layer()->AddChild(scroll_layer_);
+    scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
+    layer_tree_host()->root_layer()->AddChild(scroll_layer_);
 
     AttachPlayersToTimeline();
     player_child_->AttachElement(scroll_layer_->element_id());
@@ -844,8 +844,8 @@
     scroll_layer_->SetBounds(gfx::Size(10000, 10000));
     client_.set_bounds(scroll_layer_->bounds());
     scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
-    scroll_layer_->SetScrollClipLayerId(layer_tree()->root_layer()->id());
-    layer_tree()->root_layer()->AddChild(scroll_layer_);
+    scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
+    layer_tree_host()->root_layer()->AddChild(scroll_layer_);
 
     AttachPlayersToTimeline();
   }
@@ -951,11 +951,11 @@
     LayerTreeHostAnimationTest::SetupTree();
 
     scroll_layer_ = FakePictureLayer::Create(&client_);
-    scroll_layer_->SetScrollClipLayerId(layer_tree()->root_layer()->id());
+    scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
     scroll_layer_->SetBounds(gfx::Size(10000, 10000));
     client_.set_bounds(scroll_layer_->bounds());
     scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
-    layer_tree()->root_layer()->AddChild(scroll_layer_);
+    layer_tree_host()->root_layer()->AddChild(scroll_layer_);
 
     std::unique_ptr<ScrollOffsetAnimationCurve> curve(
         ScrollOffsetAnimationCurve::Create(
@@ -1074,15 +1074,15 @@
 
   void DidCommit() override {
     if (layer_tree_host()->SourceFrameNumber() == 1) {
-      player_->AttachElement(layer_tree()->root_layer()->element_id());
+      player_->AttachElement(layer_tree_host()->root_layer()->element_id());
       AddAnimatedTransformToPlayer(player_.get(), 4, 1, 1);
     } else if (layer_tree_host()->SourceFrameNumber() == 2) {
       AddOpacityTransitionToPlayer(player_.get(), 1, 0.f, 0.5f, true);
 
       scoped_refptr<Layer> layer = Layer::Create();
-      layer_tree()->root_layer()->AddChild(layer);
+      layer_tree_host()->root_layer()->AddChild(layer);
 
-      layer_tree()->SetElementIdsForTesting();
+      layer_tree_host()->SetElementIdsForTesting();
       layer->SetBounds(gfx::Size(4, 4));
 
       player_child_->AttachElement(layer->element_id());
@@ -1169,8 +1169,8 @@
     start_transform.Translate(4.0, 4.0);
     layer_->SetTransform(start_transform);
 
-    layer_tree()->root_layer()->AddChild(layer_);
-    layer_tree()->SetElementIdsForTesting();
+    layer_tree_host()->root_layer()->AddChild(layer_);
+    layer_tree_host()->SetElementIdsForTesting();
 
     player_->AttachElement(layer_->element_id());
 
@@ -1238,9 +1238,9 @@
     LayerTreeHostAnimationTest::SetupTree();
     layer_ = Layer::Create();
     layer_->SetBounds(gfx::Size(4, 4));
-    layer_tree()->root_layer()->AddChild(layer_);
+    layer_tree_host()->root_layer()->AddChild(layer_);
 
-    layer_tree()->SetElementIdsForTesting();
+    layer_tree_host()->SetElementIdsForTesting();
 
     animation_host()->AddAnimationTimeline(timeline_.get());
     timeline_->AttachPlayer(player_.get());
@@ -1270,7 +1270,7 @@
         EXPECT_FALSE(animation_host()->NeedsTickAnimations());
         break;
       case 2:
-        layer_tree()->root_layer()->AddChild(layer_);
+        layer_tree_host()->root_layer()->AddChild(layer_);
         EXPECT_TRUE(
             player_->element_animations()->has_element_in_active_list());
         EXPECT_FALSE(
@@ -1322,11 +1322,11 @@
     LayerTreeHostAnimationTest::SetupTree();
     layer_ = Layer::Create();
     layer_->SetBounds(gfx::Size(4, 4));
-    layer_tree()->root_layer()->AddChild(layer_);
+    layer_tree_host()->root_layer()->AddChild(layer_);
 
     AttachPlayersToTimeline();
 
-    player_->AttachElement(layer_tree()->root_layer()->element_id());
+    player_->AttachElement(layer_tree_host()->root_layer()->element_id());
     player_child_->AttachElement(layer_->element_id());
   }
 
@@ -1396,11 +1396,11 @@
     layer_ = FakePictureLayer::Create(&client_);
     layer_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(layer_->bounds());
-    layer_tree()->root_layer()->AddChild(layer_);
+    layer_tree_host()->root_layer()->AddChild(layer_);
 
     AttachPlayersToTimeline();
 
-    player_->AttachElement(layer_tree()->root_layer()->element_id());
+    player_->AttachElement(layer_tree_host()->root_layer()->element_id());
     player_child_->AttachElement(layer_->element_id());
   }
 
@@ -1476,7 +1476,7 @@
     layer_ = FakePictureLayer::Create(&client_);
     layer_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(layer_->bounds());
-    layer_tree()->root_layer()->AddChild(layer_);
+    layer_tree_host()->root_layer()->AddChild(layer_);
 
     AttachPlayersToTimeline();
     player_->AttachElement(layer_->element_id());
@@ -1556,11 +1556,11 @@
     layer_ = FakePictureLayer::Create(&client_);
     layer_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(layer_->bounds());
-    layer_tree()->root_layer()->AddChild(layer_);
+    layer_tree_host()->root_layer()->AddChild(layer_);
 
     AttachPlayersToTimeline();
 
-    player_->AttachElement(layer_tree()->root_layer()->element_id());
+    player_->AttachElement(layer_tree_host()->root_layer()->element_id());
     player_child_->AttachElement(layer_->element_id());
   }
 
@@ -1632,7 +1632,7 @@
     picture_ = FakePictureLayer::Create(&client_);
     picture_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(picture_->bounds());
-    layer_tree()->root_layer()->AddChild(picture_);
+    layer_tree_host()->root_layer()->AddChild(picture_);
 
     AttachPlayersToTimeline();
     player_->AttachElement(picture_->element_id());
@@ -1683,7 +1683,7 @@
     LayerTreeHostAnimationTest::SetupTree();
     AttachPlayersToTimeline();
     timeline_->DetachPlayer(player_child_.get());
-    player_->AttachElement(layer_tree()->root_layer()->element_id());
+    player_->AttachElement(layer_tree_host()->root_layer()->element_id());
 
     TransformOperations start;
     start.AppendTranslate(5.f, 5.f, 0.f);
@@ -1720,7 +1720,8 @@
       timeline_->DetachPlayer(player_.get());
       player_ = nullptr;
       timeline_->AttachPlayer(player_child_.get());
-      player_child_->AttachElement(layer_tree()->root_layer()->element_id());
+      player_child_->AttachElement(
+          layer_tree_host()->root_layer()->element_id());
       AddAnimatedTransformToPlayer(player_child_.get(), 1.0, 10, 10);
       Animation* animation =
           player_child_->GetAnimation(TargetProperty::TRANSFORM);
@@ -1746,7 +1747,7 @@
 
     LayerTreeHostAnimationTest::SetupTree();
     AttachPlayersToTimeline();
-    player_->AttachElement(layer_tree()->root_layer()->element_id());
+    player_->AttachElement(layer_tree_host()->root_layer()->element_id());
     AddAnimatedTransformToPlayer(player_.get(), 1.0, 5, 5);
   }
 
@@ -1826,11 +1827,11 @@
     layer_ = FakePictureLayer::Create(&client_);
     layer_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(layer_->bounds());
-    layer_tree()->root_layer()->AddChild(layer_);
+    layer_tree_host()->root_layer()->AddChild(layer_);
 
     AttachPlayersToTimeline();
 
-    player_->AttachElement(layer_tree()->root_layer()->element_id());
+    player_->AttachElement(layer_tree_host()->root_layer()->element_id());
     player_child_->AttachElement(layer_->element_id());
   }
 
@@ -1844,11 +1845,11 @@
 
   void UpdateLayerTreeHost() override {
     if (layer_tree_host()->SourceFrameNumber() == 1) {
-      EXPECT_FALSE(layer_tree()->property_trees()->needs_rebuild);
+      EXPECT_FALSE(layer_tree_host()->property_trees()->needs_rebuild);
       AddAnimatedTransformToPlayer(player_child_.get(), 1.0, 5, 5);
     }
 
-    EXPECT_TRUE(layer_tree()->property_trees()->needs_rebuild);
+    EXPECT_TRUE(layer_tree_host()->property_trees()->needs_rebuild);
   }
 
   void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index 3a2187e9..e73d79e2 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -222,7 +222,7 @@
 
   virtual void InvalidateAndSetNeedsCommit() {
     // Cause damage so we try to draw.
-    layer_tree()->root_layer()->SetNeedsDisplay();
+    layer_tree_host()->root_layer()->SetNeedsDisplay();
     layer_tree_host()->SetNeedsCommit();
   }
 
@@ -619,7 +619,7 @@
 
     root_->AddChild(layer_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostContextTest::SetupTree();
     client_.set_bounds(root_->bounds());
   }
@@ -696,7 +696,7 @@
         FakePictureLayer::Create(&client_);
     picture_layer->SetBounds(gfx::Size(10, 20));
     client_.set_bounds(picture_layer->bounds());
-    layer_tree()->SetRootLayer(picture_layer);
+    layer_tree_host()->SetRootLayer(picture_layer);
 
     LayerTreeHostContextTest::SetupTree();
   }
@@ -804,7 +804,7 @@
     root_->AddChild(child_);
     child_->AddChild(grandchild_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostContextTest::SetupTree();
     client_.set_bounds(root_->bounds());
   }
@@ -975,7 +975,7 @@
     scrollbar->SetIsDrawable(true);
     root->AddChild(scrollbar);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostContextTest::SetupTree();
   }
 
@@ -1015,10 +1015,10 @@
   }
 
   void DidCommitAndDrawFrame() override {
-    ASSERT_TRUE(layer_tree()->hud_layer());
+    ASSERT_TRUE(layer_tree_host()->hud_layer());
     // End the test once we know the 3nd frame drew.
     if (layer_tree_host()->SourceFrameNumber() < 5) {
-      layer_tree()->root_layer()->SetNeedsDisplay();
+      layer_tree_host()->root_layer()->SetNeedsDisplay();
       layer_tree_host()->SetNeedsCommit();
     } else {
       EndTest();
@@ -1060,7 +1060,7 @@
     picture->SetIsDrawable(true);
     root->AddChild(picture);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostContextTest::SetupTree();
   }
 
@@ -1088,8 +1088,8 @@
     scrollbar_layer_ =
         FakePaintedScrollbarLayer::Create(false, true, scroll_layer->id());
     scrollbar_layer_->SetBounds(gfx::Size(10, 100));
-    layer_tree()->root_layer()->AddChild(scrollbar_layer_);
-    layer_tree()->root_layer()->AddChild(scroll_layer);
+    layer_tree_host()->root_layer()->AddChild(scrollbar_layer_);
+    layer_tree_host()->root_layer()->AddChild(scroll_layer);
     PostSetNeedsCommitToMainThread();
   }
 
@@ -1610,7 +1610,7 @@
         FakePictureLayer::Create(&client_);
     picture_layer->SetBounds(gfx::Size(10, 20));
     client_.set_bounds(picture_layer->bounds());
-    layer_tree()->SetRootLayer(picture_layer);
+    layer_tree_host()->SetRootLayer(picture_layer);
 
     LayerTreeTest::SetupTree();
   }
diff --git a/cc/trees/layer_tree_host_unittest_copyrequest.cc b/cc/trees/layer_tree_host_unittest_copyrequest.cc
index ae6ff24..cf8b1cd11 100644
--- a/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -43,7 +43,7 @@
     grand_child->SetBounds(gfx::Size(5, 5));
     child->AddChild(grand_child);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostCopyRequestTest::SetupTree();
     client_.set_bounds(root->bounds());
   }
@@ -205,7 +205,7 @@
     layer_->SetBounds(gfx::Size(15, 15));
     root_->AddChild(layer_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostCopyRequestTest::SetupTree();
     client_.set_bounds(root_->bounds());
   }
@@ -260,7 +260,7 @@
     impl_destroyed_->SetBounds(gfx::Size(10, 10));
     root_->AddChild(impl_destroyed_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostCopyRequestTest::SetupTree();
     client_.set_bounds(root_->bounds());
   }
@@ -292,7 +292,7 @@
         EXPECT_EQ(1, callback_count_);
 
         // Prevent drawing so we can't make a copy of the impl_destroyed layer.
-        layer_tree()->SetViewportSize(gfx::Size());
+        layer_tree_host()->SetViewportSize(gfx::Size());
         break;
       case 2:
         // Flush the message loops and make sure the callbacks run.
@@ -359,7 +359,7 @@
     copy_layer_->SetBounds(gfx::Size(10, 10));
     parent_layer_->AddChild(copy_layer_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostCopyRequestTest::SetupTree();
     client_.set_bounds(root_->bounds());
   }
@@ -459,7 +459,7 @@
     copy_layer_->SetBounds(gfx::Size(10, 10));
     parent_layer_->AddChild(copy_layer_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostCopyRequestTest::SetupTree();
     client_.set_bounds(root_->bounds());
   }
@@ -563,7 +563,7 @@
     copy_layer_->SetBounds(gfx::Size(10, 10));
     parent_layer_->AddChild(copy_layer_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostCopyRequestTest::SetupTree();
     client_.set_bounds(root_->bounds());
   }
@@ -613,7 +613,7 @@
     child_layer_->SetBounds(gfx::Size(10, 10));
     copy_layer_->AddChild(child_layer_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostCopyRequestTest::SetupTree();
     client_.set_bounds(root_->bounds());
   }
@@ -657,7 +657,7 @@
     copy_layer_->SetBounds(gfx::Size(10, 10));
     root_->AddChild(copy_layer_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostCopyRequestTest::SetupTree();
     client_.set_bounds(root_->bounds());
   }
@@ -675,7 +675,7 @@
     PostSetNeedsCommitToMainThread();
 
     // Prevent drawing.
-    layer_tree()->SetViewportSize(gfx::Size(0, 0));
+    layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
 
     AddCopyRequest(copy_layer_.get());
   }
@@ -690,7 +690,7 @@
   void DidCommit() override {
     if (layer_tree_host()->SourceFrameNumber() == 1) {
       // Allow drawing.
-      layer_tree()->SetViewportSize(gfx::Size(root_->bounds()));
+      layer_tree_host()->SetViewportSize(gfx::Size(root_->bounds()));
 
       AddCopyRequest(copy_layer_.get());
     }
@@ -747,7 +747,7 @@
     copy_layer_->SetBounds(gfx::Size(10, 10));
     root_->AddChild(copy_layer_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostCopyRequestTest::SetupTree();
     client_.set_bounds(root_->bounds());
   }
@@ -881,7 +881,7 @@
     copy_layer_->SetForceRenderSurfaceForTesting(true);
     root_->AddChild(copy_layer_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostCopyRequestTest::SetupTree();
   }
 
@@ -1042,7 +1042,7 @@
     copy_layer_->SetBounds(gfx::Size(10, 10));
     root_->AddChild(copy_layer_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostCopyRequestTest::SetupTree();
     client_.set_bounds(root_->bounds());
   }
@@ -1077,7 +1077,7 @@
                            base::Unretained(this)));
         copy_layer_->RequestCopyOfOutput(std::move(request));
 
-        layer_tree()->SetViewportSize(gfx::Size());
+        layer_tree_host()->SetViewportSize(gfx::Size());
         break;
       }
       case 2:
@@ -1088,7 +1088,8 @@
       case 3:
         EXPECT_EQ(1, callback_count_);
         // Allow us to draw now.
-        layer_tree()->SetViewportSize(layer_tree()->root_layer()->bounds());
+        layer_tree_host()->SetViewportSize(
+            layer_tree_host()->root_layer()->bounds());
         break;
       case 4:
         EXPECT_EQ(1, callback_count_);
@@ -1118,7 +1119,7 @@
     copy_layer_->SetBounds(gfx::Size(10, 10));
     root_->AddChild(copy_layer_);
 
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostCopyRequestTest::SetupTree();
     client_.set_bounds(root_->bounds());
   }
@@ -1153,7 +1154,7 @@
                            base::Unretained(this)));
         copy_layer_->RequestCopyOfOutput(std::move(request));
 
-        layer_tree()->SetViewportSize(gfx::Size());
+        layer_tree_host()->SetViewportSize(gfx::Size());
         break;
       }
       case 2:
@@ -1190,7 +1191,7 @@
     root->AddChild(child_);
     child_->SetHideLayerAndSubtree(true);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostCopyRequestTest::SetupTree();
     client_.set_bounds(root->bounds());
   }
diff --git a/cc/trees/layer_tree_host_unittest_damage.cc b/cc/trees/layer_tree_host_unittest_damage.cc
index 2da4c5a2..fddf0ce 100644
--- a/cc/trees/layer_tree_host_unittest_damage.cc
+++ b/cc/trees/layer_tree_host_unittest_damage.cc
@@ -30,7 +30,7 @@
     scoped_refptr<FakePictureLayer> root = FakePictureLayer::Create(&client_);
     root->SetBounds(gfx::Size(10, 10));
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostDamageTest::SetupTree();
     client_.set_bounds(root->bounds());
   }
@@ -44,7 +44,7 @@
     switch (layer_tree_host()->SourceFrameNumber()) {
       case 1:
         layer_tree_host()->SetNeedsRedrawRect(
-            gfx::Rect(layer_tree()->device_viewport_size()));
+            gfx::Rect(layer_tree_host()->device_viewport_size()));
         break;
     }
   }
@@ -94,7 +94,7 @@
     scoped_refptr<FakePictureLayer> root = FakePictureLayer::Create(&client_);
     root->SetBounds(gfx::Size(10, 10));
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostDamageTest::SetupTree();
     client_.set_bounds(root->bounds());
   }
@@ -107,7 +107,7 @@
   void DidCommitAndDrawFrame() override {
     switch (layer_tree_host()->SourceFrameNumber()) {
       case 1:
-        layer_tree()->SetViewportSize(gfx::Size(15, 15));
+        layer_tree_host()->SetViewportSize(gfx::Size(15, 15));
         break;
     }
   }
@@ -164,7 +164,7 @@
     content_->SetBounds(gfx::Size(2000, 100));
     root->AddChild(content_);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostDamageTest::SetupTree();
     client_.set_bounds(root->bounds());
   }
@@ -214,7 +214,7 @@
       case 2:
         // Cause visible damage.
         content_->SetNeedsDisplayRect(
-            gfx::Rect(layer_tree()->device_viewport_size()));
+            gfx::Rect(layer_tree_host()->device_viewport_size()));
         break;
       case 3:
         // Cause non-visible damage.
@@ -249,7 +249,7 @@
     child_->SetBounds(gfx::Size(30, 30));
 
     root_->AddChild(child_);
-    layer_tree()->SetRootLayer(root_);
+    layer_tree_host()->SetRootLayer(root_);
     LayerTreeHostDamageTest::SetupTree();
     client_.set_bounds(root_->bounds());
   }
@@ -336,7 +336,7 @@
     scoped_refptr<Layer> root_layer = Layer::Create();
     root_layer->SetBounds(gfx::Size(400, 400));
     root_layer->SetMasksToBounds(true);
-    layer_tree()->SetRootLayer(root_layer);
+    layer_tree_host()->SetRootLayer(root_layer);
 
     scoped_refptr<Layer> scroll_clip_layer = Layer::Create();
     content_layer_ = FakePictureLayer::Create(&client_);
@@ -447,7 +447,7 @@
 
   void ResizeScrollLayer() {
     EXPECT_EQ(3, num_draws_);
-    Layer* root = layer_tree()->root_layer();
+    Layer* root = layer_tree_host()->root_layer();
     content_layer_->SetBounds(
         gfx::Size(root->bounds().width() + 60, root->bounds().height() + 100));
   }
diff --git a/cc/trees/layer_tree_host_unittest_occlusion.cc b/cc/trees/layer_tree_host_unittest_occlusion.cc
index 0c3863e..3cc21929 100644
--- a/cc/trees/layer_tree_host_unittest_occlusion.cc
+++ b/cc/trees/layer_tree_host_unittest_occlusion.cc
@@ -41,7 +41,7 @@
     child_->SetIsDrawable(true);
     root->AddChild(child_);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeTest::SetupTree();
   }
 
@@ -97,7 +97,7 @@
     child2->SetIsDrawable(true);
     root->AddChild(child2);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeTest::SetupTree();
   }
 
@@ -163,7 +163,7 @@
     child2->SetIsDrawable(true);
     root->AddChild(child2);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeTest::SetupTree();
     client_.set_bounds(root->bounds());
   }
@@ -236,7 +236,7 @@
     child2->SetIsDrawable(true);
     root->AddChild(child2);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeTest::SetupTree();
     client_.set_bounds(root->bounds());
   }
diff --git a/cc/trees/layer_tree_host_unittest_picture.cc b/cc/trees/layer_tree_host_unittest_picture.cc
index bb13a32..cbdd6417 100644
--- a/cc/trees/layer_tree_host_unittest_picture.cc
+++ b/cc/trees/layer_tree_host_unittest_picture.cc
@@ -24,7 +24,7 @@
     root_picture_layer_->SetBounds(size);
     root->AddChild(root_picture_layer_);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     client_.set_bounds(size);
   }
 
@@ -62,7 +62,7 @@
         scoped_refptr<FakePictureLayer> picture =
             FakePictureLayer::Create(&client_);
         picture_id2_ = picture->id();
-        layer_tree()->root_layer()->AddChild(picture);
+        layer_tree_host()->root_layer()->AddChild(picture);
         break;
       }
       case 4:
@@ -158,7 +158,7 @@
     picture_->SetBounds(gfx::Size(768, 960));
     root->AddChild(picture_);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostPictureTest::SetupTree();
   }
 
@@ -190,7 +190,7 @@
         // Change the picture layer's size along with the viewport, so it will
         // consider picking a new tile size.
         picture_->SetBounds(gfx::Size(768, 1056));
-        layer_tree()->SetViewportSize(gfx::Size(768, 1056));
+        layer_tree_host()->SetViewportSize(gfx::Size(768, 1056));
         break;
       case 2:
         EndTest();
@@ -226,7 +226,7 @@
     // force it to have a transform node by making it scrollable.
     picture_->SetScrollClipLayerId(root->id());
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostPictureTest::SetupTree();
     client_.set_bounds(picture_->bounds());
   }
@@ -338,7 +338,7 @@
     picture_->SetBounds(gfx::Size(100, 100));
     child_->AddChild(picture_);
 
-    layer_tree()->SetRootLayer(root);
+    layer_tree_host()->SetRootLayer(root);
     LayerTreeHostPictureTest::SetupTree();
   }
 
@@ -429,10 +429,10 @@
     picture_->SetBounds(gfx::Size(100, 100));
     pinch_->AddChild(picture_);
 
-    layer_tree()->RegisterViewportLayers(NULL, page_scale_layer, pinch_,
-                                         nullptr);
-    layer_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
-    layer_tree()->SetRootLayer(root_clip);
+    layer_tree_host()->RegisterViewportLayers(NULL, page_scale_layer, pinch_,
+                                              nullptr);
+    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
+    layer_tree_host()->SetRootLayer(root_clip);
     LayerTreeHostPictureTest::SetupTree();
     client_.set_bounds(picture_->bounds());
   }
@@ -592,8 +592,8 @@
     normal_layer_->SetBounds(size);
     root->AddChild(normal_layer_);
 
-    layer_tree()->SetRootLayer(root);
-    layer_tree()->SetViewportSize(size);
+    layer_tree_host()->SetRootLayer(root);
+    layer_tree_host()->SetViewportSize(size);
 
     client_.set_fill_with_nonsolid_color(true);
     client_.set_bounds(size);
@@ -658,13 +658,13 @@
   void ScaleRootUp() {
     gfx::Transform transform;
     transform.Scale(2, 2);
-    layer_tree_host()->GetLayerTree()->root_layer()->SetTransform(transform);
+    layer_tree_host()->root_layer()->SetTransform(transform);
   }
 
   void ScaleRootUpAndRecalculateScales() {
     gfx::Transform transform;
     transform.Scale(4, 4);
-    layer_tree_host()->GetLayerTree()->root_layer()->SetTransform(transform);
+    layer_tree_host()->root_layer()->SetTransform(transform);
     layer_tree_host()->SetNeedsRecalculateRasterScales();
   }
 
diff --git a/cc/trees/layer_tree_host_unittest_proxy.cc b/cc/trees/layer_tree_host_unittest_proxy.cc
index 94ca4cb..27e2835 100644
--- a/cc/trees/layer_tree_host_unittest_proxy.cc
+++ b/cc/trees/layer_tree_host_unittest_proxy.cc
@@ -16,7 +16,7 @@
  protected:
   void SetupTree() override {
     update_check_layer_ = FakePictureLayer::Create(&client_);
-    layer_tree()->SetRootLayer(update_check_layer_);
+    layer_tree_host()->SetRootLayer(update_check_layer_);
     LayerTreeTest::SetupTree();
     client_.set_bounds(update_check_layer_->bounds());
   }
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc
index 37d98c1..59fbfb6 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -72,7 +72,7 @@
  protected:
   void SetupTree() override {
     LayerTreeTest::SetupTree();
-    Layer* root_layer = layer_tree()->root_layer();
+    Layer* root_layer = layer_tree_host()->root_layer();
 
     // Create an effective max_scroll_offset of (100, 100).
     gfx::Size scroll_layer_bounds(root_layer->bounds().width() + 100,
@@ -93,18 +93,20 @@
         num_scrolls_(0) {}
 
   void BeginTest() override {
-    outer_viewport_container_layer_id_ =
-        layer_tree()->outer_viewport_scroll_layer()->scroll_clip_layer()->id();
-    layer_tree()->outer_viewport_scroll_layer()->SetScrollOffset(
+    outer_viewport_container_layer_id_ = layer_tree_host()
+                                             ->outer_viewport_scroll_layer()
+                                             ->scroll_clip_layer()
+                                             ->id();
+    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
         initial_scroll_);
-    layer_tree()->outer_viewport_scroll_layer()->set_did_scroll_callback(
+    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
         base::Bind(&LayerTreeHostScrollTestScrollSimple::DidScrollOuterViewport,
                    base::Unretained(this)));
     PostSetNeedsCommitToMainThread();
   }
 
   void UpdateLayerTreeHost() override {
-    Layer* scroll_layer = layer_tree()->outer_viewport_scroll_layer();
+    Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer();
     if (!layer_tree_host()->SourceFrameNumber()) {
       EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
     } else {
@@ -166,7 +168,7 @@
       : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}
 
   void BeginTest() override {
-    scroll_layer_ = layer_tree()->outer_viewport_scroll_layer();
+    scroll_layer_ = layer_tree_host()->outer_viewport_scroll_layer();
     scroll_layer_->SetScrollOffset(initial_scroll_);
     scroll_layer_->set_did_scroll_callback(base::Bind(
         &LayerTreeHostScrollTestScrollMultipleRedraw::DidScrollOuterViewport,
@@ -257,9 +259,9 @@
         num_impl_scrolls_(0) {}
 
   void BeginTest() override {
-    layer_tree()->outer_viewport_scroll_layer()->SetScrollOffset(
+    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
         initial_scroll_);
-    layer_tree()->outer_viewport_scroll_layer()->set_did_scroll_callback(
+    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
         base::Bind(
             &LayerTreeHostScrollTestScrollAbortedCommit::DidScrollOuterViewport,
             base::Unretained(this)));
@@ -270,20 +272,21 @@
     LayerTreeHostScrollTest::SetupTree();
 
     gfx::Size scroll_layer_bounds(200, 200);
-    layer_tree()->outer_viewport_scroll_layer()->SetBounds(scroll_layer_bounds);
-    layer_tree()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
+    layer_tree_host()->outer_viewport_scroll_layer()->SetBounds(
+        scroll_layer_bounds);
+    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
   }
 
   void WillBeginMainFrame() override {
     num_will_begin_main_frames_++;
-    Layer* root_scroll_layer = layer_tree()->outer_viewport_scroll_layer();
+    Layer* root_scroll_layer = layer_tree_host()->outer_viewport_scroll_layer();
     switch (num_will_begin_main_frames_) {
       case 1:
         // This will not be aborted because of the initial prop changes.
         EXPECT_EQ(0, num_impl_scrolls_);
         EXPECT_EQ(0, layer_tree_host()->SourceFrameNumber());
         EXPECT_VECTOR_EQ(initial_scroll_, root_scroll_layer->scroll_offset());
-        EXPECT_EQ(1.f, layer_tree()->page_scale_factor());
+        EXPECT_EQ(1.f, layer_tree_host()->page_scale_factor());
         break;
       case 2:
         // This commit will be aborted, and another commit will be
@@ -293,7 +296,7 @@
         EXPECT_VECTOR_EQ(
             gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_),
             root_scroll_layer->scroll_offset());
-        EXPECT_EQ(impl_scale_, layer_tree()->page_scale_factor());
+        EXPECT_EQ(impl_scale_, layer_tree_host()->page_scale_factor());
         PostSetNeedsRedrawToMainThread();
         break;
       case 3:
@@ -305,7 +308,8 @@
             gfx::ScrollOffsetWithDelta(initial_scroll_,
                                        impl_scroll_ + impl_scroll_),
             root_scroll_layer->scroll_offset());
-        EXPECT_EQ(impl_scale_ * impl_scale_, layer_tree()->page_scale_factor());
+        EXPECT_EQ(impl_scale_ * impl_scale_,
+                  layer_tree_host()->page_scale_factor());
         root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta(
             root_scroll_layer->scroll_offset(), second_main_scroll_));
         break;
@@ -442,7 +446,7 @@
 
   void SetupTree() override {
     LayerTreeHostScrollTest::SetupTree();
-    layer_tree()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
+    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -498,17 +502,17 @@
 
   void SetupTree() override {
     LayerTreeHostScrollTest::SetupTree();
-    layer_tree()
+    layer_tree_host()
         ->outer_viewport_scroll_layer()
         ->scroll_clip_layer()
         ->SetForceRenderSurfaceForTesting(true);
     gfx::Transform translate;
     translate.Translate(0.25f, 0.f);
-    layer_tree()
+    layer_tree_host()
         ->outer_viewport_scroll_layer()
         ->scroll_clip_layer()
         ->SetTransform(translate);
-    layer_tree()->SetPageScaleFactorAndLimits(1.f, 0.1f, 100.f);
+    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.1f, 100.f);
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -558,7 +562,7 @@
         num_scrolls_(0) {}
 
   void SetupTree() override {
-    layer_tree()->SetDeviceScaleFactor(device_scale_factor_);
+    layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
 
     scoped_refptr<Layer> root_layer = Layer::Create();
     root_layer->SetBounds(gfx::Size(10, 10));
@@ -589,7 +593,7 @@
     }
 
     scoped_refptr<Layer> outer_container_layer =
-        layer_tree()->outer_viewport_scroll_layer()->parent();
+        layer_tree_host()->outer_viewport_scroll_layer()->parent();
 
     child_layer_->SetIsDrawable(true);
     child_layer_->SetScrollClipLayerId(outer_container_layer->id());
@@ -606,11 +610,11 @@
 
     expected_scroll_layer_->SetScrollOffset(initial_offset_);
 
-    layer_tree()->SetRootLayer(root_layer);
+    layer_tree_host()->SetRootLayer(root_layer);
     LayerTreeTest::SetupTree();
     fake_content_layer_client_.set_bounds(root_layer->bounds());
 
-    layer_tree()->outer_viewport_scroll_layer()->set_did_scroll_callback(
+    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
         base::Bind(
             &LayerTreeHostScrollTestCaseWithChild::DidScrollOuterViewport,
             base::Unretained(this)));
@@ -823,20 +827,20 @@
 
   void SetupTree() override {
     LayerTreeHostScrollTest::SetupTree();
-    layer_tree()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
+    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
   }
 
   void BeginTest() override {
-    layer_tree()->outer_viewport_scroll_layer()->SetScrollOffset(
+    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
         initial_scroll_);
-    layer_tree()->outer_viewport_scroll_layer()->set_did_scroll_callback(
+    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
         base::Bind(&LayerTreeHostScrollTestSimple::DidScrollOuterViewport,
                    base::Unretained(this)));
     PostSetNeedsCommitToMainThread();
   }
 
   void UpdateLayerTreeHost() override {
-    Layer* scroll_layer = layer_tree()->outer_viewport_scroll_layer();
+    Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer();
     if (!layer_tree_host()->SourceFrameNumber()) {
       EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
     } else {
@@ -945,21 +949,21 @@
 
   void SetupTree() override {
     LayerTreeHostScrollTest::SetupTree();
-    layer_tree()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
+    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
   }
 
   void BeginTest() override {
-    layer_tree()->outer_viewport_scroll_layer()->SetScrollOffset(
+    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
         initial_scroll_);
     PostSetNeedsCommitToMainThread();
   }
 
   void WillCommit() override {
-    Layer* scroll_layer = layer_tree()->outer_viewport_scroll_layer();
+    Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer();
     switch (layer_tree_host()->SourceFrameNumber()) {
       case 0:
         EXPECT_TRUE(
-            scroll_layer->GetLayerTree()->LayerNeedsPushPropertiesForTesting(
+            scroll_layer->layer_tree_host()->LayerNeedsPushPropertiesForTesting(
                 scroll_layer));
         break;
       case 1:
@@ -967,7 +971,7 @@
         // still pick up scrolls that happen on the active layer during
         // commit.
         EXPECT_FALSE(
-            scroll_layer->GetLayerTree()->LayerNeedsPushPropertiesForTesting(
+            scroll_layer->layer_tree_host()->LayerNeedsPushPropertiesForTesting(
                 scroll_layer));
         break;
     }
@@ -1085,14 +1089,16 @@
   LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}
 
   void BeginTest() override {
-    outer_viewport_container_layer_id_ =
-        layer_tree()->outer_viewport_scroll_layer()->scroll_clip_layer()->id();
+    outer_viewport_container_layer_id_ = layer_tree_host()
+                                             ->outer_viewport_scroll_layer()
+                                             ->scroll_clip_layer()
+                                             ->id();
     PostSetNeedsCommitToMainThread();
   }
 
   void UpdateLayerTreeHost() override {
-    Layer* root = layer_tree()->root_layer();
-    Layer* scroll_layer = layer_tree()->outer_viewport_scroll_layer();
+    Layer* root = layer_tree_host()->root_layer();
+    Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer();
     switch (layer_tree_host()->SourceFrameNumber()) {
       case 0:
         scroll_layer->SetScrollClipLayerId(outer_viewport_container_layer_id_);
@@ -1161,11 +1167,12 @@
 
   void SetupTree() override {
     LayerTreeHostScrollTest::SetupTree();
-    layer_tree()->outer_viewport_scroll_layer()->SetIsDrawable(false);
-    layer_tree()->outer_viewport_scroll_layer()->SetScrollOffset(
+    layer_tree_host()->outer_viewport_scroll_layer()->SetIsDrawable(false);
+    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
         gfx::ScrollOffset(20.f, 20.f));
-    layer_tree()->outer_viewport_scroll_layer()->SetNonFastScrollableRegion(
-        gfx::Rect(20, 20, 20, 20));
+    layer_tree_host()
+        ->outer_viewport_scroll_layer()
+        ->SetNonFastScrollableRegion(gfx::Rect(20, 20, 20, 20));
   }
 
   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
@@ -1210,8 +1217,10 @@
 
   void SetupTree() override {
     LayerTreeHostScrollTest::SetupTree();
-    layer_tree()->inner_viewport_scroll_layer()->AddMainThreadScrollingReasons(
-        MainThreadScrollingReason::kNonFastScrollableRegion);
+    layer_tree_host()
+        ->inner_viewport_scroll_layer()
+        ->AddMainThreadScrollingReasons(
+            MainThreadScrollingReason::kNonFastScrollableRegion);
   }
 
   void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
@@ -1352,14 +1361,15 @@
 
   void SetupTree() override {
     LayerTreeTest::SetupTree();
-    Layer* root_layer = layer_tree()->root_layer();
+    Layer* root_layer = layer_tree_host()->root_layer();
     root_layer->SetBounds(gfx::Size(10, 10));
 
     CreateVirtualViewportLayers(root_layer, root_layer->bounds(),
                                 root_layer->bounds(), root_layer->bounds(),
                                 layer_tree_host());
 
-    Layer* outer_scroll_layer = layer_tree()->outer_viewport_scroll_layer();
+    Layer* outer_scroll_layer =
+        layer_tree_host()->outer_viewport_scroll_layer();
 
     Layer* root_scroll_layer =
         CreateScrollLayer(outer_scroll_layer, &root_scroll_layer_client_);
@@ -1399,8 +1409,8 @@
 
   virtual void DidScroll(Layer* layer) {
     if (scroll_destroy_whole_tree_) {
-      layer_tree()->RegisterViewportLayers(NULL, NULL, NULL, NULL);
-      layer_tree()->SetRootLayer(NULL);
+      layer_tree_host()->RegisterViewportLayers(NULL, NULL, NULL, NULL);
+      layer_tree_host()->SetRootLayer(NULL);
       EndTest();
       return;
     }
@@ -1479,11 +1489,13 @@
   }
 
   void BeginTest() override {
-    outer_viewport_container_layer_id_ =
-        layer_tree()->outer_viewport_scroll_layer()->scroll_clip_layer()->id();
-    layer_tree()->outer_viewport_scroll_layer()->SetScrollOffset(
+    outer_viewport_container_layer_id_ = layer_tree_host()
+                                             ->outer_viewport_scroll_layer()
+                                             ->scroll_clip_layer()
+                                             ->id();
+    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
         initial_scroll_);
-    layer_tree()->outer_viewport_scroll_layer()->set_did_scroll_callback(
+    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
         base::Bind(&LayerTreeHostScrollTestScrollMFBA::DidScrollOuterViewport,
                    base::Unretained(this)));
     PostSetNeedsCommitToMainThread();
@@ -1506,7 +1518,7 @@
   }
 
   void UpdateLayerTreeHost() override {
-    Layer* scroll_layer = layer_tree()->outer_viewport_scroll_layer();
+    Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer();
     switch (layer_tree_host()->SourceFrameNumber()) {
       case 0:
         EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
@@ -1610,9 +1622,9 @@
   }
 
   void BeginTest() override {
-    layer_tree()->outer_viewport_scroll_layer()->SetScrollOffset(
+    layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset(
         initial_scroll_);
-    layer_tree()->outer_viewport_scroll_layer()->set_did_scroll_callback(
+    layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback(
         base::Bind(&LayerTreeHostScrollTestScrollAbortedCommitMFBA::
                        DidScrollOuterViewport,
                    base::Unretained(this)));
@@ -1623,13 +1635,14 @@
     LayerTreeHostScrollTest::SetupTree();
 
     gfx::Size scroll_layer_bounds(200, 200);
-    layer_tree()->outer_viewport_scroll_layer()->SetBounds(scroll_layer_bounds);
-    layer_tree()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
+    layer_tree_host()->outer_viewport_scroll_layer()->SetBounds(
+        scroll_layer_bounds);
+    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
   }
 
   void WillBeginMainFrame() override {
     num_will_begin_main_frames_++;
-    Layer* root_scroll_layer = layer_tree()->outer_viewport_scroll_layer();
+    Layer* root_scroll_layer = layer_tree_host()->outer_viewport_scroll_layer();
     switch (num_will_begin_main_frames_) {
       case 1:
         // This will not be aborted because of the initial prop changes.
@@ -1873,7 +1886,8 @@
         elastic_overscroll_test_cases_[num_begin_main_frames_main_thread_];
     current_elastic_overscroll_ += elastic_overscroll_delta;
     EXPECT_EQ(expected_elastic_overscroll, current_elastic_overscroll_);
-    EXPECT_EQ(expected_elastic_overscroll, layer_tree()->elastic_overscroll());
+    EXPECT_EQ(expected_elastic_overscroll,
+              layer_tree_host()->elastic_overscroll());
   }
 
   void WillBeginMainFrame() override { num_begin_main_frames_main_thread_++; }
@@ -1996,14 +2010,15 @@
       : initial_scroll_(10, 20), second_scroll_(0, 0) {}
 
   void BeginTest() override {
-    layer_tree()->inner_viewport_scroll_layer()->SetScrollOffset(
+    layer_tree_host()->inner_viewport_scroll_layer()->SetScrollOffset(
         initial_scroll_);
-    layer_tree()->inner_viewport_scroll_layer()->SetBounds(gfx::Size(100, 100));
+    layer_tree_host()->inner_viewport_scroll_layer()->SetBounds(
+        gfx::Size(100, 100));
     PostSetNeedsCommitToMainThread();
   }
 
   void UpdateLayerTreeHost() override {
-    Layer* scroll_layer = layer_tree()->inner_viewport_scroll_layer();
+    Layer* scroll_layer = layer_tree_host()->inner_viewport_scroll_layer();
     if (layer_tree_host()->SourceFrameNumber() == 0) {
       EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
     } else {
diff --git a/cc/trees/layer_tree_host_unittest_video.cc b/cc/trees/layer_tree_host_unittest_video.cc
index dcfbe9ad..51e90ce 100644
--- a/cc/trees/layer_tree_host_unittest_video.cc
+++ b/cc/trees/layer_tree_host_unittest_video.cc
@@ -34,8 +34,8 @@
     root->AddChild(video);
     video_layer_id_ = video->id();
 
-    layer_tree()->SetRootLayer(root);
-    layer_tree()->SetDeviceScaleFactor(2.f);
+    layer_tree_host()->SetRootLayer(root);
+    layer_tree_host()->SetDeviceScaleFactor(2.f);
     LayerTreeHostVideoTest::SetupTree();
   }
 
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc
index f259664..375051a 100644
--- a/cc/trees/property_tree_builder.cc
+++ b/cc/trees/property_tree_builder.cc
@@ -106,7 +106,7 @@
 }
 
 static bool IsMetaInformationRecomputationNeeded(Layer* layer) {
-  return layer->GetLayerTree()->needs_meta_info_recomputation();
+  return layer->layer_tree_host()->needs_meta_info_recomputation();
 }
 
 // Recursively walks the layer tree(if needed) to compute any information
@@ -140,7 +140,7 @@
       recursive_data->num_unclipped_descendants);
 
   if (IsRootLayer(layer))
-    layer->GetLayerTree()->SetNeedsMetaInfoRecomputation(false);
+    layer->layer_tree_host()->SetNeedsMetaInfoRecomputation(false);
 }
 
 static void PreCalculateMetaInformationInternalForTesting(
@@ -1509,7 +1509,7 @@
     PropertyTrees* property_trees) {
   property_trees->is_main_thread = true;
   property_trees->is_active = false;
-  SkColor color = root_layer->GetLayerTree()->background_color();
+  SkColor color = root_layer->layer_tree_host()->background_color();
   if (SkColorGetA(color) != 255)
     color = SkColorSetA(color, 255);
   BuildPropertyTreesTopLevelInternal(
@@ -1518,7 +1518,7 @@
       elastic_overscroll, page_scale_factor, device_scale_factor, viewport,
       device_transform, property_trees, color);
 #if DCHECK_IS_ON()
-  for (auto* layer : *root_layer->GetLayerTree())
+  for (auto* layer : *root_layer->layer_tree_host())
     CheckScrollAndClipPointersForLayer(layer);
 #endif
   property_trees->ResetCachedData();
diff --git a/cc/trees/tree_synchronizer.cc b/cc/trees/tree_synchronizer.cc
index 3f467e0..b593a9d6 100644
--- a/cc/trees/tree_synchronizer.cc
+++ b/cc/trees/tree_synchronizer.cc
@@ -13,7 +13,6 @@
 #include "cc/layers/layer.h"
 #include "cc/layers/layer_collections.h"
 #include "cc/layers/layer_impl.h"
-#include "cc/trees/layer_tree.h"
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_impl.h"
 
@@ -46,8 +45,8 @@
   if (!layer_root) {
     tree_impl->DetachLayers();
   } else {
-    SynchronizeTreesInternal(layer_root->GetLayerTree(), tree_impl,
-                             layer_root->GetLayerTree()->property_trees());
+    SynchronizeTreesInternal(layer_root->layer_tree_host(), tree_impl,
+                             layer_root->layer_tree_host()->property_trees());
   }
 }
 
@@ -105,7 +104,7 @@
                               active_tree);
 }
 
-void TreeSynchronizer::PushLayerProperties(LayerTree* host_tree,
+void TreeSynchronizer::PushLayerProperties(LayerTreeHost* host_tree,
                                            LayerTreeImpl* impl_tree) {
   PushLayerPropertiesInternal(host_tree->LayersThatShouldPushProperties(),
                               impl_tree);
diff --git a/cc/trees/tree_synchronizer.h b/cc/trees/tree_synchronizer.h
index b088eaf0..e5a0b62a 100644
--- a/cc/trees/tree_synchronizer.h
+++ b/cc/trees/tree_synchronizer.h
@@ -13,7 +13,7 @@
 namespace cc {
 
 class LayerImpl;
-class LayerTree;
+class LayerTreeHost;
 class LayerTreeImpl;
 class Layer;
 
@@ -28,7 +28,7 @@
 
   static void PushLayerProperties(LayerTreeImpl* pending_tree,
                                   LayerTreeImpl* active_tree);
-  static void PushLayerProperties(LayerTree* host_tree,
+  static void PushLayerProperties(LayerTreeHost* host_tree,
                                   LayerTreeImpl* impl_tree);
 
  private:
diff --git a/cc/trees/tree_synchronizer_unittest.cc b/cc/trees/tree_synchronizer_unittest.cc
index 1ec104d..b51d8ea 100644
--- a/cc/trees/tree_synchronizer_unittest.cc
+++ b/cc/trees/tree_synchronizer_unittest.cc
@@ -91,9 +91,9 @@
 void ExpectTreesAreIdentical(Layer* root_layer,
                              LayerImpl* root_layer_impl,
                              LayerTreeImpl* tree_impl) {
-  auto layer_iter = root_layer->GetLayerTree()->begin();
+  auto layer_iter = root_layer->layer_tree_host()->begin();
   auto layer_impl_iter = tree_impl->begin();
-  for (; layer_iter != root_layer->GetLayerTree()->end();
+  for (; layer_iter != root_layer->layer_tree_host()->end();
        ++layer_iter, ++layer_impl_iter) {
     Layer* layer = *layer_iter;
     LayerImpl* layer_impl = *layer_impl_iter;
@@ -194,7 +194,7 @@
                           host_->active_tree());
 
   // We have to push properties to pick up the destruction list pointer.
-  TreeSynchronizer::PushLayerProperties(layer_tree_root->GetLayerTree(),
+  TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
                                         host_->active_tree());
 
   // Add a new layer to the Layer side
@@ -243,7 +243,7 @@
                           host_->active_tree());
 
   // We have to push properties to pick up the destruction list pointer.
-  TreeSynchronizer::PushLayerProperties(layer_tree_root->GetLayerTree(),
+  TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
                                         host_->active_tree());
 
   host_->active_tree()->ResetAllChangeTracking();
@@ -257,7 +257,7 @@
   ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
                           host_->active_tree());
 
-  TreeSynchronizer::PushLayerProperties(layer_tree_root->GetLayerTree(),
+  TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
                                         host_->active_tree());
 
   // Check that the impl thread properly tracked the change.
@@ -293,7 +293,7 @@
   ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
                           host_->active_tree());
 
-  TreeSynchronizer::PushLayerProperties(layer_tree_root->GetLayerTree(),
+  TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
                                         host_->active_tree());
 
   // Check that the property values we set on the Layer tree are reflected in
@@ -343,7 +343,7 @@
                           host_->active_tree());
 
   // We have to push properties to pick up the destruction list pointer.
-  TreeSynchronizer::PushLayerProperties(layer_tree_root->GetLayerTree(),
+  TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
                                         host_->active_tree());
 
   // Now restructure the tree to look like this:
@@ -399,7 +399,7 @@
                           host_->active_tree());
 
   // We have to push properties to pick up the destruction list pointer.
-  TreeSynchronizer::PushLayerProperties(old_layer_tree_root->GetLayerTree(),
+  TreeSynchronizer::PushLayerProperties(old_layer_tree_root->layer_tree_host(),
                                         host_->active_tree());
 
   // Remove all children on the Layer side.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
index d71e5e6..2a1e095 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
@@ -11,6 +11,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.SystemClock;
+import android.support.v4.util.ArrayMap;
 import android.util.Log;
 
 import org.chromium.base.ActivityState;
@@ -67,6 +68,8 @@
 import org.chromium.policy.AppRestrictionsProvider;
 import org.chromium.policy.CombinedPolicyProvider;
 
+import java.util.Map;
+
 /**
  * Basic application functionality that should be shared among all browser applications that use
  * chrome layer.
@@ -82,6 +85,8 @@
 
     private static DocumentTabModelSelector sDocumentTabModelSelector;
 
+    protected Map<Class, Class> mImplementationMap;
+
     @Override
     protected void attachBaseContext(Context base) {
         super.attachBaseContext(base);
@@ -111,6 +116,9 @@
         super.onCreate();
 
         TraceEvent.end("ChromeApplication.onCreate");
+        // It may be wise to update this anticipated capacity from time time as expectations for
+        // the quantity of downsteam-specific implementations increases (or decreases).
+        mImplementationMap = new ArrayMap<Class, Class>(8);
     }
 
     /**
@@ -435,23 +443,32 @@
      * implementations upstream and downstream.  To use this,
      * - give the upstream class a public parameterless constructor (required!)
      *   e.g., public MyType() {},
-     * - generate the downstream object in createObjectImpl in the ChromeApplication subclass.
-     *   e.g., if (klass.getName().equals(MyType.class.getName()) return (T)new MySubType(), and
+     * - register the downstream object in mImplementationMap,
+     *   e.g., mImplementationMap.put(MyType.class, MySubType.class);
      * - invoke this method on the appropriate class,
      *   e.g., ChromeApplication.createObject(MyType.class).
      * @param klass The class that the Chrome Application should create an instance of.
      */
+    @SuppressWarnings("unchecked")
     public static <T> T createObject(Class<T> klass) {
-        return ((ChromeApplication) ContextUtils.getApplicationContext()).createObjectImpl(klass);
-    }
+        Class newKlass = ((ChromeApplication) ContextUtils.getApplicationContext())
+                .mImplementationMap.get(klass);
+        if (newKlass == null) {
+            newKlass = klass;
+        }
 
-    protected <T> T createObjectImpl(Class<T> klass) {
+        Object obj;
         try {
-            return klass.newInstance();
+            obj = newKlass.newInstance();
         } catch (InstantiationException e) {
             throw new RuntimeException("Asked to create unexpected class: " + klass.getName(), e);
         } catch (IllegalAccessException e) {
             throw new RuntimeException("Asked to create unexpected class: " + klass.getName(), e);
         }
+        if (!klass.isInstance(obj)) {
+            throw new RuntimeException("Created an instance of type " + obj.getClass().getName()
+                    + " when expected an instance of type " + klass.getName());
+        }
+        return (T) obj;
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
index 11eeae57..4130191 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
@@ -464,8 +464,6 @@
         if (focused) StartupMetrics.getInstance().recordFocusedOmnibox();
 
         fixupTextDirection();
-        // Always align to the same as the paragraph direction (LTR = left, RTL = right).
-        ApiCompatibilityUtils.setTextAlignment(this, TEXT_ALIGNMENT_TEXT_START);
     }
 
     /**
@@ -504,6 +502,8 @@
         } else {
             ApiCompatibilityUtils.setTextDirection(this, TEXT_DIRECTION_LTR);
         }
+        // Always align to the same as the paragraph direction (LTR = left, RTL = right).
+        ApiCompatibilityUtils.setTextAlignment(this, TEXT_ALIGNMENT_TEXT_START);
     }
 
     @Override
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 990baffd..cedf127 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6402,6 +6402,12 @@
       <message name="IDS_FLAGS_MEMORY_COORDINATOR_DESCRIPTION" desc="Description of an about::flags to enable/disable memory coordinator">
         Enable memory coordinator instead of memory pressure listeners.
       </message>
+      <message name="IDS_FLAGS_SERVICE_WORKER_NAVIGATION_PRELOAD_NAME" desc="Name of the about::flags setting for service worker navigation preload.">
+        Service worker navigation preload.
+      </message>
+      <message name="IDS_FLAGS_SERVICE_WORKER_NAVIGATION_PRELOAD_DESCRIPTION" desc="Description of the about::flags setting for service worker navigation preload.">
+        Enable web pages to use the experimental service worker navigation preload API.
+      </message>
 
       <!-- Data Reduction Proxy -->
       <message name="IDS_FLAGS_DATA_REDUCTION_PROXY_LO_FI_NAME" desc="An about:flags experiment title to enable/disable Data Saver Lo-Fi" translateable="false">
@@ -15529,7 +15535,6 @@
             Enabled (Flash lowers volume when interrupted by other sound, experimental)
         </message>
     </if>
-    
     <if expr="is_win">
       <message name="IDS_FLAGS_GDI_TEXT_PRINTING" desc="Name for the flag that enables using GDI to print text">
         GDI Text Printing
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 427549f..156667e 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1128,6 +1128,10 @@
      IDS_FLAGS_ENABLE_STALE_WHILE_REVALIDATE_NAME,
      IDS_FLAGS_ENABLE_STALE_WHILE_REVALIDATE_DESCRIPTION, kOsAll,
      FEATURE_VALUE_TYPE(features::kStaleWhileRevalidate)},
+    {"enable-service-worker-navigation-preload",
+     IDS_FLAGS_SERVICE_WORKER_NAVIGATION_PRELOAD_NAME,
+     IDS_FLAGS_SERVICE_WORKER_NAVIGATION_PRELOAD_DESCRIPTION, kOsAll,
+     FEATURE_VALUE_TYPE(features::kServiceWorkerNavigationPreload)},
     {"enable-suggestions-with-substring-match",
      IDS_FLAGS_SUGGESTIONS_WITH_SUB_STRING_MATCH_NAME,
      IDS_FLAGS_SUGGESTIONS_WITH_SUB_STRING_MATCH_DESCRIPTION, kOsAll,
diff --git a/chrome/browser/chrome_browser_field_trials_desktop.cc b/chrome/browser/chrome_browser_field_trials_desktop.cc
index 40386d9e..a8c8150 100644
--- a/chrome/browser/chrome_browser_field_trials_desktop.cc
+++ b/chrome/browser/chrome_browser_field_trials_desktop.cc
@@ -80,6 +80,35 @@
                             INIT_STATUS_MAX);
 }
 
+// Record information about the chrome module.
+void RecordChromeModuleInfo(
+    base::debug::GlobalActivityTracker* global_tracker) {
+  DCHECK(global_tracker);
+
+  base::debug::GlobalActivityTracker::ModuleInfo module;
+  module.is_loaded = true;
+  module.address = reinterpret_cast<uintptr_t>(&__ImageBase);
+
+  base::win::PEImage pe(&__ImageBase);
+  PIMAGE_NT_HEADERS headers = pe.GetNTHeaders();
+  CHECK(headers);
+  module.size = headers->OptionalHeader.SizeOfImage;
+  module.timestamp = headers->FileHeader.TimeDateStamp;
+
+  GUID guid;
+  DWORD age;
+  pe.GetDebugId(&guid, &age);
+  module.age = age;
+  static_assert(sizeof(module.identifier) >= sizeof(guid),
+                "Identifier field must be able to contain a GUID.");
+  memcpy(module.identifier, &guid, sizeof(guid));
+
+  module.file = "chrome.dll";
+  module.debug_file = "chrome.dll.pdb";
+
+  global_tracker->RecordModuleInfo(module);
+}
+
 void SetupStabilityDebugging() {
   if (!base::FeatureList::IsEnabled(
           browser_watcher::kStabilityDebuggingFeature)) {
@@ -144,17 +173,8 @@
     global_data.SetString(browser_watcher::kStabilityPlatform, "Win64");
 #endif
 
-    // Record information about chrome's module.
-    global_data.SetUint(browser_watcher::kStabilityModuleAddress,
-                        reinterpret_cast<uint64_t>(&__ImageBase));
-
-    base::win::PEImage pe(&__ImageBase);
-    PIMAGE_NT_HEADERS headers = pe.GetNTHeaders();
-    CHECK(headers);
-    global_data.SetUint(browser_watcher::kStabilityModuleTimestamp,
-                        headers->FileHeader.TimeDateStamp);
-    global_data.SetUint(browser_watcher::kStabilityModuleSize,
-                        headers->OptionalHeader.SizeOfImage);
+    // Record information about chrome's module. We want this to be done early.
+    RecordChromeModuleInfo(global_tracker);
   }
 }
 #endif  // defined(OS_WIN)
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc
index aea197f1..7b06d9e 100644
--- a/chrome/browser/devtools/devtools_ui_bindings.cc
+++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -449,9 +449,8 @@
       content::NavigationHandle* navigation_handle) override;
   void DocumentAvailableInMainFrame() override;
   void DocumentOnLoadCompletedInMainFrame() override;
-  void DidNavigateMainFrame(
-      const content::LoadCommittedDetails& details,
-      const content::FrameNavigateParams& params) override;
+  void DidFinishNavigation(
+      content::NavigationHandle* navigation_handle) override;
 
   DevToolsUIBindings* devtools_bindings_;
   DISALLOW_COPY_AND_ASSIGN(FrontendWebContentsObserver);
@@ -506,9 +505,8 @@
 
 void DevToolsUIBindings::FrontendWebContentsObserver::ReadyToCommitNavigation(
     content::NavigationHandle* navigation_handle) {
-  if (!navigation_handle->IsInMainFrame())
-    return;
-  devtools_bindings_->UpdateFrontendHost(navigation_handle);
+  if (navigation_handle->IsInMainFrame())
+    devtools_bindings_->UpdateFrontendHost(navigation_handle);
 }
 
 void DevToolsUIBindings::FrontendWebContentsObserver::
@@ -521,10 +519,10 @@
   devtools_bindings_->DocumentOnLoadCompletedInMainFrame();
 }
 
-void DevToolsUIBindings::FrontendWebContentsObserver::
-    DidNavigateMainFrame(const content::LoadCommittedDetails& details,
-                         const content::FrameNavigateParams& params) {
-  devtools_bindings_->DidNavigateMainFrame();
+void DevToolsUIBindings::FrontendWebContentsObserver::DidFinishNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (navigation_handle->IsInMainFrame() && navigation_handle->HasCommitted())
+    devtools_bindings_->DidNavigateMainFrame();
 }
 
 // DevToolsUIBindings ---------------------------------------------------------
diff --git a/chrome/browser/dom_distiller/tab_utils.cc b/chrome/browser/dom_distiller/tab_utils.cc
index 6f03d4fd..f7985ff 100644
--- a/chrome/browser/dom_distiller/tab_utils.cc
+++ b/chrome/browser/dom_distiller/tab_utils.cc
@@ -20,6 +20,7 @@
 #include "components/dom_distiller/core/url_utils.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
 
@@ -49,9 +50,8 @@
   void OnArticleUpdated(ArticleDistillationUpdate article_update) override;
 
   // content::WebContentsObserver implementation.
-  void DidNavigateMainFrame(
-      const content::LoadCommittedDetails& details,
-      const content::FrameNavigateParams& params) override;
+  void DidFinishNavigation(
+      content::NavigationHandle* navigation_handle) override;
   void RenderProcessGone(base::TerminationStatus status) override;
   void WebContentsDestroyed() override;
 
@@ -65,9 +65,11 @@
   std::unique_ptr<ViewerHandle> viewer_handle_;
 };
 
-void SelfDeletingRequestDelegate::DidNavigateMainFrame(
-    const content::LoadCommittedDetails& details,
-    const content::FrameNavigateParams& params) {
+void SelfDeletingRequestDelegate::DidFinishNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted())
+    return;
+
   Observe(NULL);
   base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
 }
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 6197196..c1578c2a 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -357,7 +357,7 @@
 #endif
       globals_(nullptr),
       is_quic_allowed_by_policy_(true),
-      http_09_on_non_default_ports_enabled_(true),
+      http_09_on_non_default_ports_enabled_(false),
       creation_time_(base::TimeTicks::Now()),
       weak_factory_(this) {
   scoped_refptr<base::SingleThreadTaskRunner> io_thread_proxy =
diff --git a/chrome/browser/net/errorpage_browsertest.cc b/chrome/browser/net/errorpage_browsertest.cc
index 018c7aa..6e1fa82 100644
--- a/chrome/browser/net/errorpage_browsertest.cc
+++ b/chrome/browser/net/errorpage_browsertest.cc
@@ -1494,14 +1494,12 @@
   EXPECT_TRUE(IsDisplayingText(browser(), kHostnameJSUnicode));
 }
 
-// Make sure HTTP/0.9 is enabled on non-default ports by default.
+// Make sure HTTP/0.9 is disabled on non-default ports by default.
 IN_PROC_BROWSER_TEST_F(ErrorPageTest, Http09WeirdPort) {
-  const char kHttp09Response[] = "JumboShrimp";
   ASSERT_TRUE(embedded_test_server()->Start());
   ui_test_utils::NavigateToURL(
-      browser(), embedded_test_server()->GetURL(std::string("/echo-raw?") +
-                                                kHttp09Response));
-  EXPECT_TRUE(IsDisplayingText(browser(), kHttp09Response));
+      browser(), embedded_test_server()->GetURL("/echo-raw?spam"));
+  ExpectDisplayingLocalErrorPage(browser(), net::ERR_INVALID_HTTP_RESPONSE);
 }
 
 class ErrorPageWithHttp09OnNonDefaultPortsTest : public InProcessBrowserTest {
diff --git a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc
index 43fcb86..149dfff 100644
--- a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc
@@ -9,6 +9,11 @@
 
 namespace internal {
 
+const char kHistogramServiceWorkerParseStart[] =
+    "PageLoad.Clients.ServiceWorker.ParseTiming.NavigationToParseStart";
+const char kBackgroundHistogramServiceWorkerParseStart[] =
+    "PageLoad.Clients.ServiceWorker.ParseTiming.NavigationToParseStart."
+    "Background";
 const char kHistogramServiceWorkerFirstContentfulPaint[] =
     "PageLoad.Clients.ServiceWorker.PaintTiming."
     "NavigationToFirstContentfulPaint";
@@ -116,3 +121,18 @@
                         timing.load_event_start.value());
   }
 }
+
+void ServiceWorkerPageLoadMetricsObserver::OnParseStart(
+    const page_load_metrics::PageLoadTiming& timing,
+    const page_load_metrics::PageLoadExtraInfo& info) {
+  if (!IsServiceWorkerControlled(info))
+    return;
+  if (WasStartedInForegroundOptionalEventInForeground(timing.parse_start,
+                                                      info)) {
+    PAGE_LOAD_HISTOGRAM(internal::kHistogramServiceWorkerParseStart,
+                        timing.parse_start.value());
+  } else {
+    PAGE_LOAD_HISTOGRAM(internal::kBackgroundHistogramServiceWorkerParseStart,
+                        timing.parse_start.value());
+  }
+}
diff --git a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.h
index c34fcbe..d0e9c2f 100644
--- a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.h
@@ -11,6 +11,8 @@
 namespace internal {
 
 // Expose metrics for tests.
+extern const char kHistogramServiceWorkerParseStart[];
+extern const char kBackgroundHistogramServiceWorkerParseStart[];
 extern const char kHistogramServiceWorkerFirstContentfulPaint[];
 extern const char kBackgroundHistogramServiceWorkerFirstContentfulPaint[];
 extern const char kHistogramServiceWorkerParseStartToFirstContentfulPaint[];
@@ -29,6 +31,9 @@
  public:
   ServiceWorkerPageLoadMetricsObserver();
   // page_load_metrics::PageLoadMetricsObserver implementation:
+  void OnParseStart(
+      const page_load_metrics::PageLoadTiming& timing,
+      const page_load_metrics::PageLoadExtraInfo& extra_info) override;
   void OnFirstContentfulPaint(
       const page_load_metrics::PageLoadTiming& timing,
       const page_load_metrics::PageLoadExtraInfo& extra_info) override;
diff --git a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer_unittest.cc
index de5c3ce6..4b8161f 100644
--- a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer_unittest.cc
@@ -39,6 +39,10 @@
         internal::kHistogramServiceWorkerDomContentLoaded, 0);
     histogram_tester().ExpectTotalCount(internal::kHistogramServiceWorkerLoad,
                                         0);
+    histogram_tester().ExpectTotalCount(
+        internal::kHistogramServiceWorkerParseStart, 0);
+    histogram_tester().ExpectTotalCount(
+        internal::kBackgroundHistogramServiceWorkerParseStart, 0);
   }
 
   void AssertNoInboxHistogramsLogged() {
@@ -118,6 +122,9 @@
       internal::kHistogramServiceWorkerLoad,
       timing.load_event_start.value().InMilliseconds(), 1);
 
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramServiceWorkerParseStart, 1);
+
   AssertNoInboxHistogramsLogged();
 }
 
@@ -151,6 +158,8 @@
   histogram_tester().ExpectTotalCount(
       internal::kHistogramServiceWorkerDomContentLoaded, 0);
   histogram_tester().ExpectTotalCount(internal::kHistogramServiceWorkerLoad, 0);
+  histogram_tester().ExpectTotalCount(
+      internal::kBackgroundHistogramServiceWorkerParseStart, 1);
 
   AssertNoInboxHistogramsLogged();
 }
@@ -215,4 +224,6 @@
   histogram_tester().ExpectBucketCount(
       internal::kHistogramServiceWorkerLoadInbox,
       timing.load_event_start.value().InMilliseconds(), 1);
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramServiceWorkerParseStart, 1);
 }
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index c2b67ed..51c51b2 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -52,6 +52,7 @@
 #include "components/version_info/version_info.h"
 #include "content/public/browser/child_process_security_policy.h"
 #include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/ssl_status.h"
 #include "content/public/browser/web_contents.h"
@@ -381,9 +382,11 @@
     popup_controller_->HideAndDestroy();
 }
 
-void ChromePasswordManagerClient::DidNavigateMainFrame(
-    const content::LoadCommittedDetails& details,
-    const content::FrameNavigateParams& params) {
+void ChromePasswordManagerClient::DidFinishNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted())
+    return;
+
   password_reuse_detection_manager_.DidNavigateMainFrame(GetMainFrameURL());
   // After some navigations RenderViewHost persists and just adding the observer
   // will cause multiple call of OnInputEvent. Since Widget API doesn't allow to
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index be06164..c8d3c6f 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -129,9 +129,8 @@
   // content::WebContentsObserver overrides.
   void DidStartNavigation(
       content::NavigationHandle* navigation_handle) override;
-  void DidNavigateMainFrame(
-      const content::LoadCommittedDetails& details,
-      const content::FrameNavigateParams& params) override;
+  void DidFinishNavigation(
+      content::NavigationHandle* navigation_handle) override;
 
   // content::RenderWidgetHost::InputEventObserver overrides.
   void OnInputEvent(const blink::WebInputEvent&) override;
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.html b/chrome/browser/resources/settings/appearance_page/appearance_page.html
index b945c8f..3cb9b8f 100644
--- a/chrome/browser/resources/settings/appearance_page/appearance_page.html
+++ b/chrome/browser/resources/settings/appearance_page/appearance_page.html
@@ -91,7 +91,7 @@
         </div>
         <div class="settings-box"
             hidden="[[!pageVisibility.homeButton]]">
-          <settings-toggle-button class="start"
+          <settings-toggle-button class="start" elide-label
               pref="{{prefs.browser.show_home_button}}"
               label="$i18n{showHomeButton}"
               sub-label="[[getShowHomeSubLabel_(
diff --git a/chrome/browser/resources/settings/controls/settings_toggle_button.html b/chrome/browser/resources/settings/controls/settings_toggle_button.html
index fc96b83..add7e52 100644
--- a/chrome/browser/resources/settings/controls/settings_toggle_button.html
+++ b/chrome/browser/resources/settings/controls/settings_toggle_button.html
@@ -6,6 +6,16 @@
 <dom-module id="settings-toggle-button">
   <template>
     <style include="settings-shared">
+      :host([elide-label]),
+      :host([elide-label]) #outerRow,
+      :host([elide-label]) #outerRow > div.flex {
+        min-width: 0;
+      }
+
+      :host([elide-label]) .label {
+        @apply(--settings-text-elide);
+      }
+
       #outerRow {
         align-items: center;
         display: flex;
@@ -29,8 +39,8 @@
     <div id="outerRow" noSubLabel$="[[!subLabel]]">
       <div class="flex" on-tap="onLabelWrapperTap_"
           actionable$="[[!controlDisabled_(disabled, pref)]]">
-        <div>[[label]]</div>
-        <div class="secondary">[[subLabel]]</div>
+        <div class="label">[[label]]</div>
+        <div class="secondary label">[[subLabel]]</div>
       </div>
       <content selector=".more-actions"></content>
       <template is="dom-if" if="[[pref.controlledBy]]">
diff --git a/chrome/browser/resources/settings/controls/settings_toggle_button.js b/chrome/browser/resources/settings/controls/settings_toggle_button.js
index 35a0c02..fcfa247e 100644
--- a/chrome/browser/resources/settings/controls/settings_toggle_button.js
+++ b/chrome/browser/resources/settings/controls/settings_toggle_button.js
@@ -9,6 +9,13 @@
 Polymer({
   is: 'settings-toggle-button',
 
+  properties: {
+    elideLabel: {
+      type: Boolean,
+      reflectToAttribute: true,
+    },
+  },
+
   behaviors: [SettingsBooleanControlBehavior],
 
   /** @private */
diff --git a/chrome/browser/resources/settings/settings_shared_css.html b/chrome/browser/resources/settings/settings_shared_css.html
index d0cad3f..8170604 100644
--- a/chrome/browser/resources/settings/settings_shared_css.html
+++ b/chrome/browser/resources/settings/settings_shared_css.html
@@ -160,9 +160,7 @@
       }
 
       .text-elide {
-        overflow: hidden;
-        text-overflow: ellipsis;
-        white-space: nowrap;
+        @apply(--settings-text-elide);
       }
 
       /**
diff --git a/chrome/browser/resources/settings/settings_vars_css.html b/chrome/browser/resources/settings/settings_vars_css.html
index b3cbbf96..f3665f6e 100644
--- a/chrome/browser/resources/settings/settings_vars_css.html
+++ b/chrome/browser/resources/settings/settings_vars_css.html
@@ -42,6 +42,12 @@
     --settings-box-min-height: 48px;
     --settings-box-two-line-min-height: 60px;
 
+    --settings-text-elide: {
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    };
+
     --settings-secondary: {
       color: var(--paper-grey-600);
       font-weight: 400;
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
index 8c07d7e..737d0e4 100644
--- a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
+++ b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
@@ -33,116 +33,6 @@
   },
 
   /**
-   * A utility function to compute the description for the category.
-   * @param {string} category The category to show the description for.
-   * @param {string} setting The string value of the setting.
-   * @param {boolean} showRecommendation Whether to show the '(recommended)'
-   *     label prefix.
-   * @return {string} The category description.
-   * @protected
-   */
-  computeCategoryDesc: function(category, setting, showRecommendation) {
-    var categoryEnabled = this.computeIsSettingEnabled(setting);
-    switch (category) {
-      case settings.ContentSettingsTypes.JAVASCRIPT:
-        // "Allowed (recommended)" vs "Blocked".
-        if (!categoryEnabled) {
-          return loadTimeData.getString('siteSettingsBlocked');
-        }
-        return showRecommendation ?
-            loadTimeData.getString('siteSettingsAllowedRecommended') :
-            loadTimeData.getString('siteSettingsAllowed');
-      case settings.ContentSettingsTypes.POPUPS:
-        // "Allowed" vs "Blocked (recommended)".
-        if (categoryEnabled) {
-          return loadTimeData.getString('siteSettingsAllowed');
-        }
-        return showRecommendation ?
-            loadTimeData.getString('siteSettingsBlockedRecommended') :
-            loadTimeData.getString('siteSettingsBlocked');
-      case settings.ContentSettingsTypes.NOTIFICATIONS:
-        // "Ask before sending (recommended)" vs "Blocked".
-        if (!categoryEnabled) {
-          return loadTimeData.getString('siteSettingsBlocked');
-        }
-        return showRecommendation ?
-            loadTimeData.getString('siteSettingsAskBeforeSendingRecommended') :
-            loadTimeData.getString('siteSettingsAskBeforeSending');
-      case settings.ContentSettingsTypes.CAMERA:
-      case settings.ContentSettingsTypes.GEOLOCATION:
-      case settings.ContentSettingsTypes.MIC:
-        // "Ask before accessing (recommended)" vs "Blocked".
-        if (!categoryEnabled) {
-          return loadTimeData.getString('siteSettingsBlocked');
-        }
-        return showRecommendation ?
-            loadTimeData.getString(
-                'siteSettingsAskBeforeAccessingRecommended') :
-            loadTimeData.getString('siteSettingsAskBeforeAccessing');
-      case settings.ContentSettingsTypes.COOKIES:
-        // Tri-state: "Allow sites to save and read cookie data" vs "Blocked"
-        //     vs "Keep local data only until you quit your browser".
-        if (setting == settings.PermissionValues.BLOCK)
-          return loadTimeData.getString('siteSettingsBlocked');
-        if (setting == settings.PermissionValues.SESSION_ONLY)
-          return loadTimeData.getString('deleteDataPostSession');
-        return showRecommendation ?
-            loadTimeData.getString('siteSettingsCookiesAllowedRecommended') :
-            loadTimeData.getString('siteSettingsCookiesAllowed');
-      case settings.ContentSettingsTypes.PROTOCOL_HANDLERS:
-        // "Allow sites to ask to become default handlers" vs "Blocked".
-        if (!categoryEnabled) {
-          return loadTimeData.getString('siteSettingsHandlersBlocked');
-        }
-        return showRecommendation ?
-            loadTimeData.getString('siteSettingsHandlersAskRecommended') :
-            loadTimeData.getString('siteSettingsHandlersAsk');
-      case settings.ContentSettingsTypes.IMAGES:
-        if (!categoryEnabled) {
-          return loadTimeData.getString('siteSettingsDontShowImages');
-        }
-        return showRecommendation ?
-            loadTimeData.getString('siteSettingsShowAllRecommended') :
-            loadTimeData.getString('siteSettingsShowAll');
-      case settings.ContentSettingsTypes.PLUGINS:
-        if (setting == settings.PermissionValues.ALLOW)
-          return loadTimeData.getString('siteSettingsFlashAllow');
-        if (setting == settings.PermissionValues.BLOCK)
-          return loadTimeData.getString('siteSettingsFlashBlock');
-        return loadTimeData.getString('siteSettingsFlashAskBefore');
-      case settings.ContentSettingsTypes.BACKGROUND_SYNC:
-        // "Allow sites to finish sending and receiving data" vs "Do not allow".
-        if (!categoryEnabled) {
-          return loadTimeData.getString('siteSettingsBackgroundSyncBlocked');
-        }
-        return showRecommendation ?
-            loadTimeData.getString(
-                 'siteSettingsAllowRecentlyClosedSitesRecommended') :
-            loadTimeData.getString('siteSettingsAllowRecentlyClosedSites');
-      case settings.ContentSettingsTypes.AUTOMATIC_DOWNLOADS:
-        // "Ask when a site wants to auto-download multiple" vs "Do not allow".
-        if (!categoryEnabled) {
-          return loadTimeData.getString('siteSettingsAutoDownloadBlock');
-        }
-        return showRecommendation ?
-            loadTimeData.getString('siteSettingsAutoDownloadAskRecommended') :
-            loadTimeData.getString('siteSettingsAutoDownloadAsk');
-      case settings.ContentSettingsTypes.UNSANDBOXED_PLUGINS:
-        // "Ask when a plugin accesses your computer" vs "Do not allow".
-        if (!categoryEnabled) {
-          return loadTimeData.getString('siteSettingsUnsandboxedPluginsBlock');
-        }
-        return showRecommendation ?
-            loadTimeData.getString(
-                'siteSettingsUnsandboxedPluginsAskRecommended') :
-            loadTimeData.getString('siteSettingsUnsandboxedPluginsAsk');
-      default:
-        assertNotReached('Invalid category: ' + category);
-        return '';
-    }
-  },
-
-  /**
    * Ensures the URL has a scheme (assumes http if omitted).
    * @param {string} url The URL with or without a scheme.
    * @return {string} The URL with a scheme, or an empty string.
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.html b/chrome/browser/resources/settings/site_settings_page/site_settings_page.html
index cb801ce9..1d43797 100644
--- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.html
+++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.html
@@ -27,7 +27,13 @@
       <iron-icon icon="settings:cookie"></iron-icon>
       <div class="middle">
         <div>$i18n{siteSettingsCookies}</div>
-        <div class="secondary">[[default_.cookies]]</div>
+        <div class="secondary">
+          [[defaultSettingLabel_(
+              default_.cookies,
+              '$i18n{siteSettingsCookiesAllowed}',
+              '$i18n{siteSettingsBlocked}',
+              '$i18n{deleteDataPostSession}')]]
+        </div>
       </div>
       <button class="subpage-arrow" is="paper-icon-button-light"></button>
     </div>
@@ -37,7 +43,12 @@
       <iron-icon icon="settings:location-on"></iron-icon>
       <div class="middle">
         <div>$i18n{siteSettingsLocation}</div>
-        <div class="secondary">[[default_.location]]</div>
+        <div class="secondary">
+          [[defaultSettingLabel_(
+              default_.location,
+              '$i18n{siteSettingsAskBeforeAccessing}',
+              '$i18n{siteSettingsBlocked}')]]
+        </div>
       </div>
       <button class="subpage-arrow" is="paper-icon-button-light"></button>
     </div>
@@ -48,7 +59,12 @@
       <iron-icon icon="settings:videocam"></iron-icon>
       <div class="middle">
         <div>$i18n{siteSettingsCamera}</div>
-        <div class="secondary">[[default_.mediaStreamCamera]]</div>
+        <div class="secondary">
+          [[defaultSettingLabel_(
+              default_.mediaStreamCamera,
+              '$i18n{siteSettingsAskBeforeAccessing}',
+              '$i18n{siteSettingsBlocked}')]]
+        </div>
       </div>
       <button class="subpage-arrow" is="paper-icon-button-light"></button>
     </div>
@@ -58,7 +74,12 @@
       <iron-icon icon="settings:mic"></iron-icon>
       <div class="middle">
         $i18n{siteSettingsMic}
-        <div class="secondary">[[default_.mediaStreamMic]]</div>
+        <div class="secondary">
+          [[defaultSettingLabel_(
+              default_.mediaStreamMic,
+              '$i18n{siteSettingsAskBeforeAccessing}',
+              '$i18n{siteSettingsBlocked}')]]
+        </div>
       </div>
       <button class="subpage-arrow" is="paper-icon-button-light"></button>
     </div>
@@ -69,7 +90,12 @@
       <iron-icon icon="settings:notifications"></iron-icon>
       <div class="middle">
         $i18n{siteSettingsNotifications}
-        <div class="secondary">[[default_.notifications]]</div>
+        <div class="secondary">
+          [[defaultSettingLabel_(
+              default_.notifications,
+              '$i18n{siteSettingsAskBeforeSending}',
+              '$i18n{siteSettingsBlocked}')]]
+        </div>
       </div>
       <button class="subpage-arrow" is="paper-icon-button-light"></button>
     </div>
@@ -80,7 +106,12 @@
       <iron-icon icon="settings:input"></iron-icon>
       <div class="middle">
         $i18n{siteSettingsJavascript}
-        <div class="secondary">[[default_.javascript]]</div>
+        <div class="secondary">
+          [[defaultSettingLabel_(
+              default_.javascript,
+              '$i18n{siteSettingsAllowed}',
+              '$i18n{siteSettingsBlocked}')]]
+        </div>
       </div>
       <button class="subpage-arrow" is="paper-icon-button-light"></button>
     </div>
@@ -90,7 +121,13 @@
       <iron-icon icon="cr:extension"></iron-icon>
       <div class="middle">
         $i18n{siteSettingsFlash}
-        <div class="secondary">[[default_.plugins]]</div>
+        <div class="secondary">
+          [[defaultSettingLabel_(
+              default_.plugins,
+              '$i18n{siteSettingsFlashAllow}',
+              '$i18n{siteSettingsFlashBlock}',
+              '$i18n{siteSettingsFlashAskBefore}')]]
+        </div>
       </div>
       <button class="subpage-arrow" is="paper-icon-button-light"></button>
     </div>
@@ -100,7 +137,12 @@
       <iron-icon icon="settings:photo"></iron-icon>
       <div class="middle">
         $i18n{siteSettingsImages}
-        <div class="secondary">[[default_.images]]</div>
+        <div class="secondary">
+          [[defaultSettingLabel_(
+              default_.images,
+              '$i18n{siteSettingsShowAll}',
+              '$i18n{siteSettingsDontShowImages}')]]
+        </div>
       </div>
       <button class="subpage-arrow" is="paper-icon-button-light"></button>
     </div>
@@ -110,7 +152,12 @@
       <iron-icon icon="cr:open-in-new"></iron-icon>
       <div class="middle">
         $i18n{siteSettingsPopups}
-        <div class="secondary">[[default_.popups]]</div>
+        <div class="secondary">
+          [[defaultSettingLabel_(
+              default_.popups,
+              '$i18n{siteSettingsAllowed}',
+              '$i18n{siteSettingsBlocked}')]]
+        </div>
       </div>
       <button class="subpage-arrow" is="paper-icon-button-light"></button>
     </div>
@@ -121,7 +168,12 @@
       <iron-icon icon="settings:sync"></iron-icon>
       <div class="middle">
         $i18n{siteSettingsBackgroundSync}
-        <div class="secondary">[[default_.backgroundSync]]</div>
+        <div class="secondary">
+          [[defaultSettingLabel_(
+              default_.backgroundSync,
+              '$i18n{siteSettingsAllowRecentlyClosedSites}',
+              '$i18n{siteSettingsBackgroundSyncBlocked}')]]
+        </div>
       </div>
       <button class="subpage-arrow" is="paper-icon-button-light"></button>
     </div>
@@ -132,7 +184,12 @@
       <iron-icon icon="cr:file-download"></iron-icon>
       <div class="middle">
         $i18n{siteSettingsAutomaticDownloads}
-        <div class="secondary">[[default_.multipleAutomaticDownloads]]</div>
+        <div class="secondary">
+          [[defaultSettingLabel_(
+              default_.multipleAutomaticDownloads,
+              '$i18n{siteSettingsAutoDownloadAsk}',
+              '$i18n{siteSettingsAutoDownloadBlock}')]]
+        </div>
       </div>
       <button class="subpage-arrow" is="paper-icon-button-light"></button>
     </div>
@@ -143,7 +200,12 @@
       <iron-icon icon="cr:extension"></iron-icon>
       <div class="middle">
         $i18n{siteSettingsUnsandboxedPlugins}
-        <div class="secondary">[[default_.ppapiBroker]]</div>
+        <div class="secondary">
+          [[defaultSettingLabel_(
+              default_.ppapiBroker,
+              '$i18n{siteSettingsUnsandboxedPluginsAsk}',
+              '$i18n{siteSettingsUnsandboxedPluginsBlock}')]]
+        </div>
       </div>
       <button class="subpage-arrow" is="paper-icon-button-light"></button>
     </div>
@@ -154,7 +216,12 @@
       <iron-icon icon="settings:protocol-handler"></iron-icon>
       <div class="middle">
         $i18n{siteSettingsHandlers}
-        <div class="secondary">[[default_.registerProtocolHandler]]</div>
+        <div class="secondary">
+          [[defaultSettingLabel_(
+              default_.registerProtocolHandler,
+              '$i18n{siteSettingsHandlersAsk}',
+              '$i18n{siteSettingsHandlersBlocked}')]]
+        </div>
       </div>
       <button class="subpage-arrow" is="paper-icon-button-light"></button>
     </div>
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
index 69701bf..e3be214 100644
--- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
+++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
@@ -7,6 +7,7 @@
  * 'settings-site-settings-page' is the settings page containing privacy and
  * security site settings.
  */
+
 Polymer({
   is: 'settings-site-settings-page',
 
@@ -14,7 +15,7 @@
 
   properties: {
     /**
-     * An object to bind default value labels to (so they are not in the |this|
+     * An object to bind default values to (so they are not in the |this|
      * scope). The keys of this object are the values of the
      * settings.ContentSettingsTypes enum.
      * @private
@@ -60,6 +61,23 @@
   },
 
   /**
+   * @param {string} setting Value from settings.PermissionValues.
+   * @param {string} enabled Non-block label ('feature X not allowed').
+   * @param {string} disabled Block label (likely just, 'Blocked').
+   * @param {?string} other Tristate value (maybe, 'session only').
+   * @private
+   */
+  defaultSettingLabel_: function(setting, enabled, disabled, other) {
+    if (setting == settings.PermissionValues.BLOCK)
+      return disabled;
+    if (setting == settings.PermissionValues.ALLOW)
+      return enabled;
+    if (other)
+      return other;
+    return enabled;
+  },
+
+  /**
    * @param {string} category The category to update.
    * @private
    */
@@ -68,10 +86,7 @@
         category).then(function(defaultValue) {
           this.set(
               'default_.' + Polymer.CaseMap.dashToCamelCase(category),
-              this.computeCategoryDesc(
-                  category,
-                  defaultValue.setting,
-                  /*showRecommendation=*/false));
+              defaultValue.setting);
         }.bind(this));
   },
 
@@ -84,12 +99,9 @@
     var category = settings.ContentSettingsTypes.PROTOCOL_HANDLERS;
     this.set(
         'default_.' + Polymer.CaseMap.dashToCamelCase(category),
-        this.computeCategoryDesc(
-            category,
-            enabled ?
-                settings.PermissionValues.ALLOW :
-                settings.PermissionValues.BLOCK,
-            /*showRecommendation=*/false));
+        enabled ?
+            settings.PermissionValues.ALLOW :
+            settings.PermissionValues.BLOCK);
   },
 
   /**
diff --git a/chrome/browser/resources/signin/signin_error/signin_error.js b/chrome/browser/resources/signin/signin_error/signin_error.js
index 0abdaa28..749c99b 100644
--- a/chrome/browser/resources/signin/signin_error/signin_error.js
+++ b/chrome/browser/resources/signin/signin_error/signin_error.js
@@ -14,7 +14,11 @@
     if (loadTimeData.getBoolean('isSystemProfile')) {
       $('learnMoreLink').hidden = true;
     }
-    chrome.send('initializedWithSize', [document.body.scrollHeight]);
+
+    // Prefer using |document.body.offsetHeight| instead of
+    // |document.body.scrollHeight| as it returns the correct height of the
+    // even when the page zoom in Chrome is different than 100%.
+    chrome.send('initializedWithSize', [document.body.offsetHeight]);
   }
 
   function onKeyDown(e) {
diff --git a/chrome/browser/resources/signin/signin_shared_css.html b/chrome/browser/resources/signin/signin_shared_css.html
index a350d03..5b58be1 100644
--- a/chrome/browser/resources/signin/signin_shared_css.html
+++ b/chrome/browser/resources/signin/signin_shared_css.html
@@ -9,10 +9,8 @@
 
       body {
         margin: 0;
-        /* Scrollbars are hidden as the sign-in dialogs are automatically
-         * resized. */
-        overflow: hidden;
         padding: 0;
+        zoom: reset;
       }
 
       paper-button {
@@ -49,9 +47,6 @@
       .container {
         background-color: white;
         color: #333;
-        /* Scrollbars are hidden as the sign-in dialogs are automatically
-         * resized. */
-        overflow: hidden;
         width: 448px;
       }
 
diff --git a/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.js b/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.js
index 0a08712..1f51ec8 100644
--- a/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.js
+++ b/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.js
@@ -28,7 +28,11 @@
     } else {
       $('syncConfirmationDetails').hidden = true;
     }
-    chrome.send('initializedWithSize', [document.body.scrollHeight]);
+
+    // Prefer using |document.body.offsetHeight| instead of
+    // |document.body.scrollHeight| as it returns the correct height of the
+    // even when the page zoom in Chrome is different than 100%.
+    chrome.send('initializedWithSize', [document.body.offsetHeight]);
   }
 
   function clearFocus() {
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 8fcbaed73..8c4e1f7 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -813,8 +813,6 @@
       "startup/google_api_keys_infobar_delegate.h",
       "startup/obsolete_system_infobar_delegate.cc",
       "startup/obsolete_system_infobar_delegate.h",
-      "startup/session_crashed_infobar_delegate.cc",
-      "startup/session_crashed_infobar_delegate.h",
       "startup/startup_browser_creator.cc",
       "startup/startup_browser_creator.h",
       "startup/startup_browser_creator_impl.cc",
@@ -1802,6 +1800,8 @@
         "views/payments/payment_request_dialog_view.cc",
         "views/payments/payment_request_dialog_view.h",
         "views/payments/payment_request_dialog_view_ids.h",
+        "views/payments/payment_request_row_view.cc",
+        "views/payments/payment_request_row_view.h",
         "views/payments/payment_request_sheet_controller.h",
         "views/payments/payment_request_views_util.cc",
         "views/payments/payment_request_views_util.h",
@@ -2027,6 +2027,10 @@
         "views/profiles/new_avatar_button.cc",
         "views/profiles/new_avatar_button.h",
       ]
+      sources += [
+        "startup/session_crashed_infobar_delegate.cc",
+        "startup/session_crashed_infobar_delegate.h",
+      ]
     }
   }
   if (use_aura) {
diff --git a/chrome/browser/ui/app_list/start_page_service.cc b/chrome/browser/ui/app_list/start_page_service.cc
index f61f792..5e7d505 100644
--- a/chrome/browser/ui/app_list/start_page_service.cc
+++ b/chrome/browser/ui/app_list/start_page_service.cc
@@ -40,6 +40,7 @@
 #include "components/search_engines/template_url_service.h"
 #include "components/zoom/zoom_controller.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -557,12 +558,24 @@
   network_change_observer_.reset();
 }
 
-void StartPageService::DidNavigateMainFrame(
-    const content::LoadCommittedDetails& /*details*/,
-    const content::FrameNavigateParams& /*params*/) {
-  // Set the zoom level in DidNavigateMainFrame, as this is the earliest point
+void StartPageService::DidFinishNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted())
+    return;
+
+  if (navigation_handle->IsErrorPage()) {
+    // This avoids displaying a "Webpage Blocked" error or similar (which can
+    // happen if the URL is blacklisted by enterprise policy).
+    content::BrowserThread::PostTask(
+        content::BrowserThread::UI, FROM_HERE,
+        base::Bind(&StartPageService::UnloadContents,
+                   weak_factory_.GetWeakPtr()));
+    return;
+  }
+
+  // Set the zoom level in DidFinishNavigation, as this is the earliest point
   // at which it can be done and not be affected by the ZoomController's
-  // DidNavigateMainFrame handler.
+  // DidFinishNavigation handler.
   //
   // Use a temporary zoom level for this web contents (aka isolated zoom
   // mode) so changes to its zoom aren't reflected in any preferences.
@@ -573,19 +586,6 @@
   zoom::ZoomController::FromWebContents(contents_.get())->SetZoomLevel(0);
 }
 
-void StartPageService::DidFailProvisionalLoad(
-    content::RenderFrameHost* render_frame_host,
-    const GURL& validated_url,
-    int error_code,
-    const base::string16& error_description,
-    bool was_ignored_by_handler) {
-  // This avoids displaying a "Webpage Blocked" error or similar (which can
-  // happen if the URL is blacklisted by enterprise policy).
-  content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
-                                   base::Bind(&StartPageService::UnloadContents,
-                                              weak_factory_.GetWeakPtr()));
-}
-
 void StartPageService::WebUILoaded() {
   // There's a race condition between the WebUI loading, and calling its JS
   // functions. Specifically, calling LoadContents() doesn't mean that the page
diff --git a/chrome/browser/ui/app_list/start_page_service.h b/chrome/browser/ui/app_list/start_page_service.h
index 30200759..5181982 100644
--- a/chrome/browser/ui/app_list/start_page_service.h
+++ b/chrome/browser/ui/app_list/start_page_service.h
@@ -28,8 +28,6 @@
 #include "ui/app_list/speech_ui_model_observer.h"
 
 namespace content {
-struct FrameNavigateParams;
-struct LoadCommittedDetails;
 struct SpeechRecognitionSessionPreamble;
 }
 
@@ -144,14 +142,8 @@
   void Shutdown() override;
 
   // contents::WebContentsObserver overrides;
-  void DidNavigateMainFrame(
-      const content::LoadCommittedDetails& details,
-      const content::FrameNavigateParams& params) override;
-  void DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host,
-                              const GURL& validated_url,
-                              int error_code,
-                              const base::string16& error_description,
-                              bool was_ignored_by_handler) override;
+  void DidFinishNavigation(
+      content::NavigationHandle* navigation_handle) override;
 
   // Change the known microphone availability. |available| should be true if
   // the microphone exists and is available for use.
diff --git a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.h b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.h
index d0c6e4a..fe1c52ba 100644
--- a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.h
+++ b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.h
@@ -17,6 +17,7 @@
 
 @class ContentSettingAnimationState;
 @class ContentSettingBubbleController;
+class ContentSettingDecorationTest;
 class ContentSettingImageModel;
 class LocationBarViewMac;
 class Profile;
@@ -49,6 +50,7 @@
   virtual void AnimationTimerFired();
 
  private:
+  friend class ContentSettingDecorationTest;
 
   void SetToolTip(NSString* tooltip);
 
diff --git a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration_browsertest.mm b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration_browsertest.mm
new file mode 100644
index 0000000..916d33d
--- /dev/null
+++ b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration_browsertest.mm
@@ -0,0 +1,63 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/ui/cocoa/location_bar/content_setting_decoration.h"
+
+#include "chrome/browser/ui/browser_window.h"
+#import "chrome/browser/ui/cocoa/browser_window_controller.h"
+#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
+#include "chrome/browser/ui/content_settings/content_setting_image_model.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/test/test_utils.h"
+
+class ContentSettingDecorationTest : public InProcessBrowserTest {
+ protected:
+  ContentSettingDecorationTest() : InProcessBrowserTest() {}
+
+  void SetUpOnMainThread() override {
+    std::unique_ptr<ContentSettingImageModel> content_setting_image_model(
+        ContentSettingSimpleImageModel::CreateForContentTypeForTesting(
+            CONTENT_SETTINGS_TYPE_GEOLOCATION));
+    BrowserWindowController* controller = [BrowserWindowController
+        browserWindowControllerForWindow:browser()
+                                             ->window()
+                                             ->GetNativeWindow()];
+
+    content_setting_decoration_.reset(new ContentSettingDecoration(
+        std::move(content_setting_image_model), [controller locationBarBridge],
+        browser()->profile()));
+  }
+
+  // Returns the content settings bubble window anchored to
+  // |content_setting_decoration_|.
+  NSWindow* GetBubbleWindow() const {
+    return content_setting_decoration_->bubbleWindow_.get();
+  }
+
+  // Simulates a mouse press on the decoration.
+  void PressDecoration() {
+    content_setting_decoration_->OnMousePressed(NSZeroRect, NSZeroPoint);
+  }
+
+ private:
+  std::unique_ptr<ContentSettingDecoration> content_setting_decoration_;
+
+  DISALLOW_COPY_AND_ASSIGN(ContentSettingDecorationTest);
+};
+
+// Tests to check if pressing the decoration will open/close the content
+// settings bubble.
+IN_PROC_BROWSER_TEST_F(ContentSettingDecorationTest, DecorationPress) {
+  // Bubble should appear.
+  PressDecoration();
+  EXPECT_TRUE(GetBubbleWindow());
+
+  // Bubble should be closed.
+  PressDecoration();
+  EXPECT_FALSE(GetBubbleWindow());
+
+  // Bubble should reappear.
+  PressDecoration();
+  EXPECT_TRUE(GetBubbleWindow());
+}
diff --git a/chrome/browser/ui/startup/session_crashed_infobar_delegate.h b/chrome/browser/ui/startup/session_crashed_infobar_delegate.h
index fe3e1c4..21021e4c 100644
--- a/chrome/browser/ui/startup/session_crashed_infobar_delegate.h
+++ b/chrome/browser/ui/startup/session_crashed_infobar_delegate.h
@@ -12,6 +12,9 @@
 class Profile;
 
 // A delegate for the InfoBar shown when the previous session has crashed.
+//
+// TODO: remove this class once mac supports SessionCrashedBubble.
+// http://crbug.com/653966.
 class SessionCrashedInfoBarDelegate : public ConfirmInfoBarDelegate {
  public:
   // If |browser| is not incognito, creates a session crashed infobar and
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
index 1b5e7da..856bb1a 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -71,7 +71,6 @@
 #include "chrome/browser/ui/startup/default_browser_prompt.h"
 #include "chrome/browser/ui/startup/google_api_keys_infobar_delegate.h"
 #include "chrome/browser/ui/startup/obsolete_system_infobar_delegate.h"
-#include "chrome/browser/ui/startup/session_crashed_infobar_delegate.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "chrome/browser/ui/startup/startup_features.h"
 #include "chrome/browser/ui/tabs/pinned_tab_codec.h"
@@ -105,12 +104,17 @@
 #include "net/base/network_change_notifier.h"
 #include "rlz/features/features.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/base/ui_features.h"
 
 #if defined(OS_MACOSX)
 #include "base/mac/mac_util.h"
 #include "chrome/browser/ui/cocoa/keystone_infobar_delegate.h"
 #endif
 
+#if defined(OS_MACOSX) && !BUILDFLAG(MAC_VIEWS_BROWSER)
+#include "chrome/browser/ui/startup/session_crashed_infobar_delegate.h"
+#endif
+
 #if defined(OS_WIN)
 #include "base/win/windows_version.h"
 #include "chrome/browser/apps/app_launch_for_metro_restart_win.h"
@@ -797,7 +801,9 @@
 
   if (HasPendingUncleanExit(browser->profile()) &&
       !SessionCrashedBubble::Show(browser)) {
+#if defined(OS_MACOSX) && !BUILDFLAG(MAC_VIEWS_BROWSER)
     SessionCrashedInfoBarDelegate::Create(browser);
+#endif
   }
 
   // The below info bars are only added to the first profile which is launched.
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc
index 2f198b5..5ab7444a 100644
--- a/chrome/browser/ui/views/content_setting_bubble_contents.cc
+++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
@@ -22,6 +22,7 @@
 #include "chrome/grit/generated_resources.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/strings/grit/components_strings.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/cursor/cursor.h"
@@ -462,9 +463,11 @@
   return l10n_util::GetStringUTF16(IDS_DONE);
 }
 
-void ContentSettingBubbleContents::DidNavigateMainFrame(
-    const content::LoadCommittedDetails& details,
-    const content::FrameNavigateParams& params) {
+void ContentSettingBubbleContents::DidFinishNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted())
+    return;
+
   // Content settings are based on the main frame, so if it switches then
   // close up shop.
   GetWidget()->Close();
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.h b/chrome/browser/ui/views/content_setting_bubble_contents.h
index f2fd50d..298eea5 100644
--- a/chrome/browser/ui/views/content_setting_bubble_contents.h
+++ b/chrome/browser/ui/views/content_setting_bubble_contents.h
@@ -93,9 +93,8 @@
   typedef std::map<views::Link*, int> ListItemLinks;
 
   // content::WebContentsObserver:
-  void DidNavigateMainFrame(
-      const content::LoadCommittedDetails& details,
-      const content::FrameNavigateParams& params) override;
+  void DidFinishNavigation(
+      content::NavigationHandle* navigation_handle) override;
 
   // views::ButtonListener:
   void ButtonPressed(views::Button* sender, const ui::Event& event) override;
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index cada439..3b3b4dd 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -81,7 +81,6 @@
 #include "chrome/browser/ui/views/new_back_shortcut_bubble.h"
 #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
 #include "chrome/browser/ui/views/profiles/profile_indicator_icon.h"
-#include "chrome/browser/ui/views/session_crashed_bubble_view.h"
 #include "chrome/browser/ui/views/status_bubble_views.h"
 #include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h"
 #include "chrome/browser/ui/views/tabs/tab.h"
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller.cc b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
index b0f0cc7..f0f33f91 100644
--- a/chrome/browser/ui/views/payments/order_summary_view_controller.cc
+++ b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
@@ -43,12 +43,17 @@
                                                 DialogViewID amount_label_id) {
   std::unique_ptr<views::View> row = base::MakeUnique<views::View>();
 
-  row->SetBorder(views::CreateSolidSidedBorder(0, 0, 1, 0, SK_ColorLTGRAY));
+  row->SetBorder(payments::CreatePaymentRequestRowBorder());
 
   views::GridLayout* layout = new views::GridLayout(row.get());
 
+  // The vertical spacing for these rows is slightly different than the spacing
+  // spacing for clickable rows, so don't use kPaymentRequestRowVerticalInsets.
   constexpr int kRowVerticalInset = 12;
-  layout->SetInsets(kRowVerticalInset, 0, kRowVerticalInset, 0);
+  layout->SetInsets(kRowVerticalInset,
+                    payments::kPaymentRequestRowHorizontalInsets,
+                    kRowVerticalInset,
+                    payments::kPaymentRequestRowHorizontalInsets);
 
   row->SetLayoutManager(layout);
   views::ColumnSet* columns = layout->AddColumnSet(0);
diff --git a/chrome/browser/ui/views/payments/payment_request_row_view.cc b/chrome/browser/ui/views/payments/payment_request_row_view.cc
new file mode 100644
index 0000000..28365b9
--- /dev/null
+++ b/chrome/browser/ui/views/payments/payment_request_row_view.cc
@@ -0,0 +1,32 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/payments/payment_request_row_view.h"
+
+#include "chrome/browser/ui/views/payments/payment_request_views_util.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/views/background.h"
+#include "ui/views/border.h"
+
+namespace payments {
+
+PaymentRequestRowView::PaymentRequestRowView(
+    views::ButtonListener* listener)
+  : views::CustomButton(listener) {
+  SetBorder(payments::CreatePaymentRequestRowBorder());
+}
+
+PaymentRequestRowView::~PaymentRequestRowView() {}
+
+// views::CustomButton:
+void PaymentRequestRowView::StateChanged() {
+  if (state() == views::Button::STATE_HOVERED ||
+      state() == views::Button::STATE_PRESSED) {
+    set_background(views::Background::CreateSolidBackground(SK_ColorLTGRAY));
+  } else {
+    set_background(nullptr);
+  }
+}
+
+}  // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_row_view.h b/chrome/browser/ui/views/payments/payment_request_row_view.h
new file mode 100644
index 0000000..f8664343
--- /dev/null
+++ b/chrome/browser/ui/views/payments/payment_request_row_view.h
@@ -0,0 +1,29 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_ROW_VIEW_H_
+#define CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_ROW_VIEW_H_
+
+#include "base/macros.h"
+#include "ui/views/controls/button/custom_button.h"
+
+namespace payments {
+
+// This class implements a clickable row of the Payment Request dialog that
+// darkens on hover and displays a horizontal ruler on its lower bound.
+class PaymentRequestRowView : public views::CustomButton {
+ public:
+  explicit PaymentRequestRowView(views::ButtonListener* listener);
+  ~PaymentRequestRowView() override;
+
+  // views::CustomButton:
+  void StateChanged() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PaymentRequestRowView);
+};
+
+}  // namespace payments
+
+#endif  // CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_ROW_VIEW_H_
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc
index 6e7643ab..2c8e2dd 100644
--- a/chrome/browser/ui/views/payments/payment_request_views_util.cc
+++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -6,6 +6,7 @@
 
 #include <vector>
 
+#include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/vector_icons/vector_icons.h"
@@ -14,13 +15,19 @@
 #include "components/autofill/core/browser/autofill_type.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "third_party/skia/include/core/SkColor.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/geometry/point_f.h"
+#include "ui/gfx/paint_vector_icon.h"
 #include "ui/views/background.h"
+#include "ui/views/border.h"
 #include "ui/views/bubble/bubble_frame_view.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/button/vector_icon_button.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/controls/styled_label.h"
 #include "ui/views/layout/grid_layout.h"
+#include "ui/views/painter.h"
 #include "ui/views/view.h"
 
 namespace {
@@ -42,6 +49,31 @@
   return profile.ConstructInferredLabel(fields, fields.size(), locale);
 }
 
+// Paints the gray horizontal line that doesn't span the entire width of the
+// dialog at the bottom of the view it borders.
+class PaymentRequestRowBorderPainter : public views::Painter {
+ public:
+  PaymentRequestRowBorderPainter() {}
+  ~PaymentRequestRowBorderPainter() override {}
+
+  // views::Painter:
+  gfx::Size GetMinimumSize() const override {
+    return gfx::Size(2 * payments::kPaymentRequestRowHorizontalInsets, 1);
+  }
+
+  void Paint(gfx::Canvas* canvas, const gfx::Size& size) override {
+    int line_height = size.height() - 1;
+    canvas->DrawLine(
+        gfx::PointF(payments::kPaymentRequestRowHorizontalInsets, line_height),
+        gfx::PointF(size.width() - payments::kPaymentRequestRowHorizontalInsets,
+                    line_height),
+        SK_ColorLTGRAY);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PaymentRequestRowBorderPainter);
+};
+
 }  // namespace
 
 namespace payments {
@@ -53,6 +85,8 @@
   std::unique_ptr<views::View> container = base::MakeUnique<views::View>();
   views::GridLayout* layout = new views::GridLayout(container.get());
   container->SetLayoutManager(layout);
+  layout->SetInsets(0, kPaymentRequestRowHorizontalInsets,
+                    0, kPaymentRequestRowHorizontalInsets);
 
   views::ColumnSet* columns = layout->AddColumnSet(0);
   // A column for the optional back arrow.
@@ -97,9 +131,7 @@
 
   constexpr int kTopInsetSize = 9;
   constexpr int kBottomInsetSize = 18;
-  constexpr int kSideInsetSize = 14;
-  layout->SetInsets(
-      kTopInsetSize, kSideInsetSize, kBottomInsetSize, kSideInsetSize);
+  layout->SetInsets(kTopInsetSize, 0, kBottomInsetSize, 0);
   views::ColumnSet* columns = layout->AddColumnSet(0);
   columns->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER,
                      1, views::GridLayout::USE_PREF, 0, 0);
@@ -181,4 +213,12 @@
       base::JoinString(values, base::ASCIIToUTF16("\n")), nullptr);
 }
 
+// Creates a views::Border object that can paint the gray horizontal ruler used
+// as a separator between items in the Payment Request dialog.
+std::unique_ptr<views::Border> CreatePaymentRequestRowBorder() {
+  return views::CreateBorderPainter(
+      base::MakeUnique<PaymentRequestRowBorderPainter>(),
+      gfx::Insets());
+}
+
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.h b/chrome/browser/ui/views/payments/payment_request_views_util.h
index 9176241..13e2506 100644
--- a/chrome/browser/ui/views/payments/payment_request_views_util.h
+++ b/chrome/browser/ui/views/payments/payment_request_views_util.h
@@ -15,12 +15,16 @@
 }
 
 namespace views {
+class Border;
 class VectorIconButtonDelegate;
 class View;
 }
 
 namespace payments {
 
+constexpr int kPaymentRequestRowHorizontalInsets = 14;
+constexpr int kPaymentRequestRowVerticalInsets = 8;
+
 enum class PaymentRequestCommonTags {
   BACK_BUTTON_TAG = 0,
   CLOSE_BUTTON_TAG,
@@ -81,6 +85,10 @@
     bool show_payer_email,
     bool show_payer_phone);
 
+// Creates a views::Border object that can paint the gray horizontal ruler used
+// as a separator between items in the Payment Request dialog.
+std::unique_ptr<views::Border> CreatePaymentRequestRowBorder();
+
 }  // namespace payments
 
 #endif  // CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_VIEWS_UTIL_H_
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
index bbb83db..e337ee1 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -9,12 +9,14 @@
 #include <utility>
 #include <vector>
 
+#include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h"
 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h"
+#include "chrome/browser/ui/views/payments/payment_request_row_view.h"
 #include "chrome/browser/ui/views/payments/payment_request_views_util.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/autofill/core/browser/autofill_data_util.h"
@@ -26,16 +28,13 @@
 #include "components/payments/payment_request.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/web_contents.h"
-#include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/gfx/font.h"
-#include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/gfx/range/range.h"
 #include "ui/views/border.h"
-#include "ui/views/controls/button/custom_button.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/controls/button/md_text_button.h"
 #include "ui/views/controls/image_view.h"
@@ -60,86 +59,6 @@
   SHOW_CONTACT_INFO_BUTTON,
 };
 
-// Creates a clickable row to be displayed in the Payment Sheet. It contains
-// a section name and some content, followed by a chevron as a clickability
-// affordance. Both, either, or none of |content_view| and |extra_content_view|
-// may be present, the difference between the two being that content is pinned
-// to the left and extra_content is pinned to the right.
-// The row also displays a light gray horizontal ruler on its lower boundary.
-// The name column has a fixed width equal to |name_column_width|.
-// +----------------------------+
-// | Name | Content | Extra | > |
-// +~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ <-- ruler
-class PaymentSheetRow : public views::CustomButton {
- public:
-  PaymentSheetRow(views::ButtonListener* listener,
-                  const base::string16& section_name,
-                  std::unique_ptr<views::View> content_view,
-                  std::unique_ptr<views::View> extra_content_view,
-                  int name_column_width)
-    : views::CustomButton(listener) {
-    SetBorder(views::CreateSolidSidedBorder(0, 0, 1, 0, SK_ColorLTGRAY));
-    views::GridLayout* layout = new views::GridLayout(this);
-
-    constexpr int kRowVerticalInset = 8;
-    // The rows have extra inset compared to the header so that their right edge
-    // lines up with the close button's X rather than its invisible right edge.
-    constexpr int kRowExtraRightInset = 8;
-    layout->SetInsets(
-        kRowVerticalInset, 0, kRowVerticalInset, kRowExtraRightInset);
-    SetLayoutManager(layout);
-
-    views::ColumnSet* columns = layout->AddColumnSet(0);
-    // A column for the section name.
-    columns->AddColumn(views::GridLayout::LEADING,
-                       views::GridLayout::LEADING,
-                       0,
-                       views::GridLayout::FIXED,
-                       name_column_width,
-                       0);
-
-    constexpr int kPaddingColumnsWidth = 25;
-    columns->AddPaddingColumn(0, kPaddingColumnsWidth);
-
-    // A column for the content.
-    columns->AddColumn(views::GridLayout::FILL, views::GridLayout::LEADING,
-                       1, views::GridLayout::USE_PREF, 0, 0);
-    // A column for the extra content.
-    columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER,
-                       0, views::GridLayout::USE_PREF, 0, 0);
-
-    columns->AddPaddingColumn(0, kPaddingColumnsWidth);
-    // A column for the chevron.
-    columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER,
-                       0, views::GridLayout::USE_PREF, 0, 0);
-
-    layout->StartRow(0, 0);
-    views::Label* name_label = new views::Label(section_name);
-    layout->AddView(name_label);
-
-    if (content_view) {
-      layout->AddView(content_view.release());
-    } else {
-      layout->SkipColumns(1);
-    }
-
-    if (extra_content_view) {
-      layout->AddView(extra_content_view.release());
-    } else {
-      layout->SkipColumns(1);
-    }
-
-    views::ImageView* chevron = new views::ImageView();
-    chevron->SetImage(gfx::CreateVectorIcon(
-        views::kSubmenuArrowIcon,
-        color_utils::DeriveDefaultIconColor(name_label->enabled_color())));
-    layout->AddView(chevron);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PaymentSheetRow);
-};
-
 int ComputeWidestNameColumnViewWidth() {
   // The name colums in each row should all have the same width, large enough to
   // accomodate the longest piece of text they contain. Because of this, each
@@ -165,6 +84,87 @@
   return widest_column_width;
 }
 
+// Creates a clickable row to be displayed in the Payment Sheet. It contains
+// a section name and some content, followed by a chevron as a clickability
+// affordance. Both, either, or none of |content_view| and |extra_content_view|
+// may be present, the difference between the two being that content is pinned
+// to the left and extra_content is pinned to the right.
+// The row also displays a light gray horizontal ruler on its lower boundary.
+// The name column has a fixed width equal to |name_column_width|.
+// +----------------------------+
+// | Name | Content | Extra | > |
+// +~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ <-- ruler
+std::unique_ptr<views::Button> CreatePaymentSheetRow(
+    views::ButtonListener* listener,
+    const base::string16& section_name,
+    std::unique_ptr<views::View> content_view,
+    std::unique_ptr<views::View> extra_content_view,
+    int name_column_width) {
+  std::unique_ptr<PaymentRequestRowView> row =
+      base::MakeUnique<PaymentRequestRowView>(listener);
+  views::GridLayout* layout = new views::GridLayout(row.get());
+
+  // The rows have extra inset compared to the header so that their right edge
+  // lines up with the close button's X rather than its invisible right edge.
+  constexpr int kRowExtraRightInset = 8;
+  layout->SetInsets(kPaymentRequestRowVerticalInsets,
+                    kPaymentRequestRowHorizontalInsets,
+                    kPaymentRequestRowVerticalInsets,
+                    kPaymentRequestRowHorizontalInsets + kRowExtraRightInset);
+  row->SetLayoutManager(layout);
+
+  views::ColumnSet* columns = layout->AddColumnSet(0);
+  // A column for the section name.
+  columns->AddColumn(views::GridLayout::LEADING,
+                     views::GridLayout::LEADING,
+                     0,
+                     views::GridLayout::FIXED,
+                     name_column_width,
+                     0);
+
+  constexpr int kPaddingColumnsWidth = 25;
+  columns->AddPaddingColumn(0, kPaddingColumnsWidth);
+
+  // A column for the content.
+  columns->AddColumn(views::GridLayout::FILL, views::GridLayout::LEADING,
+                     1, views::GridLayout::USE_PREF, 0, 0);
+  // A column for the extra content.
+  columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER,
+                     0, views::GridLayout::USE_PREF, 0, 0);
+
+  columns->AddPaddingColumn(0, kPaddingColumnsWidth);
+  // A column for the chevron.
+  columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER,
+                     0, views::GridLayout::USE_PREF, 0, 0);
+
+  layout->StartRow(0, 0);
+  views::Label* name_label = new views::Label(section_name);
+  layout->AddView(name_label);
+
+  if (content_view) {
+    content_view->set_can_process_events_within_subtree(false);
+    layout->AddView(content_view.release());
+  } else {
+    layout->SkipColumns(1);
+  }
+
+  if (extra_content_view) {
+    extra_content_view->set_can_process_events_within_subtree(false);
+    layout->AddView(extra_content_view.release());
+  } else {
+    layout->SkipColumns(1);
+  }
+
+  views::ImageView* chevron = new views::ImageView();
+  chevron->set_interactive(false);
+  chevron->SetImage(gfx::CreateVectorIcon(
+      views::kSubmenuArrowIcon,
+      color_utils::DeriveDefaultIconColor(name_label->enabled_color())));
+  layout->AddView(chevron);
+
+  return std::move(row);
+}
+
 }  // namespace
 
 PaymentSheetViewController::PaymentSheetViewController(
@@ -254,7 +254,7 @@
 // +----------------------------------------------+
 std::unique_ptr<views::Button>
 PaymentSheetViewController::CreatePaymentSheetSummaryRow() {
-  std::unique_ptr<views::Button> section = base::MakeUnique<PaymentSheetRow>(
+  std::unique_ptr<views::Button> section = CreatePaymentSheetRow(
       this,
       l10n_util::GetStringUTF16(IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SECTION_NAME),
       std::unique_ptr<views::View>(nullptr),
@@ -286,7 +286,7 @@
 // |                    1800MYPOTUS               |
 // +----------------------------------------------+
 std::unique_ptr<views::Button> PaymentSheetViewController::CreateShippingRow() {
-  std::unique_ptr<views::Button> section = base::MakeUnique<PaymentSheetRow>(
+  std::unique_ptr<views::Button> section = CreatePaymentSheetRow(
       this,
       l10n_util::GetStringUTF16(IDS_PAYMENT_REQUEST_SHIPPING_SECTION_NAME),
       CreateShippingSectionContent(), std::unique_ptr<views::View>(nullptr),
@@ -330,6 +330,7 @@
             g_browser_process->GetApplicationLocale())));
 
     card_icon_view = base::MakeUnique<views::ImageView>();
+    card_icon_view->set_interactive(false);
     card_icon_view->SetImage(
       ResourceBundle::GetSharedInstance()
           .GetImageNamed(autofill::data_util::GetPaymentRequestData(
@@ -342,7 +343,7 @@
     card_icon_view->SetImageSize(kCardIconSize);
   }
 
-  std::unique_ptr<views::Button> section = base::MakeUnique<PaymentSheetRow>(
+  std::unique_ptr<views::Button> section = CreatePaymentSheetRow(
       this,
       l10n_util::GetStringUTF16(
           IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME),
@@ -375,7 +376,7 @@
 // +----------------------------------------------+
 std::unique_ptr<views::Button>
 PaymentSheetViewController::CreateContactInfoRow() {
-  std::unique_ptr<views::Button> section = base::MakeUnique<PaymentSheetRow>(
+  std::unique_ptr<views::Button> section = CreatePaymentSheetRow(
       this,
       l10n_util::GetStringUTF16(IDS_PAYMENT_REQUEST_CONTACT_INFO_SECTION_NAME),
       CreateContactInfoSectionContent(), std::unique_ptr<views::View>(nullptr),
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc
index 3278d7c..5fd54eb1 100644
--- a/chrome/browser/ui/views/session_crashed_bubble_view.cc
+++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -71,16 +71,11 @@
       "SessionCrashed.Bubble", value, SESSION_CRASHED_BUBBLE_MAX);
 }
 
-// Whether or not the bubble UI should be used.
-// TODO(crbug.com/653966): Enable this on all desktop platforms.
-bool IsBubbleUIEnabled() {
-// Function ChangeMetricsReportingState (called when the user chooses to
-// opt-in to UMA) does not support Chrome OS yet, so don't show the bubble on
-// Chrome OS.
-#if defined(OS_CHROMEOS)
-  return false;
-#else
+bool DoesSupportConsentCheck() {
+#if defined(GOOGLE_CHROME_BUILD)
   return true;
+#else
+  return false;
 #endif
 }
 
@@ -113,9 +108,6 @@
 
 // static
 bool SessionCrashedBubble::Show(Browser* browser) {
-  if (!IsBubbleUIEnabled())
-    return false;
-
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (browser->profile()->IsOffTheRecord())
     return true;
@@ -125,21 +117,18 @@
       browser_observer(
           new SessionCrashedBubbleView::BrowserRemovalObserver(browser));
 
-// Stats collection only applies to Google Chrome builds.
-#if defined(GOOGLE_CHROME_BUILD)
-  // Schedule a task to run GoogleUpdateSettings::GetCollectStatsConsent() on
-  // FILE thread, since it does IO. Then, call
-  // SessionCrashedBubbleView::ShowForReal with the result.
-  content::BrowserThread::PostTaskAndReplyWithResult(
-      content::BrowserThread::FILE,
-      FROM_HERE,
-      base::Bind(&GoogleUpdateSettings::GetCollectStatsConsent),
-      base::Bind(&SessionCrashedBubbleView::ShowForReal,
-                 base::Passed(&browser_observer)));
-#else
-  SessionCrashedBubbleView::ShowForReal(std::move(browser_observer), false);
-#endif  // defined(GOOGLE_CHROME_BUILD)
-
+  if (DoesSupportConsentCheck()) {
+    // Schedule a task to run GoogleUpdateSettings::GetCollectStatsConsent() on
+    // FILE thread, since it does IO. Then, call
+    // SessionCrashedBubbleView::ShowForReal with the result.
+    content::BrowserThread::PostTaskAndReplyWithResult(
+        content::BrowserThread::FILE, FROM_HERE,
+        base::Bind(&GoogleUpdateSettings::GetCollectStatsConsent),
+        base::Bind(&SessionCrashedBubbleView::ShowForReal,
+                   base::Passed(&browser_observer)));
+  } else {
+    SessionCrashedBubbleView::ShowForReal(std::move(browser_observer), false);
+  }
   return true;
 }
 
@@ -152,10 +141,8 @@
   // and the preference is modifiable by the user.
   bool offer_uma_optin = false;
 
-#if defined(GOOGLE_CHROME_BUILD)
-  if (!uma_opted_in_already)
+  if (DoesSupportConsentCheck() && !uma_opted_in_already)
     offer_uma_optin = !IsMetricsReportingPolicyManaged();
-#endif  // defined(GOOGLE_CHROME_BUILD)
 
   Browser* browser = browser_observer->browser();
 
diff --git a/chrome/browser/ui/webui/inspect_ui.cc b/chrome/browser/ui/webui/inspect_ui.cc
index 02a7116..fdebd22 100644
--- a/chrome/browser/ui/webui/inspect_ui.cc
+++ b/chrome/browser/ui/webui/inspect_ui.cc
@@ -20,6 +20,7 @@
 #include "components/ui_devtools/devtools_server.h"
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/notification_types.h"
@@ -286,9 +287,8 @@
  private:
   // contents::WebContentsObserver overrides.
   void WebContentsDestroyed() override;
-  void DidNavigateMainFrame(
-      const content::LoadCommittedDetails& details,
-      const content::FrameNavigateParams& params) override;
+  void DidFinishNavigation(
+      content::NavigationHandle* navigation_handle) override;
 
   DevToolsUIBindings bindings_;
   GURL url_;
@@ -311,10 +311,12 @@
   delete this;
 }
 
-void DevToolsUIBindingsEnabler::DidNavigateMainFrame(
-      const content::LoadCommittedDetails& details,
-      const content::FrameNavigateParams& params) {
-  if (url_ != params.url)
+void DevToolsUIBindingsEnabler::DidFinishNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted())
+    return;
+
+  if (url_ != navigation_handle->GetURL())
     delete this;
 }
 
diff --git a/chrome/browser/ui/zoom/zoom_controller_unittest.cc b/chrome/browser/ui/zoom/zoom_controller_unittest.cc
index 18f76df..835867d 100644
--- a/chrome/browser/ui/zoom/zoom_controller_unittest.cc
+++ b/chrome/browser/ui/zoom/zoom_controller_unittest.cc
@@ -12,8 +12,7 @@
 #include "components/zoom/zoom_controller.h"
 #include "components/zoom/zoom_observer.h"
 #include "content/public/browser/host_zoom_map.h"
-#include "content/public/browser/navigation_details.h"
-#include "content/public/common/frame_navigate_params.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/test/test_renderer_host.h"
 #include "content/public/test/test_utils.h"
 #include "ipc/ipc_message.h"
@@ -54,8 +53,10 @@
       false);
   ZoomChangedWatcher zoom_change_watcher(zoom_controller_.get(),
                                          zoom_change_data);
-  zoom_controller_->DidNavigateMainFrame(content::LoadCommittedDetails(),
-                                         content::FrameNavigateParams());
+  std::unique_ptr<content::NavigationHandle> navigation_handle =
+      content::NavigationHandle::CreateNavigationHandleForTesting(
+          GURL(), rvh()->GetMainFrame(), true);
+  zoom_controller_->DidFinishNavigation(navigation_handle.get());
   zoom_change_watcher.Wait();
 }
 
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 1938a8b..78d0e1c 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1045,6 +1045,7 @@
       "data/webui/settings/settings_passwords_section_browsertest.js",
       "data/webui/settings/settings_subpage_browsertest.js",
       "data/webui/settings/settings_ui_browsertest.js",
+      "data/webui/settings/site_settings_page_browsertest.js",
       "data/webui/text_defaults_browsertest.js",
       "data/webui/webui_resource_async_browsertest.js",
     ]
@@ -2533,6 +2534,7 @@
           "../browser/ui/cocoa/extensions/media_galleries_dialog_cocoa_browsertest.mm",
           "../browser/ui/cocoa/extensions/windowed_install_dialog_controller_browsertest.mm",
           "../browser/ui/cocoa/find_bar/find_bar_browsertest.mm",
+          "../browser/ui/cocoa/location_bar/content_setting_decoration_browsertest.mm",
           "../browser/ui/cocoa/location_bar/zoom_decoration_browsertest.mm",
           "../browser/ui/cocoa/omnibox/omnibox_view_mac_browsertest.mm",
           "../browser/ui/cocoa/passwords/passwords_bubble_browsertest.mm",
@@ -4420,8 +4422,11 @@
       "../browser/sessions/session_restore_stats_collector_unittest.cc",
       "../browser/sessions/session_service_unittest.cc",
       "../browser/sessions/tab_loader_unittest.cc",
-      "../browser/ui/startup/session_crashed_infobar_delegate_unittest.cc",
     ]
+
+    if (is_mac && !mac_views_browser) {
+      sources += [ "../browser/ui/startup/session_crashed_infobar_delegate_unittest.cc" ]
+    }
   }
   if (enable_webrtc) {
     sources += [
diff --git a/chrome/test/data/webui/settings/category_default_setting_tests.js b/chrome/test/data/webui/settings/category_default_setting_tests.js
index 58a8b071..ecd69ce 100644
--- a/chrome/test/data/webui/settings/category_default_setting_tests.js
+++ b/chrome/test/data/webui/settings/category_default_setting_tests.js
@@ -135,49 +135,6 @@
         return testCategoryEnabled(testElement, false);
       });
 
-      test('basic category tests', function() {
-        for (var key in settings.ContentSettingsTypes) {
-          var category = settings.ContentSettingsTypes[key];
-
-          // A quick testing note on a few special categories...
-
-          // The USB Devices category has no global toggle -- and therefore no
-          // Category Desc (and has a special way of storing its data).
-
-          // The Protocol Handlers is a special category in that is does not
-          // store its data like the rest, but it has a global default toggle
-          // and therefore can be tested like the rest below.
-
-          // Test category text ids and descriptions for those categories that
-          // have those.
-          if (category != settings.ContentSettingsTypes.USB_DEVICES &&
-              category != settings.ContentSettingsTypes.ZOOM_LEVELS) {
-            assertNotEquals('', testElement.computeCategoryDesc(
-                category, settings.PermissionValues.ALLOW, true));
-            assertNotEquals('', testElement.computeCategoryDesc(
-                category, settings.PermissionValues.ALLOW, false));
-            assertNotEquals('', testElement.computeCategoryDesc(
-                category, settings.PermissionValues.BLOCK, true));
-            assertNotEquals('', testElement.computeCategoryDesc(
-                category, settings.PermissionValues.BLOCK, false));
-
-            // Test additional tri-state values:
-            if (category == settings.ContentSettingsTypes.PLUGINS) {
-              assertNotEquals('', testElement.computeCategoryDesc(
-                  category, settings.PermissionValues.IMPORTANT_CONTENT, true));
-              assertNotEquals('', testElement.computeCategoryDesc(
-                  category, settings.PermissionValues.IMPORTANT_CONTENT,
-                  false));
-            } else if (category == settings.ContentSettingsTypes.COOKIES) {
-              assertNotEquals('', testElement.computeCategoryDesc(
-                  category, settings.PermissionValues.SESSION_ONLY, true));
-              assertNotEquals('', testElement.computeCategoryDesc(
-                  category, settings.PermissionValues.SESSION_ONLY, false));
-            }
-          }
-        }
-      });
-
       function testTristateCategory(prefs, category, thirdState,
                                     secondaryToggleId) {
         browserProxy.setPrefs(prefs);
diff --git a/chrome/test/data/webui/settings/site_settings_page_browsertest.js b/chrome/test/data/webui/settings/site_settings_page_browsertest.js
new file mode 100644
index 0000000..0b8256e2
--- /dev/null
+++ b/chrome/test/data/webui/settings/site_settings_page_browsertest.js
@@ -0,0 +1,47 @@
+// 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.
+
+/** @fileoverview Site settings page tests. */
+
+GEN_INCLUDE(['settings_page_browsertest.js']);
+/**
+ * @constructor
+ * @extends {SettingsPageBrowserTest}
+ */
+function SettingsSiteSettingsPageBrowserTest() {}
+
+SettingsSiteSettingsPageBrowserTest.prototype = {
+  __proto__: SettingsPageBrowserTest.prototype,
+};
+
+TEST_F('SettingsSiteSettingsPageBrowserTest', 'labels', function() {
+  suite('Site settings page', function() {
+    var ui;
+
+    suiteSetup(function() {
+      ui = assert(document.createElement('settings-site-settings-page'));
+    });
+
+    test('defaultSettingLabel_ tests', function() {
+      assertEquals('a', ui.defaultSettingLabel_(
+          settings.PermissionValues.ALLOW, 'a', 'b'));
+      assertEquals('b', ui.defaultSettingLabel_(
+          settings.PermissionValues.BLOCK, 'a', 'b'));
+      assertEquals('a', ui.defaultSettingLabel_(
+          settings.PermissionValues.ALLOW, 'a', 'b', 'c'));
+      assertEquals('b', ui.defaultSettingLabel_(
+          settings.PermissionValues.BLOCK, 'a', 'b', 'c'));
+      assertEquals('c', ui.defaultSettingLabel_(
+          settings.PermissionValues.SESSION_ONLY, 'a', 'b', 'c'));
+      assertEquals('c', ui.defaultSettingLabel_(
+          settings.PermissionValues.DEFAULT, 'a', 'b', 'c'));
+      assertEquals('c', ui.defaultSettingLabel_(
+          settings.PermissionValues.ASK, 'a', 'b', 'c'));
+      assertEquals('c', ui.defaultSettingLabel_(
+          settings.PermissionValues.DETECT_IMPORTANT_CONTENT, 'a', 'b', 'c'));
+    });
+  });
+
+  mocha.run();
+});
diff --git a/chromeos/components/tether/ble_scanner.cc b/chromeos/components/tether/ble_scanner.cc
index fa86feb..1553a091 100644
--- a/chromeos/components/tether/ble_scanner.cc
+++ b/chromeos/components/tether/ble_scanner.cc
@@ -297,7 +297,7 @@
     PA_LOG(INFO) << "Received advertisement from remote device with ID "
                  << identified_device->GetTruncatedDeviceIdForLogs() << ".";
     for (auto& observer : observer_list_) {
-      observer.OnReceivedAdvertisementFromDevice(bluetooth_device,
+      observer.OnReceivedAdvertisementFromDevice(bluetooth_device->GetAddress(),
                                                  *identified_device);
     }
   } else {
diff --git a/chromeos/components/tether/ble_scanner.h b/chromeos/components/tether/ble_scanner.h
index 9122c7f5..a601417 100644
--- a/chromeos/components/tether/ble_scanner.h
+++ b/chromeos/components/tether/ble_scanner.h
@@ -29,7 +29,7 @@
   class Observer {
    public:
     virtual void OnReceivedAdvertisementFromDevice(
-        const device::BluetoothDevice* bluetooth_device,
+        const std::string& device_address,
         cryptauth::RemoteDevice remote_device) = 0;
   };
 
diff --git a/chromeos/components/tether/ble_scanner_unittest.cc b/chromeos/components/tether/ble_scanner_unittest.cc
index b2b9bbca..79ce95d7 100644
--- a/chromeos/components/tether/ble_scanner_unittest.cc
+++ b/chromeos/components/tether/ble_scanner_unittest.cc
@@ -28,40 +28,41 @@
 namespace tether {
 
 namespace {
+
 class MockBleScannerObserver : public BleScanner::Observer {
  public:
   MockBleScannerObserver() {}
 
+  // BleScanner::Observer:
   void OnReceivedAdvertisementFromDevice(
-      const device::BluetoothDevice* bluetooth_device,
+      const std::string& device_address,
       cryptauth::RemoteDevice remote_device) override {
-    bluetooth_devices_.push_back(bluetooth_device);
+    device_addresses_.push_back(device_address);
     remote_devices_.push_back(remote_device);
   }
 
-  int GetNumCalls() { return static_cast<int>(bluetooth_devices_.size()); }
+  int GetNumCalls() { return static_cast<int>(device_addresses_.size()); }
 
-  std::vector<const device::BluetoothDevice*>& bluetooth_devices() {
-    return bluetooth_devices_;
-  }
+  std::vector<std::string>& device_addresses() { return device_addresses_; }
 
   std::vector<cryptauth::RemoteDevice>& remote_devices() {
     return remote_devices_;
   }
 
  private:
-  std::vector<const device::BluetoothDevice*> bluetooth_devices_;
+  std::vector<std::string> device_addresses_;
   std::vector<cryptauth::RemoteDevice> remote_devices_;
 };
 
 class MockBluetoothDeviceWithServiceData : public device::MockBluetoothDevice {
  public:
   MockBluetoothDeviceWithServiceData(device::MockBluetoothAdapter* adapter,
+                                     const std::string& device_address,
                                      const std::string& service_data)
       : device::MockBluetoothDevice(adapter,
                                     /* bluetooth_class */ 0,
                                     "name",
-                                    "11:22:33:44:55:66",
+                                    device_address,
                                     false,
                                     false) {
     for (size_t i = 0; i < service_data.size(); i++) {
@@ -78,6 +79,8 @@
 const int kExpectedDiscoveryRSSI = -90;
 const size_t kMinNumBytesInServiceData = 4;
 
+const std::string kDefaultBluetoothAddress = "11:22:33:44:55:66";
+
 const std::string fake_local_public_key = "fakeLocalPublicKey";
 
 const std::string current_eid_data = "currentEidData";
@@ -381,9 +384,9 @@
 
   // Device with no service data connected. Service data is required to identify
   // the advertising device.
-  MockBluetoothDeviceWithServiceData device1(mock_adapter_.get(),
-                                             empty_service_data);
-  ble_scanner_->DeviceAdded(mock_adapter_.get(), &device1);
+  MockBluetoothDeviceWithServiceData device(
+      mock_adapter_.get(), kDefaultBluetoothAddress, empty_service_data);
+  ble_scanner_->DeviceAdded(mock_adapter_.get(), &device);
   EXPECT_FALSE(mock_eid_generator_->num_identify_calls());
   EXPECT_FALSE(mock_observer_->GetNumCalls());
 }
@@ -400,9 +403,9 @@
 
   // Device with short service data connected. Service data of at least 4 bytes
   // is required to identify the advertising device.
-  MockBluetoothDeviceWithServiceData device2(mock_adapter_.get(),
-                                             short_service_data);
-  ble_scanner_->DeviceAdded(mock_adapter_.get(), &device2);
+  MockBluetoothDeviceWithServiceData device(
+      mock_adapter_.get(), kDefaultBluetoothAddress, short_service_data);
+  ble_scanner_->DeviceAdded(mock_adapter_.get(), &device);
   EXPECT_FALSE(mock_eid_generator_->num_identify_calls());
   EXPECT_FALSE(mock_observer_->GetNumCalls());
 }
@@ -422,9 +425,10 @@
   // cannot be fetched.
   mock_local_device_data_provider_->SetPublicKey(nullptr);
   mock_local_device_data_provider_->SetBeaconSeeds(nullptr);
-  MockBluetoothDeviceWithServiceData device3(
-      mock_adapter_.get(), valid_service_data_for_other_device);
-  ble_scanner_->DeviceAdded(mock_adapter_.get(), &device3);
+  MockBluetoothDeviceWithServiceData device(
+      mock_adapter_.get(), kDefaultBluetoothAddress,
+      valid_service_data_for_other_device);
+  ble_scanner_->DeviceAdded(mock_adapter_.get(), &device);
   EXPECT_FALSE(mock_eid_generator_->num_identify_calls());
   EXPECT_FALSE(mock_observer_->GetNumCalls());
 }
@@ -446,9 +450,10 @@
       base::MakeUnique<std::string>(fake_local_public_key));
   mock_local_device_data_provider_->SetBeaconSeeds(
       base::MakeUnique<std::vector<cryptauth::BeaconSeed>>(test_beacon_seeds_));
-  MockBluetoothDeviceWithServiceData device4(
-      mock_adapter_.get(), valid_service_data_for_other_device);
-  ble_scanner_->DeviceAdded(mock_adapter_.get(), &device4);
+  MockBluetoothDeviceWithServiceData device(
+      mock_adapter_.get(), kDefaultBluetoothAddress,
+      valid_service_data_for_other_device);
+  ble_scanner_->DeviceAdded(mock_adapter_.get(), &device);
   EXPECT_EQ(1, mock_eid_generator_->num_identify_calls());
   EXPECT_FALSE(mock_observer_->GetNumCalls());
 }
@@ -465,14 +470,15 @@
   InvokeDiscoveryStartedCallback();
 
   // Registered device connects.
-  MockBluetoothDeviceWithServiceData device5(
-      mock_adapter_.get(), valid_service_data_for_registered_device);
+  MockBluetoothDeviceWithServiceData device(
+      mock_adapter_.get(), kDefaultBluetoothAddress,
+      valid_service_data_for_registered_device);
   mock_eid_generator_->set_identified_device(&test_devices_[0]);
-  ble_scanner_->DeviceAdded(mock_adapter_.get(), &device5);
+  ble_scanner_->DeviceAdded(mock_adapter_.get(), &device);
   EXPECT_EQ(1, mock_eid_generator_->num_identify_calls());
   EXPECT_EQ(1, mock_observer_->GetNumCalls());
-  EXPECT_EQ(1, static_cast<int>(mock_observer_->bluetooth_devices().size()));
-  EXPECT_EQ(&device5, mock_observer_->bluetooth_devices()[0]);
+  EXPECT_EQ(1, static_cast<int>(mock_observer_->device_addresses().size()));
+  EXPECT_EQ(device.GetAddress(), mock_observer_->device_addresses()[0]);
   EXPECT_EQ(1, static_cast<int>(mock_observer_->remote_devices().size()));
   EXPECT_EQ(test_devices_[0], mock_observer_->remote_devices()[0]);
 
@@ -492,20 +498,22 @@
   InvokeAdapterCallback();
   InvokeDiscoveryStartedCallback();
 
-  MockBluetoothDeviceWithServiceData mock_bluetooth_device(mock_adapter_.get(),
-                                                           "fakeServiceData");
+  MockBluetoothDeviceWithServiceData mock_bluetooth_device(
+      mock_adapter_.get(), kDefaultBluetoothAddress, "fakeServiceData");
   mock_eid_generator_->set_identified_device(&test_devices_[0]);
   ble_scanner_->DeviceAdded(mock_adapter_.get(), &mock_bluetooth_device);
 
   EXPECT_EQ(1, mock_observer_->GetNumCalls());
-  EXPECT_EQ(1, static_cast<int>(mock_observer_->bluetooth_devices().size()));
-  EXPECT_EQ(&mock_bluetooth_device, mock_observer_->bluetooth_devices()[0]);
+  EXPECT_EQ(1, static_cast<int>(mock_observer_->device_addresses().size()));
+  EXPECT_EQ(mock_bluetooth_device.GetAddress(),
+            mock_observer_->device_addresses()[0]);
   EXPECT_EQ(1, static_cast<int>(mock_observer_->remote_devices().size()));
   EXPECT_EQ(test_devices_[0], mock_observer_->remote_devices()[0]);
 
   EXPECT_EQ(1, extra_observer.GetNumCalls());
-  EXPECT_EQ(1, static_cast<int>(extra_observer.bluetooth_devices().size()));
-  EXPECT_EQ(&mock_bluetooth_device, extra_observer.bluetooth_devices()[0]);
+  EXPECT_EQ(1, static_cast<int>(extra_observer.device_addresses().size()));
+  EXPECT_EQ(mock_bluetooth_device.GetAddress(),
+            extra_observer.device_addresses()[0]);
   EXPECT_EQ(1, static_cast<int>(extra_observer.remote_devices().size()));
   EXPECT_EQ(test_devices_[0], extra_observer.remote_devices()[0]);
 
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 88096ec..dad0d38 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -1820,7 +1820,7 @@
       C -> D
   */
 
-  for (auto& credit_card : local_credit_cards_) {
+  for (auto& credit_card : GetCreditCards()) {
     // If the credit card is not associated with a billing address, skip it.
     if (credit_card->billing_address_id().empty())
       break;
@@ -1847,7 +1847,10 @@
 
     // If the card was modified, apply the changes to the database.
     if (was_modified) {
-      database_->UpdateCreditCard(*credit_card);
+      if (credit_card->record_type() == CreditCard::LOCAL_CARD)
+        database_->UpdateCreditCard(*credit_card);
+      else
+        database_->UpdateServerCardMetadata(*credit_card);
     }
   }
 }
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h
index 165862f..a6de3ac 100644
--- a/components/autofill/core/browser/personal_data_manager.h
+++ b/components/autofill/core/browser/personal_data_manager.h
@@ -416,7 +416,7 @@
   std::vector<std::unique_ptr<CreditCard>> server_credit_cards_;
 
   // A combination of local and server credit cards. The pointers are owned
-  // by the local/sverver_credit_cards_ vectors.
+  // by the local/server_credit_cards_ vectors.
   mutable std::vector<CreditCard*> credit_cards_;
 
   // When the manager makes a request from WebDataServiceBase, the database
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index 18bb0aeb..f570efe 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -4803,9 +4803,11 @@
 
   // Add the credit cards to the database.
   personal_data_->local_credit_cards_.push_back(base::WrapUnique(credit_card1));
-  personal_data_->local_credit_cards_.push_back(base::WrapUnique(credit_card2));
+  personal_data_->server_credit_cards_.push_back(
+      base::WrapUnique(credit_card2));
   personal_data_->local_credit_cards_.push_back(base::WrapUnique(credit_card3));
-  personal_data_->local_credit_cards_.push_back(base::WrapUnique(credit_card4));
+  personal_data_->server_credit_cards_.push_back(
+      base::WrapUnique(credit_card4));
 
   personal_data_->UpdateCardsBillingAddressReference(guids_merge_map);
 
diff --git a/components/browser_watcher/dump_postmortem_minidump_main_win.cc b/components/browser_watcher/dump_postmortem_minidump_main_win.cc
index 246a06a..db01260 100644
--- a/components/browser_watcher/dump_postmortem_minidump_main_win.cc
+++ b/components/browser_watcher/dump_postmortem_minidump_main_win.cc
@@ -33,14 +33,66 @@
   return true;
 }
 
-void Indent(FILE* out, size_t indent_level) {
+void Indent(FILE* out, int indent_level) {
   DCHECK(out);
-  for (size_t i = 0; i < indent_level; ++i)
+  for (int i = 0; i < indent_level; ++i)
     fprintf(out, "  ");
 }
 
+void PrintUserData(
+    FILE* out,
+    int indent_level,
+    const google::protobuf::Map<std::string, browser_watcher::TypedValue>&
+        user_data) {
+  DCHECK(out);
+  Indent(out, indent_level);
+  fprintf(out, "User data (%zu)\n", user_data.size());
+  for (const auto& kv : user_data) {
+    Indent(out, indent_level + 1);
+    fprintf(out, "%s : ", kv.first.c_str());
+    const browser_watcher::TypedValue& value = kv.second;
+    switch (kv.second.value_case()) {
+      case browser_watcher::TypedValue::kBytesValue: {
+        const std::string& bytes_value = value.bytes_value();
+        for (size_t i = 0; i < bytes_value.size(); ++i)
+          fprintf(out, "%02X ", bytes_value.at(i));
+        fprintf(out, "\n");
+        break;
+      }
+      case browser_watcher::TypedValue::kBytesReference:
+        fprintf(out, "bytes reference (address: %llX, size: %llX)\n",
+                value.bytes_reference().address(),
+                value.bytes_reference().size());
+        break;
+      case browser_watcher::TypedValue::kStringValue:
+        fprintf(out, "\"%s\"\n", value.string_value().c_str());
+        break;
+      case browser_watcher::TypedValue::kStringReference:
+        fprintf(out, "string reference (address: %llX, size: %llX)\n",
+                value.string_reference().address(),
+                value.string_reference().size());
+        break;
+      case browser_watcher::TypedValue::kCharValue:
+        fprintf(out, "'%s'\n", value.char_value().c_str());
+        break;
+      case browser_watcher::TypedValue::kBoolValue:
+        fprintf(out, "%s\n", value.bool_value() ? "true" : "false");
+        break;
+      case browser_watcher::TypedValue::kSignedValue:
+        fprintf(out, "%lld\n", value.signed_value());
+        break;
+      case browser_watcher::TypedValue::kUnsignedValue:
+        fprintf(out, "%llu\n", value.unsigned_value());
+        break;
+      case browser_watcher::TypedValue::VALUE_NOT_SET:
+        fprintf(out, "<not set>\n");
+        break;
+    }
+  }
+}
+
 void PrintActivity(FILE* out,
-                   size_t indent_level,
+                   int indent_level,
                    const browser_watcher::Activity& activity) {
   DCHECK(out);
   Indent(out, indent_level);
@@ -54,16 +106,16 @@
       break;
     case browser_watcher::Activity::ACT_TASK_RUN:
       Indent(out, indent_level + 1);
-      fprintf(out, "origin_address: %llx\n", activity.origin_address());
+      fprintf(out, "origin_address: %llX\n", activity.origin_address());
       fprintf(out, "task_sequence_id: %lld\n", activity.task_sequence_id());
       break;
     case browser_watcher::Activity::ACT_LOCK_ACQUIRE:
       Indent(out, indent_level + 1);
-      fprintf(out, "lock_address: %llx\n", activity.lock_address());
+      fprintf(out, "lock_address: %llX\n", activity.lock_address());
       break;
     case browser_watcher::Activity::ACT_EVENT_WAIT:
       Indent(out, indent_level + 1);
-      fprintf(out, "event_address: %llx\n", activity.event_address());
+      fprintf(out, "event_address: %llX\n", activity.event_address());
       break;
     case browser_watcher::Activity::ACT_THREAD_JOIN:
       Indent(out, indent_level + 1);
@@ -74,6 +126,8 @@
       fprintf(out, "process_id: %lld\n", activity.process_id());
       break;
   }
+
+  PrintUserData(out, indent_level + 1, activity.user_data());
 }
 
 void PrintProcessState(FILE* out,
@@ -90,6 +144,7 @@
 
 // TODO(manzagop): flesh out as StabilityReport gets fleshed out.
 void PrintReport(FILE* out, const browser_watcher::StabilityReport& report) {
+  PrintUserData(out, 0, report.global_data());
   for (int i = 0; i < report.process_states_size(); ++i) {
     const browser_watcher::ProcessState process = report.process_states(i);
     PrintProcessState(out, process);
diff --git a/components/browser_watcher/postmortem_report_collector.cc b/components/browser_watcher/postmortem_report_collector.cc
index 2b3d9d5..aa3845f 100644
--- a/components/browser_watcher/postmortem_report_collector.cc
+++ b/components/browser_watcher/postmortem_report_collector.cc
@@ -25,6 +25,7 @@
 using ActivitySnapshot = base::debug::ThreadActivityAnalyzer::Snapshot;
 using base::debug::ActivityUserData;
 using base::debug::GlobalActivityAnalyzer;
+using base::debug::GlobalActivityTracker;
 using base::debug::ThreadActivityAnalyzer;
 using crashpad::CrashReportDatabase;
 
@@ -89,6 +90,39 @@
   }
 }
 
+void CollectModuleInformation(
+    const std::vector<GlobalActivityTracker::ModuleInfo>& modules,
+    ProcessState* process_state) {
+  DCHECK(process_state);
+
+  char code_identifier[17];
+  char debug_identifier[41];
+
+  for (const GlobalActivityTracker::ModuleInfo& recorded : modules) {
+    CodeModule* collected = process_state->add_modules();
+    collected->set_base_address(recorded.address);
+    collected->set_size(recorded.size);
+    collected->set_code_file(recorded.file);
+
+    // Compute the code identifier using the required format.
+    snprintf(code_identifier, sizeof(code_identifier), "%08X%zx",
+             recorded.timestamp, recorded.size);
+    collected->set_code_identifier(code_identifier);
+    collected->set_debug_file(recorded.debug_file);
+
+    // Compute the debug identifier using the required format.
+    const crashpad::UUID* uuid =
+        reinterpret_cast<const crashpad::UUID*>(recorded.identifier);
+    snprintf(debug_identifier, sizeof(debug_identifier),
+             "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%x", uuid->data_1,
+             uuid->data_2, uuid->data_3, uuid->data_4[0], uuid->data_4[1],
+             uuid->data_5[0], uuid->data_5[1], uuid->data_5[2], uuid->data_5[3],
+             uuid->data_5[4], uuid->data_5[5], recorded.age);
+    collected->set_debug_identifier(debug_identifier);
+    collected->set_is_unloaded(!recorded.is_loaded);
+  }
+}
+
 }  // namespace
 
 PostmortemReportCollector::PostmortemReportCollector(
@@ -273,6 +307,9 @@
     CollectThread(thread_analyzer->activity_snapshot(), thread_state);
   }
 
+  // Collect module information.
+  CollectModuleInformation(global_analyzer->GetModules(), process_state);
+
   return SUCCESS;
 }
 
diff --git a/components/browser_watcher/postmortem_report_collector.h b/components/browser_watcher/postmortem_report_collector.h
index e1bac13..8d26698aa 100644
--- a/components/browser_watcher/postmortem_report_collector.h
+++ b/components/browser_watcher/postmortem_report_collector.h
@@ -78,6 +78,9 @@
   FRIEND_TEST_ALL_PREFIXES(
       PostmortemReportCollectorCollectionFromGlobalTrackerTest,
       GlobalUserDataCollection);
+  FRIEND_TEST_ALL_PREFIXES(
+      PostmortemReportCollectorCollectionFromGlobalTrackerTest,
+      ModuleCollection);
 
   // Virtual for unittesting.
   virtual std::vector<base::FilePath> GetDebugStateFilePaths(
diff --git a/components/browser_watcher/postmortem_report_collector_unittest.cc b/components/browser_watcher/postmortem_report_collector_unittest.cc
index d7c2307..6f79bbb 100644
--- a/components/browser_watcher/postmortem_report_collector_unittest.cc
+++ b/components/browser_watcher/postmortem_report_collector_unittest.cc
@@ -585,7 +585,7 @@
             collector.Collect(debug_file_path(), &report));
   ASSERT_NE(nullptr, report);
 
-  // Validate the report's log content.
+  // Validate the report's user data.
   const auto& collected_data = report->global_data();
   ASSERT_EQ(8U, collected_data.size());
 
@@ -628,4 +628,52 @@
   EXPECT_EQ(strlen(string2), static_cast<uint64_t>(sref.size()));
 }
 
+TEST_F(PostmortemReportCollectorCollectionFromGlobalTrackerTest,
+       ModuleCollection) {
+  // Record some module information.
+  GlobalActivityTracker::CreateWithFile(debug_file_path(), kMemorySize, 0ULL,
+                                        "", 3);
+
+  base::debug::GlobalActivityTracker::ModuleInfo module_info = {};
+  module_info.is_loaded = true;
+  module_info.address = 0x123456;
+  module_info.load_time = 1111LL;
+  module_info.size = 0x2d000;
+  module_info.timestamp = 0xCAFECAFE;
+  module_info.age = 1;
+  crashpad::UUID debug_uuid;
+  debug_uuid.InitializeFromString("11223344-5566-7788-abcd-0123456789ab");
+  memcpy(module_info.identifier, &debug_uuid, sizeof(module_info.identifier));
+  module_info.file = "foo";
+  module_info.debug_file = "bar";
+
+  GlobalActivityTracker::Get()->RecordModuleInfo(module_info);
+
+  // Collect the stability report.
+  PostmortemReportCollector collector(kProductName, kVersionNumber,
+                                      kChannelName);
+  std::unique_ptr<StabilityReport> report;
+  ASSERT_EQ(PostmortemReportCollector::SUCCESS,
+            collector.Collect(debug_file_path(), &report));
+  ASSERT_NE(nullptr, report);
+
+  // Validate the report's modules content.
+  ASSERT_EQ(1, report->process_states_size());
+  const ProcessState& process_state = report->process_states(0);
+  ASSERT_EQ(1, process_state.modules_size());
+
+  const CodeModule collected_module = process_state.modules(0);
+  EXPECT_EQ(module_info.address,
+            static_cast<uintptr_t>(collected_module.base_address()));
+  EXPECT_EQ(module_info.size, static_cast<size_t>(collected_module.size()));
+  EXPECT_EQ(module_info.file, collected_module.code_file());
+  EXPECT_EQ("CAFECAFE2d000", collected_module.code_identifier());
+  EXPECT_EQ(module_info.debug_file, collected_module.debug_file());
+  EXPECT_EQ("1122334455667788ABCD0123456789AB1",
+            collected_module.debug_identifier());
+  EXPECT_EQ("", collected_module.version());
+  EXPECT_EQ(0LL, collected_module.shrink_down_delta());
+  EXPECT_EQ(!module_info.is_loaded, collected_module.is_unloaded());
+}
+
 }  // namespace browser_watcher
diff --git a/components/browser_watcher/stability_data_names.cc b/components/browser_watcher/stability_data_names.cc
index 03cb921..27be25b 100644
--- a/components/browser_watcher/stability_data_names.cc
+++ b/components/browser_watcher/stability_data_names.cc
@@ -8,9 +8,6 @@
 
 const char kStabilityChannel[] = "channel";
 const char kStabilityExecutionPhase[] = "stability-execution-phase";
-const char kStabilityModuleAddress[] = "module-address";
-const char kStabilityModuleSize[] = "module-size";
-const char kStabilityModuleTimestamp[] = "module-timestamp";
 const char kStabilityPlatform[] = "platform";
 const char kStabilityProduct[] = "product";
 const char kStabilitySpecialBuild[] = "special-build";
diff --git a/components/browser_watcher/stability_data_names.h b/components/browser_watcher/stability_data_names.h
index 32fb640..9143811 100644
--- a/components/browser_watcher/stability_data_names.h
+++ b/components/browser_watcher/stability_data_names.h
@@ -10,9 +10,6 @@
 // Alphabetical list of stability data names.
 extern const char kStabilityChannel[];
 extern const char kStabilityExecutionPhase[];
-extern const char kStabilityModuleAddress[];
-extern const char kStabilityModuleSize[];
-extern const char kStabilityModuleTimestamp[];
 extern const char kStabilityPlatform[];
 extern const char kStabilityProduct[];
 extern const char kStabilitySpecialBuild[];
diff --git a/components/browser_watcher/stability_report.proto b/components/browser_watcher/stability_report.proto
index 1d1897f..72c8fc20 100644
--- a/components/browser_watcher/stability_report.proto
+++ b/components/browser_watcher/stability_report.proto
@@ -15,7 +15,7 @@
   // TODO(manzagop): flesh out.
 }
 
-// Next id: 8
+// Next id: 10
 message CodeModule {
   // The base address of this code module as it was loaded by the process.
   optional int64 base_address = 1;
@@ -49,6 +49,11 @@
 
   // A human-readable representation of the code module's version.
   optional string version = 7;
+
+  optional int64 shrink_down_delta = 8;
+
+  // Whether the module was still loaded into memory.
+  optional bool is_unloaded = 9;
 }
 
 // A typed value holds values of interest or references to such values.
diff --git a/components/cryptauth/BUILD.gn b/components/cryptauth/BUILD.gn
index 6a0fba0..1b14f27 100644
--- a/components/cryptauth/BUILD.gn
+++ b/components/cryptauth/BUILD.gn
@@ -50,6 +50,8 @@
     "remote_beacon_seed_fetcher.h",
     "remote_device.cc",
     "remote_device.h",
+    "secure_channel.cc",
+    "secure_channel.h",
     "secure_context.h",
     "secure_message_delegate.cc",
     "secure_message_delegate.h",
@@ -91,6 +93,8 @@
     "cryptauth_test_util.h",
     "device_to_device_responder_operations.cc",
     "device_to_device_responder_operations.h",
+    "fake_authenticator.cc",
+    "fake_authenticator.h",
     "fake_connection.cc",
     "fake_connection.h",
     "fake_cryptauth_gcm_manager.cc",
@@ -141,6 +145,7 @@
     "eid_generator_unittest.cc",
     "fake_secure_message_delegate_unittest.cc",
     "remote_beacon_seed_fetcher_unittest.cc",
+    "secure_channel_unittest.cc",
     "sync_scheduler_impl_unittest.cc",
     "wire_message_unittest.cc",
   ]
diff --git a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc
index fac07bc7..e7c0241a 100644
--- a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc
+++ b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/location.h"
+#include "base/memory/ptr_util.h"
 #include "base/task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/cryptauth/bluetooth_throttler.h"
@@ -16,16 +17,10 @@
 #include "components/proximity_auth/logging/logging.h"
 #include "device/bluetooth/bluetooth_gatt_connection.h"
 
-using device::BluetoothAdapter;
-using device::BluetoothDevice;
-using device::BluetoothGattConnection;
-using device::BluetoothRemoteGattService;
-using device::BluetoothRemoteGattCharacteristic;
-using device::BluetoothGattNotifySession;
-using device::BluetoothUUID;
-
 namespace cryptauth {
+
 namespace weave {
+
 namespace {
 
 typedef BluetoothLowEnergyWeavePacketReceiver::State ReceiverState;
@@ -36,16 +31,63 @@
 // The UUID of the RX characteristic used to receive data from the server.
 const char kRXCharacteristicUUID[] = "00000100-0004-1000-8000-001A11000102";
 
+// If sending a message fails, retry up to 2 additional times. This means that
+// each message gets 3 attempts: the first one, and 2 retries.
+const int kMaxNumberOfRetryAttempts = 2;
+
 }  // namespace
 
+// static
+std::shared_ptr<BluetoothLowEnergyWeaveClientConnection::Factory>
+    BluetoothLowEnergyWeaveClientConnection::Factory::factory_instance_ =
+        nullptr;
+
+// static
+std::unique_ptr<BluetoothLowEnergyWeaveClientConnection>
+BluetoothLowEnergyWeaveClientConnection::Factory::NewInstance(
+    const RemoteDevice& remote_device,
+    const std::string& device_address,
+    scoped_refptr<device::BluetoothAdapter> adapter,
+    const device::BluetoothUUID remote_service_uuid,
+    BluetoothThrottler* bluetooth_throttler) {
+  if (!factory_instance_) {
+    factory_instance_.reset(new Factory());
+  }
+  return factory_instance_->BuildInstance(
+      remote_device,
+      device_address,
+      adapter,
+      remote_service_uuid,
+      bluetooth_throttler);
+}
+
+// static
+void BluetoothLowEnergyWeaveClientConnection::Factory::SetInstanceForTesting(
+    std::shared_ptr<Factory> factory) {
+  factory_instance_ = factory;
+}
+
+std::unique_ptr<BluetoothLowEnergyWeaveClientConnection>
+BluetoothLowEnergyWeaveClientConnection::Factory::BuildInstance(
+    const RemoteDevice& remote_device,
+    const std::string& device_address,
+    scoped_refptr<device::BluetoothAdapter> adapter,
+    const device::BluetoothUUID remote_service_uuid,
+    BluetoothThrottler* bluetooth_throttler) {
+  return base::MakeUnique<BluetoothLowEnergyWeaveClientConnection>(
+      remote_device, device_address, adapter, remote_service_uuid,
+      bluetooth_throttler);
+}
+
 BluetoothLowEnergyWeaveClientConnection::
     BluetoothLowEnergyWeaveClientConnection(
         const RemoteDevice& device,
+        const std::string& device_address,
         scoped_refptr<device::BluetoothAdapter> adapter,
-        const BluetoothUUID remote_service_uuid,
-        BluetoothThrottler* bluetooth_throttler,
-        int max_number_of_write_attempts)
+        const device::BluetoothUUID remote_service_uuid,
+        BluetoothThrottler* bluetooth_throttler)
     : Connection(device),
+      device_address_(device_address),
       adapter_(adapter),
       remote_service_({remote_service_uuid, ""}),
       packet_generator_(
@@ -53,13 +95,12 @@
       packet_receiver_(
           BluetoothLowEnergyWeavePacketReceiver::Factory::NewInstance(
               BluetoothLowEnergyWeavePacketReceiver::ReceiverType::CLIENT)),
-      tx_characteristic_({BluetoothUUID(kTXCharacteristicUUID), ""}),
-      rx_characteristic_({BluetoothUUID(kRXCharacteristicUUID), ""}),
+      tx_characteristic_({device::BluetoothUUID(kTXCharacteristicUUID), ""}),
+      rx_characteristic_({device::BluetoothUUID(kRXCharacteristicUUID), ""}),
       bluetooth_throttler_(bluetooth_throttler),
       task_runner_(base::ThreadTaskRunnerHandle::Get()),
       sub_status_(SubStatus::DISCONNECTED),
       write_remote_characteristic_pending_(false),
-      max_number_of_write_attempts_(max_number_of_write_attempts),
       weak_ptr_factory_(this) {
   DCHECK(adapter_);
   DCHECK(adapter_->IsInitialized());
@@ -75,7 +116,7 @@
 
   if (adapter_) {
     adapter_->RemoveObserver(this);
-    adapter_ = NULL;
+    adapter_ = nullptr;
   }
 }
 
@@ -108,21 +149,23 @@
 void BluetoothLowEnergyWeaveClientConnection::CreateGattConnection() {
   DCHECK(sub_status() == SubStatus::WAITING_GATT_CONNECTION);
 
-  BluetoothDevice* remote_device = GetRemoteDevice();
-  if (remote_device) {
-    PA_LOG(INFO) << "Creating GATT connection with "
-                 << remote_device->GetAddress();
+  PA_LOG(INFO) << "Creating GATT connection with " << device_address_;
 
-    remote_device->CreateGattConnection(
-        base::Bind(
-            &BluetoothLowEnergyWeaveClientConnection::OnGattConnectionCreated,
-            weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&BluetoothLowEnergyWeaveClientConnection::
-                       OnCreateGattConnectionError,
-                   weak_ptr_factory_.GetWeakPtr()));
-  } else {
-    SetSubStatus(SubStatus::DISCONNECTED);
+  device::BluetoothDevice* bluetooth_device = GetBluetoothDevice();
+  if (!bluetooth_device) {
+    PA_LOG(WARNING) << "Could not create GATT connection with "
+                    << device_address_ << " because the device could not be "
+                    << "found.";
+    return;
   }
+
+  bluetooth_device->CreateGattConnection(
+      base::Bind(
+          &BluetoothLowEnergyWeaveClientConnection::OnGattConnectionCreated,
+          weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&BluetoothLowEnergyWeaveClientConnection::
+                     OnCreateGattConnectionError,
+                 weak_ptr_factory_.GetWeakPtr()));
 }
 
 void BluetoothLowEnergyWeaveClientConnection::Disconnect() {
@@ -200,8 +243,8 @@
 // here. If the GATT connection is dropped, we should call DestroyConnection()
 // anyway, so the object can notify its observers.
 void BluetoothLowEnergyWeaveClientConnection::DeviceChanged(
-    BluetoothAdapter* adapter,
-    BluetoothDevice* device) {
+    device::BluetoothAdapter* adapter,
+    device::BluetoothDevice* device) {
   DCHECK(device);
   if (sub_status() == SubStatus::DISCONNECTED ||
       device->GetAddress() != GetDeviceAddress())
@@ -219,8 +262,8 @@
 }
 
 void BluetoothLowEnergyWeaveClientConnection::DeviceRemoved(
-    BluetoothAdapter* adapter,
-    BluetoothDevice* device) {
+    device::BluetoothAdapter* adapter,
+    device::BluetoothDevice* device) {
   DCHECK(device);
   if (sub_status_ == SubStatus::DISCONNECTED ||
       device->GetAddress() != GetDeviceAddress())
@@ -231,8 +274,8 @@
 }
 
 void BluetoothLowEnergyWeaveClientConnection::GattCharacteristicValueChanged(
-    BluetoothAdapter* adapter,
-    BluetoothRemoteGattCharacteristic* characteristic,
+    device::BluetoothAdapter* adapter,
+    device::BluetoothRemoteGattCharacteristic* characteristic,
     const Packet& value) {
   DCHECK_EQ(adapter, adapter_.get());
   if (sub_status() != SubStatus::WAITING_CONNECTION_RESPONSE &&
@@ -319,7 +362,7 @@
     const BluetoothLowEnergyCharacteristicsFinder::ErrorCallback&
         error_callback) {
   return new BluetoothLowEnergyCharacteristicsFinder(
-      adapter_, GetRemoteDevice(), remote_service_, tx_characteristic_,
+      adapter_, GetBluetoothDevice(), remote_service_, tx_characteristic_,
       rx_characteristic_, success_callback, error_callback);
 }
 
@@ -359,7 +402,7 @@
 
 void BluetoothLowEnergyWeaveClientConnection::StartNotifySession() {
   DCHECK(sub_status() == SubStatus::CHARACTERISTICS_FOUND);
-  BluetoothRemoteGattCharacteristic* characteristic =
+  device::BluetoothRemoteGattCharacteristic* characteristic =
       GetGattCharacteristic(rx_characteristic_.id);
   CHECK(characteristic);
 
@@ -384,7 +427,7 @@
 }
 
 void BluetoothLowEnergyWeaveClientConnection::OnNotifySessionStarted(
-    std::unique_ptr<BluetoothGattNotifySession> notify_session) {
+    std::unique_ptr<device::BluetoothGattNotifySession> notify_session) {
   DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION);
   PA_LOG(INFO) << "Notification session started "
                << notify_session->GetCharacteristicIdentifier();
@@ -397,7 +440,7 @@
 }
 
 void BluetoothLowEnergyWeaveClientConnection::OnNotifySessionError(
-    BluetoothRemoteGattService::GattErrorCode error) {
+    device::BluetoothRemoteGattService::GattErrorCode error) {
   DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION);
   PA_LOG(WARNING) << "Error starting notification session: " << error;
   DestroyConnection();
@@ -425,12 +468,11 @@
 void BluetoothLowEnergyWeaveClientConnection::WriteRemoteCharacteristic(
     const WriteRequest& request) {
   write_requests_queue_.push(request);
-  PA_LOG(ERROR) << "you got " << request.message.get();
   ProcessNextWriteRequest();
 }
 
 void BluetoothLowEnergyWeaveClientConnection::ProcessNextWriteRequest() {
-  BluetoothRemoteGattCharacteristic* characteristic =
+  device::BluetoothRemoteGattCharacteristic* characteristic =
       GetGattCharacteristic(tx_characteristic_.id);
   if (!write_requests_queue_.empty() && !write_remote_characteristic_pending_ &&
       characteristic) {
@@ -478,7 +520,7 @@
 }
 
 void BluetoothLowEnergyWeaveClientConnection::OnWriteRemoteCharacteristicError(
-    BluetoothRemoteGattService::GattErrorCode error) {
+    device::BluetoothRemoteGattService::GattErrorCode error) {
   PA_LOG(WARNING) << "Error " << error << " writing characteristic: "
                   << tx_characteristic_.uuid.canonical_value();
 
@@ -487,9 +529,11 @@
   DCHECK(!write_requests_queue_.empty());
   WriteRequest* request = &write_requests_queue_.front();
 
-  // Increases the number of failed attempts and retry.
+  ++request->number_of_failed_attempts;
 
-  if (++request->number_of_failed_attempts >= max_number_of_write_attempts_) {
+  // If the message has failed to send the first time and up to
+  // |kMaxNumberOfRetryAttempts| retries, give up.
+  if (request->number_of_failed_attempts >= kMaxNumberOfRetryAttempts + 1) {
     switch (request->request_type) {
       case WriteRequestType::REGULAR:
       case WriteRequestType::MESSAGE_COMPLETE:
@@ -502,8 +546,9 @@
         NOTREACHED();
     }
 
-    // If the previous write failed that many times, probably can't write a
-    // connection close either, so just destroy the connection.
+    // If the previous write has failed each retry attempt up to the maximum
+    // number allowed, a "connection close" message cannot be sent since the
+    // connection is not working. Destroy the connection.
     DestroyConnection();
   } else {
     ProcessNextWriteRequest();
@@ -544,52 +589,43 @@
   // paired. The address in |gatt_connection_| is automatically updated in this
   // case.
   return gatt_connection_ ? gatt_connection_->GetDeviceAddress()
-                          : remote_device().bluetooth_address;
+                          : device_address_;
 }
 
-BluetoothDevice* BluetoothLowEnergyWeaveClientConnection::GetRemoteDevice() {
-  // It's not possible to simply use
-  // |adapter_->GetDevice(GetDeviceAddress())| to find the device with MAC
-  // address |GetDeviceAddress()|. For paired devices,
-  // BluetoothAdapter::GetDevice(XXX) searches for the temporary MAC address
-  // XXX, whereas |GetDeviceAddress()| is the real MAC address. This is a
-  // bug in the way device::BluetoothAdapter is storing the devices (see
-  // crbug.com/497841).
-  std::vector<BluetoothDevice*> devices = adapter_->GetDevices();
-  for (const auto& device : devices) {
-    if (device->GetAddress() == GetDeviceAddress())
-      return device;
-  }
-
-  return nullptr;
+device::BluetoothDevice*
+BluetoothLowEnergyWeaveClientConnection::GetBluetoothDevice() {
+  return adapter_->GetDevice(device_address_);
 }
 
-BluetoothRemoteGattService*
+device::BluetoothRemoteGattService*
 BluetoothLowEnergyWeaveClientConnection::GetRemoteService() {
-  BluetoothDevice* remote_device = GetRemoteDevice();
-  if (!remote_device) {
-    PA_LOG(WARNING) << "Remote device not found.";
-    return NULL;
+  device::BluetoothDevice* bluetooth_device = GetBluetoothDevice();
+  if (!bluetooth_device) {
+    PA_LOG(WARNING) << "Could not create GATT connection with "
+                    << device_address_ << " because the device could not be "
+                    << "found.";
+    return nullptr;
   }
+
   if (remote_service_.id.empty()) {
-    std::vector<BluetoothRemoteGattService*> services =
-        remote_device->GetGattServices();
+    std::vector<device::BluetoothRemoteGattService*> services =
+        bluetooth_device->GetGattServices();
     for (const auto& service : services)
       if (service->GetUUID() == remote_service_.uuid) {
         remote_service_.id = service->GetIdentifier();
         break;
       }
   }
-  return remote_device->GetGattService(remote_service_.id);
+  return bluetooth_device->GetGattService(remote_service_.id);
 }
 
-BluetoothRemoteGattCharacteristic*
+device::BluetoothRemoteGattCharacteristic*
 BluetoothLowEnergyWeaveClientConnection::GetGattCharacteristic(
     const std::string& gatt_characteristic) {
-  BluetoothRemoteGattService* remote_service = GetRemoteService();
+  device::BluetoothRemoteGattService* remote_service = GetRemoteService();
   if (!remote_service) {
     PA_LOG(WARNING) << "Remote service not found.";
-    return NULL;
+    return nullptr;
   }
   return remote_service->GetCharacteristic(gatt_characteristic);
 }
diff --git a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h
index 797c73241..8bb2413 100644
--- a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h
+++ b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h
@@ -37,6 +37,7 @@
 namespace cryptauth {
 
 namespace weave {
+
 // Creates GATT connection on top of the BLE connection and act as a Client.
 // uWeave communication follows the flow:
 // Client                           | Server
@@ -55,18 +56,28 @@
   class Factory {
    public:
     static std::unique_ptr<BluetoothLowEnergyWeaveClientConnection>
-    NewInstance();
+    NewInstance(
+        const RemoteDevice& remote_device,
+        const std::string& device_address,
+        scoped_refptr<device::BluetoothAdapter> adapter,
+        const device::BluetoothUUID remote_service_uuid,
+        BluetoothThrottler* bluetooth_throttler);
 
     // Exposed for testing.
-    static void SetInstanceForTesting(Factory* factory);
+    static void SetInstanceForTesting(std::shared_ptr<Factory> factory);
 
    protected:
     // Exposed for testing.
     virtual std::unique_ptr<BluetoothLowEnergyWeaveClientConnection>
-    BuildInstance();
+    BuildInstance(
+        const RemoteDevice& remote_device,
+        const std::string& device_address,
+        scoped_refptr<device::BluetoothAdapter> adapter,
+        const device::BluetoothUUID remote_service_uuid,
+        BluetoothThrottler* bluetooth_throttler);
 
    private:
-    static Factory* factory_instance_;
+    static std::shared_ptr<Factory> factory_instance_;
   };
 
   // The sub-state of a BluetoothLowEnergyWeaveClientConnection
@@ -89,10 +100,10 @@
   // made.
   BluetoothLowEnergyWeaveClientConnection(
       const RemoteDevice& remote_device,
+      const std::string& device_address,
       scoped_refptr<device::BluetoothAdapter> adapter,
       const device::BluetoothUUID remote_service_uuid,
-      BluetoothThrottler* bluetooth_throttler,
-      int max_number_of_write_attempts);
+      BluetoothThrottler* bluetooth_throttler);
 
   ~BluetoothLowEnergyWeaveClientConnection() override;
 
@@ -233,9 +244,6 @@
   // Prints the time elapsed since |Connect()| was called.
   void PrintTimeElapsed();
 
-  // Returns the device corresponding to |remote_device_address_|.
-  device::BluetoothDevice* GetRemoteDevice();
-
   // Returns the service corresponding to |remote_service_| in the current
   // device.
   device::BluetoothRemoteGattService* GetRemoteService();
@@ -250,6 +258,12 @@
   // Will crash if the receiver is not in CONNECTION_CLOSED state.
   std::string GetReasonForClose();
 
+  // Returns the device corresponding to |device_address_|.
+  device::BluetoothDevice* GetBluetoothDevice();
+
+  // The device to which to connect.
+  const std::string device_address_;
+
   // The Bluetooth adapter over which the Bluetooth connection will be made.
   scoped_refptr<device::BluetoothAdapter> adapter_;
 
@@ -297,9 +311,6 @@
 
   std::queue<WriteRequest> write_requests_queue_;
 
-  // Maximum number of tries to send any write request.
-  int max_number_of_write_attempts_;
-
   // Stores when the instace was created.
   base::TimeTicks start_time_;
 
diff --git a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
index cf49aa0..a2f1ead 100644
--- a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
+++ b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
@@ -305,15 +305,15 @@
  public:
   TestBluetoothLowEnergyWeaveClientConnection(
       const RemoteDevice& remote_device,
+      const std::string& device_address,
       scoped_refptr<device::BluetoothAdapter> adapter,
       const device::BluetoothUUID remote_service_uuid,
-      BluetoothThrottler* bluetooth_throttler,
-      int max_number_of_write_attempts)
+      BluetoothThrottler* bluetooth_throttler)
       : BluetoothLowEnergyWeaveClientConnection(remote_device,
+                                                device_address,
                                                 adapter,
                                                 remote_service_uuid,
-                                                bluetooth_throttler,
-                                                max_number_of_write_attempts) {}
+                                                bluetooth_throttler) {}
 
   ~TestBluetoothLowEnergyWeaveClientConnection() override {}
 
@@ -371,12 +371,13 @@
   }
 
   void SetUp() override {
-    device_ = base::MakeUnique<NiceMock<device::MockBluetoothDevice>>(
-        adapter_.get(), 0, kTestRemoteDeviceName,
-        kTestRemoteDeviceBluetoothAddress, false, false);
+    mock_bluetooth_device_ =
+        base::MakeUnique<NiceMock<device::MockBluetoothDevice>>(
+            adapter_.get(), 0, kTestRemoteDeviceName,
+            kTestRemoteDeviceBluetoothAddress, false, false);
 
     service_ = base::MakeUnique<NiceMock<device::MockBluetoothGattService>>(
-        device_.get(), kServiceID, service_uuid_, true, false);
+        mock_bluetooth_device_.get(), kServiceID, service_uuid_, true, false);
     tx_characteristic_ =
         base::MakeUnique<NiceMock<device::MockBluetoothGattCharacteristic>>(
             service_.get(), kTXCharacteristicID, tx_characteristic_uuid_, false,
@@ -392,11 +393,11 @@
     device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_);
 
     std::vector<const device::BluetoothDevice*> devices;
-    devices.push_back(device_.get());
+    devices.push_back(mock_bluetooth_device_.get());
     ON_CALL(*adapter_, GetDevices()).WillByDefault(Return(devices));
     ON_CALL(*adapter_, GetDevice(kTestRemoteDeviceBluetoothAddress))
-        .WillByDefault(Return(device_.get()));
-    ON_CALL(*device_, GetGattService(kServiceID))
+        .WillByDefault(Return(mock_bluetooth_device_.get()));
+    ON_CALL(*mock_bluetooth_device_, GetGattService(kServiceID))
         .WillByDefault(Return(service_.get()));
     ON_CALL(*service_, GetCharacteristic(kRXCharacteristicID))
         .WillByDefault(Return(rx_characteristic_.get()));
@@ -413,8 +414,8 @@
 
     std::unique_ptr<TestBluetoothLowEnergyWeaveClientConnection> connection(
         new TestBluetoothLowEnergyWeaveClientConnection(
-            remote_device_, adapter_, service_uuid_, bluetooth_throttler_.get(),
-            kMaxNumberOfTries));
+            remote_device_, kTestRemoteDeviceBluetoothAddress, adapter_,
+            service_uuid_, bluetooth_throttler_.get()));
 
     EXPECT_EQ(connection->sub_status(), SubStatus::DISCONNECTED);
     EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
@@ -431,7 +432,7 @@
   // state, without an existing GATT connection.
   void ConnectGatt(TestBluetoothLowEnergyWeaveClientConnection* connection) {
     // Preparing |connection| for a CreateGattConnection call.
-    EXPECT_CALL(*device_, CreateGattConnection(_, _))
+    EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection(_, _))
         .WillOnce(DoAll(SaveArg<0>(&create_gatt_connection_success_callback_),
                         SaveArg<1>(&create_gatt_connection_error_callback_)));
 
@@ -592,7 +593,7 @@
   device::BluetoothUUID service_uuid_;
   device::BluetoothUUID tx_characteristic_uuid_;
   device::BluetoothUUID rx_characteristic_uuid_;
-  std::unique_ptr<device::MockBluetoothDevice> device_;
+  std::unique_ptr<device::MockBluetoothDevice> mock_bluetooth_device_;
   std::unique_ptr<device::MockBluetoothGattService> service_;
   std::unique_ptr<device::MockBluetoothGattCharacteristic> tx_characteristic_;
   std::unique_ptr<device::MockBluetoothGattCharacteristic> rx_characteristic_;
@@ -632,8 +633,8 @@
 TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
        CreateAndDestroyWithoutConnectCallDoesntCrash) {
   BluetoothLowEnergyWeaveClientConnection connection(
-      remote_device_, adapter_, service_uuid_, bluetooth_throttler_.get(),
-      kMaxNumberOfTries);
+      remote_device_, kTestRemoteDeviceBluetoothAddress, adapter_,
+      service_uuid_, bluetooth_throttler_.get());
 }
 
 TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
@@ -1024,7 +1025,7 @@
 
   EXPECT_CALL(*bluetooth_throttler_, GetDelay())
       .WillOnce(Return(base::TimeDelta(base::TimeDelta::FromSeconds(1))));
-  EXPECT_CALL(*device_, CreateGattConnection(_, _))
+  EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection(_, _))
       .WillOnce(DoAll(SaveArg<0>(&create_gatt_connection_success_callback_),
                       SaveArg<1>(&create_gatt_connection_error_callback_)));
 
diff --git a/components/cryptauth/connection.h b/components/cryptauth/connection.h
index c134fbf4..dbc731d7 100644
--- a/components/cryptauth/connection.h
+++ b/components/cryptauth/connection.h
@@ -42,8 +42,8 @@
   // either success or failure.
   void SendMessage(std::unique_ptr<WireMessage> message);
 
-  void AddObserver(ConnectionObserver* observer);
-  void RemoveObserver(ConnectionObserver* observer);
+  virtual void AddObserver(ConnectionObserver* observer);
+  virtual void RemoveObserver(ConnectionObserver* observer);
 
   const RemoteDevice& remote_device() const {
     return remote_device_;
diff --git a/components/cryptauth/device_to_device_authenticator.cc b/components/cryptauth/device_to_device_authenticator.cc
index 425e314..7acc1a7 100644
--- a/components/cryptauth/device_to_device_authenticator.cc
+++ b/components/cryptauth/device_to_device_authenticator.cc
@@ -29,6 +29,39 @@
 
 }  // namespace
 
+// static
+std::shared_ptr<DeviceToDeviceAuthenticator::Factory>
+    DeviceToDeviceAuthenticator::Factory::factory_instance_ = nullptr;
+
+// static
+std::unique_ptr<Authenticator>
+DeviceToDeviceAuthenticator::Factory::NewInstance(
+    cryptauth::Connection* connection,
+    const std::string& account_id,
+    std::unique_ptr<cryptauth::SecureMessageDelegate> secure_message_delegate) {
+  if (!factory_instance_) {
+    factory_instance_.reset(new Factory());
+  }
+  return factory_instance_->BuildInstance(
+      connection, account_id, std::move(secure_message_delegate));
+}
+
+// static
+void DeviceToDeviceAuthenticator::Factory::SetInstanceForTesting(
+    std::shared_ptr<Factory> factory) {
+  factory_instance_ = factory;
+}
+
+std::unique_ptr<Authenticator>
+DeviceToDeviceAuthenticator::Factory::BuildInstance(
+    cryptauth::Connection* connection,
+    const std::string& account_id,
+    std::unique_ptr<cryptauth::SecureMessageDelegate>
+    secure_message_delegate) {
+  return base::WrapUnique(new DeviceToDeviceAuthenticator(
+      connection, account_id, std::move(secure_message_delegate)));
+}
+
 DeviceToDeviceAuthenticator::DeviceToDeviceAuthenticator(
     Connection* connection,
     const std::string& account_id,
diff --git a/components/cryptauth/device_to_device_authenticator.h b/components/cryptauth/device_to_device_authenticator.h
index ab98308..cbb39c9 100644
--- a/components/cryptauth/device_to_device_authenticator.h
+++ b/components/cryptauth/device_to_device_authenticator.h
@@ -43,6 +43,27 @@
 class DeviceToDeviceAuthenticator : public Authenticator,
                                     public ConnectionObserver {
  public:
+  class Factory {
+   public:
+    static std::unique_ptr<Authenticator> NewInstance(
+        cryptauth::Connection* connection,
+        const std::string& account_id,
+        std::unique_ptr<cryptauth::SecureMessageDelegate>
+            secure_message_delegate);
+
+    static void SetInstanceForTesting(std::shared_ptr<Factory> factory);
+
+   protected:
+    virtual std::unique_ptr<Authenticator> BuildInstance(
+        cryptauth::Connection* connection,
+        const std::string& account_id,
+        std::unique_ptr<cryptauth::SecureMessageDelegate>
+            secure_message_delegate);
+
+   private:
+    static std::shared_ptr<Factory> factory_instance_;
+  };
+
   // Creates the instance:
   // |connection|: The connection to the remote device, which must be in a
   //     connected state. Not owned.
diff --git a/components/cryptauth/fake_authenticator.cc b/components/cryptauth/fake_authenticator.cc
new file mode 100644
index 0000000..fb54ac3
--- /dev/null
+++ b/components/cryptauth/fake_authenticator.cc
@@ -0,0 +1,22 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/cryptauth/fake_authenticator.h"
+
+#include <utility>
+
+#include "base/memory/ptr_util.h"
+
+namespace cryptauth {
+
+FakeAuthenticator::FakeAuthenticator() {}
+
+FakeAuthenticator::~FakeAuthenticator() {}
+
+void FakeAuthenticator::Authenticate(
+    const Authenticator::AuthenticationCallback& callback) {
+  last_callback_ = callback;
+}
+
+}  // namespace cryptauth
diff --git a/components/cryptauth/fake_authenticator.h b/components/cryptauth/fake_authenticator.h
new file mode 100644
index 0000000..68e1eea
--- /dev/null
+++ b/components/cryptauth/fake_authenticator.h
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_CRYPTAUTH_FAKE_AUTHENTICATOR_H_
+#define COMPONENTS_CRYPTAUTH_FAKE_AUTHENTICATOR_H_
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "components/cryptauth/authenticator.h"
+
+namespace cryptauth {
+
+// A fake implementation of Authenticator to use in tests.
+class FakeAuthenticator : public Authenticator {
+ public:
+  FakeAuthenticator();
+  ~FakeAuthenticator() override;
+
+  // Authenticator:
+  void Authenticate(const AuthenticationCallback& callback)
+      override;
+
+  AuthenticationCallback last_callback() {
+    return last_callback_;
+  }
+
+ private:
+  AuthenticationCallback last_callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeAuthenticator);
+};
+
+}  // namespace cryptauth
+
+#endif  // COMPONENTS_CRYPTAUTH_FAKE_AUTHENTICATOR_H_
diff --git a/components/cryptauth/fake_connection.cc b/components/cryptauth/fake_connection.cc
index ce11c64..fc861ab 100644
--- a/components/cryptauth/fake_connection.cc
+++ b/components/cryptauth/fake_connection.cc
@@ -11,13 +11,15 @@
 
 namespace cryptauth {
 
-namespace {
-const char kFakeFeatureName[] = "fakeFeature";
-}  // namespace
-
 FakeConnection::FakeConnection(const RemoteDevice& remote_device)
-    : Connection(remote_device) {
-  Connect();
+    : FakeConnection(remote_device, /* should_auto_connect */ true) {}
+
+FakeConnection::FakeConnection(
+    const RemoteDevice& remote_device, bool should_auto_connect)
+    : Connection(remote_device), should_auto_connect_(should_auto_connect) {
+  if (should_auto_connect_) {
+    Connect();
+  }
 }
 
 FakeConnection::~FakeConnection() {
@@ -25,13 +27,40 @@
 }
 
 void FakeConnection::Connect() {
-  SetStatus(CONNECTED);
+  if (should_auto_connect_) {
+    SetStatus(CONNECTED);
+  } else {
+    SetStatus(IN_PROGRESS);
+  }
 }
 
 void FakeConnection::Disconnect() {
   SetStatus(DISCONNECTED);
 }
 
+void FakeConnection::AddObserver(ConnectionObserver* observer) {
+  observers_.push_back(observer);
+  Connection::AddObserver(observer);
+}
+
+void FakeConnection::RemoveObserver(ConnectionObserver* observer) {
+  observers_.erase(
+      std::remove(observers_.begin(), observers_.end(), observer),
+      observers_.end());
+  Connection::RemoveObserver(observer);
+}
+
+void FakeConnection::CompleteInProgressConnection(bool success) {
+  DCHECK(!should_auto_connect_);
+  DCHECK(status() == IN_PROGRESS);
+
+  if (success) {
+    SetStatus(CONNECTED);
+  } else {
+    SetStatus(DISCONNECTED);
+  }
+}
+
 void FakeConnection::FinishSendingMessageWithSuccess(bool success) {
   CHECK(current_message_);
   // Capture a copy of the message, as OnDidSendMessage() might reentrantly
@@ -40,9 +69,12 @@
   OnDidSendMessage(*sent_message, success);
 }
 
-void FakeConnection::ReceiveMessageWithPayload(const std::string& payload) {
+void FakeConnection::ReceiveMessage(
+    const std::string& feature, const std::string& payload) {
+  pending_feature_ = feature;
   pending_payload_ = payload;
   OnBytesReceived(std::string());
+  pending_feature_.clear();
   pending_payload_.clear();
 }
 
@@ -54,8 +86,7 @@
 std::unique_ptr<WireMessage> FakeConnection::DeserializeWireMessage(
     bool* is_incomplete_message) {
   *is_incomplete_message = false;
-  return base::MakeUnique<WireMessage>(
-      pending_payload_, std::string(kFakeFeatureName));
+  return base::MakeUnique<WireMessage>(pending_payload_, pending_feature_);
 }
 
 }  // namespace cryptauth
diff --git a/components/cryptauth/fake_connection.h b/components/cryptauth/fake_connection.h
index 9cb804f..cae66db 100644
--- a/components/cryptauth/fake_connection.h
+++ b/components/cryptauth/fake_connection.h
@@ -10,26 +10,41 @@
 
 namespace cryptauth {
 
+class ConnectionObserver;
+
 // A fake implementation of Connection to use in tests.
 class FakeConnection : public Connection {
  public:
   FakeConnection(const RemoteDevice& remote_device);
+  FakeConnection(const RemoteDevice& remote_device, bool should_auto_connect);
   ~FakeConnection() override;
 
   // Connection:
   void Connect() override;
   void Disconnect() override;
+  void AddObserver(ConnectionObserver* observer) override;
+  void RemoveObserver(ConnectionObserver* observer) override;
+
+  // Completes a connection attempt which was originally started via a call to
+  // |Connect()|. If |success| is true, the connection's status shifts to
+  // |CONNECTED|; otherwise, the status shifts to |DISCONNECTED|. Note that this
+  // function should only be called when |should_auto_connect| is false.
+  void CompleteInProgressConnection(bool success);
 
   // Completes the current send operation with success |success|.
   void FinishSendingMessageWithSuccess(bool success);
 
   // Simulates receiving a wire message with the given |payload|, bypassing the
   // container WireMessage format.
-  void ReceiveMessageWithPayload(const std::string& payload);
+  void ReceiveMessage(const std::string& feature, const std::string& payload);
 
   // Returns the current message in progress of being sent.
   WireMessage* current_message() { return current_message_.get(); }
 
+  std::vector<ConnectionObserver*>& observers() {
+    return observers_;
+  }
+
   using Connection::SetStatus;
 
  private:
@@ -42,10 +57,15 @@
   // SendMessageImpl() and FinishSendingMessageWithSuccess().
   std::unique_ptr<WireMessage> current_message_;
 
-  // The payload that should be returned when DeserializeWireMessage() is
-  // called.
+  // The feature and payload that should be returned when
+  // DeserializeWireMessage() is called.
+  std::string pending_feature_;
   std::string pending_payload_;
 
+  std::vector<ConnectionObserver*> observers_;
+
+  const bool should_auto_connect_;
+
   DISALLOW_COPY_AND_ASSIGN(FakeConnection);
 };
 
diff --git a/components/cryptauth/secure_channel.cc b/components/cryptauth/secure_channel.cc
new file mode 100644
index 0000000..c8ed9fd
--- /dev/null
+++ b/components/cryptauth/secure_channel.cc
@@ -0,0 +1,247 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/cryptauth/secure_channel.h"
+
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "components/cryptauth/wire_message.h"
+#include "components/proximity_auth/logging/logging.h"
+
+namespace cryptauth {
+
+// static
+std::string SecureChannel::StatusToString(const Status& status) {
+  switch (status) {
+    case Status::DISCONNECTED:
+      return "[disconnected]";
+    case Status::CONNECTING:
+      return "[connecting]";
+    case Status::CONNECTED:
+      return "[connected]";
+    case Status::AUTHENTICATING:
+      return "[authenticating]";
+    case Status::AUTHENTICATED:
+      return "[authenticated]";
+    default:
+      return "[unknown status]";
+  }
+}
+
+SecureChannel::Delegate::~Delegate() {}
+
+SecureChannel::PendingMessage::PendingMessage() {}
+
+SecureChannel::PendingMessage::PendingMessage(
+    const std::string& feature, const std::string& payload)
+    : feature(feature), payload(payload) {}
+
+SecureChannel::PendingMessage::~PendingMessage() {}
+
+SecureChannel::SecureChannel(
+    std::unique_ptr<Connection> connection,
+    std::unique_ptr<Delegate> delegate)
+    : connection_(std::move(connection)),
+      delegate_(std::move(delegate)),
+      status_(Status::DISCONNECTED),
+      weak_ptr_factory_(this) {
+  DCHECK(connection_);
+  DCHECK(!connection_->IsConnected());
+  DCHECK(!connection_->remote_device().user_id.empty());
+  DCHECK(delegate_);
+
+  connection_->AddObserver(this);
+}
+
+SecureChannel::~SecureChannel() {
+  connection_->RemoveObserver(this);
+}
+
+void SecureChannel::Initialize() {
+  DCHECK(status_ == Status::DISCONNECTED);
+  connection_->Connect();
+  TransitionToStatus(Status::CONNECTING);
+}
+
+void SecureChannel::SendMessage(
+    const std::string& feature, const std::string& payload) {
+  DCHECK(status_ == Status::AUTHENTICATED);
+
+  PA_LOG(INFO) << "Queuing new message to send: {"
+               << "feature: \"" << feature << "\", "
+               << "payload: \"" << payload << "\""
+               << "}";
+
+  queued_messages_.push_back(PendingMessage(feature, payload));
+  ProcessMessageQueue();
+}
+
+void SecureChannel::Disconnect() {
+  if (connection_->IsConnected()) {
+    connection_->Disconnect();
+  }
+
+  TransitionToStatus(Status::DISCONNECTED);
+}
+
+void SecureChannel::AddObserver(Observer* observer) {
+  observer_list_.AddObserver(observer);
+}
+
+void SecureChannel::RemoveObserver(Observer* observer) {
+  observer_list_.RemoveObserver(observer);
+}
+
+void SecureChannel::OnConnectionStatusChanged(
+    Connection* connection,
+    Connection::Status old_status,
+    Connection::Status new_status) {
+  DCHECK(connection == connection_.get());
+
+  if (new_status == Connection::Status::CONNECTED) {
+    TransitionToStatus(Status::CONNECTED);
+
+    // Once the connection has succeeded, authenticate the connection by
+    // initiating the security handshake.
+    Authenticate();
+    return;
+  }
+
+  if (new_status == Connection::Status::DISCONNECTED) {
+    // If the connection is no longer active, disconnect.
+    Disconnect();
+    return;
+  }
+}
+
+void SecureChannel::OnMessageReceived(const Connection& connection,
+                                      const WireMessage& wire_message) {
+  DCHECK(&connection == const_cast<const Connection*>(connection_.get()));
+  if (wire_message.feature() == Authenticator::kAuthenticationFeature) {
+    // If the message received was part of the authentication handshake, it
+    // is a low-level message and should not be forwarded to observers.
+    return;
+  }
+
+  secure_context_->Decode(wire_message.payload(),
+                          base::Bind(&SecureChannel::OnMessageDecoded,
+                                     weak_ptr_factory_.GetWeakPtr(),
+                                     wire_message.feature()));
+}
+
+void SecureChannel::OnSendCompleted(const cryptauth::Connection& connection,
+                                    const cryptauth::WireMessage& wire_message,
+                                    bool success) {
+  DCHECK(pending_message_->feature == wire_message.feature());
+
+  if (success && status_ != Status::DISCONNECTED) {
+    pending_message_.reset();
+    ProcessMessageQueue();
+    return;
+  }
+
+  PA_LOG(ERROR) << "Could not send message: {"
+                << "payload: \"" << pending_message_->payload << "\", "
+                << "feature: \"" << pending_message_->feature << "\""
+                << "}";
+  pending_message_.reset();
+
+  // The connection automatically retries failed messges, so if |success| is
+  // |false| here, a fatal error has occurred. Thus, there is no need to retry
+  // the message; instead, disconnect.
+  Disconnect();
+}
+
+void SecureChannel::TransitionToStatus(const Status& new_status) {
+  if (new_status == status_) {
+    // Only report changes to state.
+    return;
+  }
+
+  PA_LOG(INFO) << "Connection status changed: "
+               << StatusToString(status_)
+               << " => " << StatusToString(new_status);
+
+  Status old_status = status_;
+  status_ = new_status;
+
+  for (auto& observer : observer_list_) {
+    observer.OnSecureChannelStatusChanged(this, old_status, status_);
+  }
+}
+
+void SecureChannel::Authenticate() {
+  DCHECK(status_ == Status::CONNECTED);
+  DCHECK(!authenticator_);
+
+  authenticator_ = DeviceToDeviceAuthenticator::Factory::NewInstance(
+      connection_.get(),
+      connection_->remote_device().user_id,
+      delegate_->CreateSecureMessageDelegate());
+  authenticator_->Authenticate(
+      base::Bind(&SecureChannel::OnAuthenticationResult,
+                 weak_ptr_factory_.GetWeakPtr()));
+
+  TransitionToStatus(Status::AUTHENTICATING);
+}
+
+void SecureChannel::ProcessMessageQueue() {
+  if (pending_message_ || queued_messages_.empty())  {
+    return;
+  }
+
+  DCHECK(!connection_->is_sending_message());
+
+  pending_message_.reset(new PendingMessage(queued_messages_.front()));
+  queued_messages_.pop_front();
+
+  PA_LOG(INFO) << "Sending message: {"
+               << "feature: \"" << pending_message_->feature << "\", "
+               << "payload: \"" << pending_message_->payload << "\""
+               << "}";
+
+  secure_context_->Encode(pending_message_->payload,
+                          base::Bind(&SecureChannel::OnMessageEncoded,
+                                     weak_ptr_factory_.GetWeakPtr(),
+                                     pending_message_->feature));
+}
+
+void SecureChannel::OnMessageEncoded(
+    const std::string& feature, const std::string& encoded_message) {
+  connection_->SendMessage(base::MakeUnique<cryptauth::WireMessage>(
+      encoded_message, feature));
+}
+
+void SecureChannel::OnMessageDecoded(
+    const std::string& feature, const std::string& decoded_message) {
+  PA_LOG(INFO) << "Received message: {"
+               << "feature: \"" << feature << "\", "
+               << "payload: \"" << decoded_message << "\""
+               << "}";
+
+  for (auto& observer : observer_list_) {
+    observer.OnMessageReceived(this, feature, decoded_message);
+  }
+}
+
+void SecureChannel::OnAuthenticationResult(
+    Authenticator::Result result,
+    std::unique_ptr<SecureContext> secure_context) {
+  DCHECK(status_ == Status::AUTHENTICATING);
+
+  // The authenticator is no longer needed, so release it.
+  authenticator_.reset();
+
+  if (result != Authenticator::Result::SUCCESS) {
+    PA_LOG(WARNING) << "Failed to authenticate connection to device with ID "
+        << connection_->remote_device().GetTruncatedDeviceIdForLogs();
+    Disconnect();
+    return;
+  }
+
+  secure_context_ = std::move(secure_context);
+  TransitionToStatus(Status::AUTHENTICATED);
+}
+
+}  // namespace cryptauth
diff --git a/components/cryptauth/secure_channel.h b/components/cryptauth/secure_channel.h
new file mode 100644
index 0000000..4e18af9
--- /dev/null
+++ b/components/cryptauth/secure_channel.h
@@ -0,0 +1,137 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_CRYPTAUTH_SECURE_CHANNEL_H_
+#define COMPONENTS_CRYPTAUTH_SECURE_CHANNEL_H_
+
+#include <deque>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "components/cryptauth/authenticator.h"
+#include "components/cryptauth/connection.h"
+#include "components/cryptauth/connection_observer.h"
+#include "components/cryptauth/device_to_device_authenticator.h"
+#include "components/cryptauth/remote_device.h"
+#include "components/cryptauth/secure_context.h"
+#include "components/cryptauth/secure_message_delegate.h"
+
+namespace cryptauth {
+
+// An authenticated bi-directional channel for exchanging messages with remote
+// devices. |SecureChannel| manages a |Connection| by initializing it and
+// authenticating it via a security handshake once the connection has occurred.
+// Once the channel has been authenticated, messages sent are automatically
+// encrypted and messages received are automatically decrypted.
+class SecureChannel : public ConnectionObserver {
+ public:
+  // Enumeration of possible states of connecting to a remote device.
+  //   DISCONNECTED: There is no connection to the device, nor is there a
+  //       pending connection attempt.
+  //   CONNECTING: There is an ongoing connection attempt.
+  //   CONNECTED: There is a Bluetooth connection to the device, but the
+  //       connection has not yet been authenticated.
+  //   AUTHENTICATING: There is an active connection that is currently in the
+  //       process of authenticating via a 3-message authentication handshake.
+  //   AUTHENTICATED: The connection has been authenticated, and arbitrary
+  //       messages can be sent/received to/from the device.
+  enum class Status {
+    DISCONNECTED,
+    CONNECTING,
+    CONNECTED,
+    AUTHENTICATING,
+    AUTHENTICATED,
+  };
+
+  static std::string StatusToString(const Status& status);
+
+  class Observer {
+   public:
+    virtual void OnSecureChannelStatusChanged(
+        SecureChannel* secure_channel,
+        const Status& old_status,
+        const Status& new_status) = 0;
+
+    virtual void OnMessageReceived(
+        SecureChannel* secure_channel,
+        const std::string& feature,
+        const std::string& payload) = 0;
+  };
+
+  class Delegate {
+   public:
+    virtual ~Delegate();
+
+    virtual std::unique_ptr<SecureMessageDelegate>
+    CreateSecureMessageDelegate() = 0;
+  };
+
+  SecureChannel(
+      std::unique_ptr<Connection> connection,
+      std::unique_ptr<Delegate> delegate);
+  ~SecureChannel() override;
+
+  void Initialize();
+
+  void SendMessage(const std::string& feature, const std::string& payload);
+
+  void Disconnect();
+
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
+  Status status() const {
+    return status_;
+  }
+
+  // ConnectionObserver:
+  void OnConnectionStatusChanged(Connection* connection,
+                                 Connection::Status old_status,
+                                 Connection::Status new_status) override;
+  void OnMessageReceived(const Connection& connection,
+                         const WireMessage& wire_message) override;
+  void OnSendCompleted(const cryptauth::Connection& connection,
+                       const cryptauth::WireMessage& wire_message,
+                       bool success) override;
+
+ private:
+  // Message waiting to be sent. Note that this is *not* the message that will
+  // end up being sent over the wire; before that can be done, the payload must
+  // be encrypted.
+  struct PendingMessage {
+    PendingMessage();
+    PendingMessage(const std::string& feature, const std::string& payload);
+    virtual ~PendingMessage();
+
+    const std::string feature;
+    const std::string payload;
+  };
+
+  void TransitionToStatus(const Status& new_status);
+  void Authenticate();
+  void ProcessMessageQueue();
+  void OnMessageEncoded(
+      const std::string& feature, const std::string& encoded_message);
+  void OnMessageDecoded(
+      const std::string& feature, const std::string& decoded_message);
+  void OnAuthenticationResult(
+      Authenticator::Result result,
+      std::unique_ptr<SecureContext> secure_context);
+
+  std::unique_ptr<Connection> connection_;
+  std::unique_ptr<Delegate> delegate_;
+  std::unique_ptr<Authenticator> authenticator_;
+  std::unique_ptr<SecureContext> secure_context_;
+  Status status_;
+  std::deque<PendingMessage> queued_messages_;
+  std::unique_ptr<PendingMessage> pending_message_;
+  base::ObserverList<Observer> observer_list_;
+  base::WeakPtrFactory<SecureChannel> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(SecureChannel);
+};
+
+}  // namespace cryptauth
+
+#endif  // COMPONENTS_CRYPTAUTH_SECURE_CHANNEL_H_
diff --git a/components/cryptauth/secure_channel_unittest.cc b/components/cryptauth/secure_channel_unittest.cc
new file mode 100644
index 0000000..ebb8d90c
--- /dev/null
+++ b/components/cryptauth/secure_channel_unittest.cc
@@ -0,0 +1,549 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/cryptauth/secure_channel.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/weak_ptr.h"
+#include "components/cryptauth/fake_authenticator.h"
+#include "components/cryptauth/fake_connection.h"
+#include "components/cryptauth/fake_secure_context.h"
+#include "components/cryptauth/fake_secure_message_delegate.h"
+#include "components/cryptauth/remote_device_test_util.h"
+#include "components/cryptauth/wire_message.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cryptauth {
+
+namespace {
+
+const std::string test_user_id = "testUserId";
+
+class TestDelegate : public SecureChannel::Delegate {
+ public:
+  TestDelegate(std::unique_ptr<SecureMessageDelegate> secure_message_delegate)
+      : secure_message_delegate_(std::move(secure_message_delegate)) {}
+  ~TestDelegate() override {}
+
+  std::unique_ptr<SecureMessageDelegate> CreateSecureMessageDelegate()
+      override {
+    return std::move(secure_message_delegate_);
+  }
+
+ private:
+  std::unique_ptr<SecureMessageDelegate> secure_message_delegate_;
+};
+
+struct SecureChannelStatusChange {
+  SecureChannelStatusChange(
+      const SecureChannel::Status& old_status,
+      const SecureChannel::Status& new_status)
+      : old_status(old_status), new_status(new_status) {}
+
+  SecureChannel::Status old_status;
+  SecureChannel::Status new_status;
+};
+
+struct ReceivedMessage {
+  ReceivedMessage(const std::string& feature, const std::string& payload)
+      : feature(feature), payload(payload) {}
+
+  std::string feature;
+  std::string payload;
+};
+
+class TestObserver : public SecureChannel::Observer {
+ public:
+  TestObserver(SecureChannel* secure_channel)
+      : secure_channel_(secure_channel) {}
+
+  // SecureChannel::Observer:
+  void OnSecureChannelStatusChanged(
+      SecureChannel* secure_channel,
+      const SecureChannel::Status& old_status,
+      const SecureChannel::Status& new_status) override {
+    DCHECK(secure_channel == secure_channel_);
+    connection_status_changes_.push_back(
+        SecureChannelStatusChange(old_status, new_status));
+  }
+
+  void OnMessageReceived(SecureChannel* secure_channel,
+                         const std::string& feature,
+                         const std::string& payload) override {
+    DCHECK(secure_channel == secure_channel_);
+    received_messages_.push_back(ReceivedMessage(feature, payload));
+  }
+
+  std::vector<SecureChannelStatusChange>& connection_status_changes() {
+    return connection_status_changes_;
+  }
+
+  std::vector<ReceivedMessage>& received_messages() {
+    return received_messages_;
+  }
+
+ private:
+  SecureChannel* secure_channel_;
+  std::vector<SecureChannelStatusChange> connection_status_changes_;
+  std::vector<ReceivedMessage> received_messages_;
+};
+
+class TestAuthenticatorFactory : public DeviceToDeviceAuthenticator::Factory {
+ public:
+  TestAuthenticatorFactory() : last_instance_(nullptr) {}
+
+  std::unique_ptr<Authenticator> BuildInstance(
+      cryptauth::Connection* connection,
+      const std::string& account_id,
+      std::unique_ptr<cryptauth::SecureMessageDelegate>
+          secure_message_delegate) override {
+    last_instance_ = new FakeAuthenticator();
+    return base::WrapUnique(last_instance_);
+  }
+
+  Authenticator* last_instance() {
+    return last_instance_;
+  }
+
+ private:
+  Authenticator* last_instance_;
+};
+
+RemoteDevice CreateTestRemoteDevice() {
+  RemoteDevice remote_device = GenerateTestRemoteDevices(1)[0];
+  remote_device.user_id = test_user_id;
+  return remote_device;
+}
+
+}  // namespace
+
+class CryptAuthSecureChannelTest : public testing::Test {
+ protected:
+  CryptAuthSecureChannelTest()
+      : test_device_(CreateTestRemoteDevice()),
+        weak_ptr_factory_(this) {}
+
+  void SetUp() override {
+    test_authenticator_factory_ = std::shared_ptr<TestAuthenticatorFactory>(
+        new TestAuthenticatorFactory());
+    DeviceToDeviceAuthenticator::Factory::SetInstanceForTesting(
+        test_authenticator_factory_);
+
+    fake_secure_context_ = nullptr;
+
+    fake_secure_message_delegate_ = new FakeSecureMessageDelegate();
+
+    test_delegate_ =
+        new TestDelegate(base::WrapUnique(fake_secure_message_delegate_));
+
+    fake_connection_ =
+        new FakeConnection(test_device_, /* should_auto_connect */ false);
+
+    EXPECT_FALSE(fake_connection_->observers().size());
+    secure_channel_ = base::MakeUnique<SecureChannel>(
+        base::WrapUnique(fake_connection_), base::WrapUnique(test_delegate_));
+    EXPECT_EQ(static_cast<size_t>(1), fake_connection_->observers().size());
+    EXPECT_EQ(secure_channel_.get(), fake_connection_->observers()[0]);
+
+    test_observer_ = base::MakeUnique<TestObserver>(secure_channel_.get());
+    secure_channel_->AddObserver(test_observer_.get());
+  }
+
+  void TearDown() override {
+    // All state changes should have already been verified. This ensures that
+    // no test has missed one.
+    VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>());
+
+    // Same with received messages.
+    VerifyReceivedMessages(std::vector<ReceivedMessage>());
+
+    // Same with messages being sent.
+    VerifyNoMessageBeingSent();
+  }
+
+  void VerifyConnectionStateChanges(
+      const std::vector<SecureChannelStatusChange>& expected_changes) {
+    verified_status_changes_.insert(
+        verified_status_changes_.end(),
+        expected_changes.begin(),
+        expected_changes.end());
+
+    ASSERT_EQ(
+        verified_status_changes_.size(),
+        test_observer_->connection_status_changes().size());
+
+    for (size_t i = 0; i < verified_status_changes_.size(); i++) {
+      EXPECT_EQ(
+          verified_status_changes_[i].old_status,
+          test_observer_->connection_status_changes()[i].old_status);
+      EXPECT_EQ(
+          verified_status_changes_[i].new_status,
+          test_observer_->connection_status_changes()[i].new_status);
+    }
+  }
+
+  void VerifyReceivedMessages(
+      const std::vector<ReceivedMessage>& expected_messages) {
+    verified_received_messages_.insert(
+        verified_received_messages_.end(),
+        expected_messages.begin(),
+        expected_messages.end());
+
+    ASSERT_EQ(
+        verified_received_messages_.size(),
+        test_observer_->received_messages().size());
+
+    for (size_t i = 0; i < verified_received_messages_.size(); i++) {
+      EXPECT_EQ(
+          verified_received_messages_[i].feature,
+          test_observer_->received_messages()[i].feature);
+      EXPECT_EQ(
+          verified_received_messages_[i].payload,
+          test_observer_->received_messages()[i].payload);
+    }
+  }
+
+  void FailAuthentication(Authenticator::Result result) {
+    ASSERT_NE(result, Authenticator::Result::SUCCESS);
+
+    FakeAuthenticator* authenticator = static_cast<FakeAuthenticator*>(
+        test_authenticator_factory_->last_instance());
+    authenticator->last_callback().Run(result, nullptr);
+  }
+
+  void AuthenticateSuccessfully() {
+    FakeAuthenticator* authenticator = static_cast<FakeAuthenticator*>(
+        test_authenticator_factory_->last_instance());
+
+    fake_secure_context_ = new FakeSecureContext();
+    authenticator->last_callback().Run(
+        Authenticator::Result::SUCCESS, base::WrapUnique(fake_secure_context_));
+  }
+
+  void ConnectAndAuthenticate() {
+    secure_channel_->Initialize();
+    VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+        {
+          SecureChannel::Status::DISCONNECTED,
+          SecureChannel::Status::CONNECTING
+        }
+    });
+
+    fake_connection_->CompleteInProgressConnection(/* success */ true);
+    VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+        {
+          SecureChannel::Status::CONNECTING,
+          SecureChannel::Status::CONNECTED
+        },
+        {
+          SecureChannel::Status::CONNECTED,
+          SecureChannel::Status::AUTHENTICATING
+        }
+    });
+
+    AuthenticateSuccessfully();
+    VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+        {
+          SecureChannel::Status::AUTHENTICATING,
+          SecureChannel::Status::AUTHENTICATED
+        }
+    });
+  }
+
+  void StartSendingMessage(
+      const std::string& feature, const std::string& payload) {
+    secure_channel_->SendMessage(feature, payload);
+    VerifyMessageBeingSent(feature, payload);
+  }
+
+  void StartAndFinishSendingMessage(
+      const std::string& feature, const std::string& payload, bool success) {
+    StartSendingMessage(feature, payload);
+    fake_connection_->FinishSendingMessageWithSuccess(success);
+  }
+
+  void VerifyNoMessageBeingSent() {
+    EXPECT_FALSE(fake_connection_->current_message());
+  }
+
+  void VerifyMessageBeingSent(
+      const std::string& feature, const std::string& payload) {
+    WireMessage* message_being_sent = fake_connection_->current_message();
+    // Note that despite the fact that |Encode()| has an asynchronous interface,
+    // the implementation will call |VerifyWireMessageContents()| synchronously.
+    fake_secure_context_->Encode(
+        payload,
+        base::Bind(&CryptAuthSecureChannelTest::VerifyWireMessageContents,
+                   weak_ptr_factory_.GetWeakPtr(),
+                   message_being_sent,
+                   feature));
+  }
+
+  void VerifyWireMessageContents(
+      WireMessage* wire_message,
+      const std::string& expected_feature,
+      const std::string& expected_payload) {
+    EXPECT_EQ(expected_feature, wire_message->feature());
+    EXPECT_EQ(expected_payload, wire_message->payload());
+  }
+
+  // Owned by secure_channel_.
+  FakeConnection* fake_connection_;
+
+  // Owned by secure_chanel_.
+  TestDelegate* test_delegate_;
+
+  // Owned by test_delegate_.
+  FakeSecureMessageDelegate* fake_secure_message_delegate_;
+
+  // Owned by secure_channel_ once authentication has completed successfully.
+  FakeSecureContext* fake_secure_context_;
+
+  std::vector<SecureChannelStatusChange> verified_status_changes_;
+
+  std::vector<ReceivedMessage> verified_received_messages_;
+
+  std::unique_ptr<SecureChannel> secure_channel_;
+
+  std::unique_ptr<TestObserver> test_observer_;
+
+  std::shared_ptr<TestAuthenticatorFactory> test_authenticator_factory_;
+
+  const RemoteDevice test_device_;
+
+  base::WeakPtrFactory<CryptAuthSecureChannelTest> weak_ptr_factory_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CryptAuthSecureChannelTest);
+};
+
+TEST_F(CryptAuthSecureChannelTest, ConnectionAttemptFails) {
+  secure_channel_->Initialize();
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::DISCONNECTED,
+        SecureChannel::Status::CONNECTING
+      }
+  });
+
+  fake_connection_->CompleteInProgressConnection(/* success */ false);
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::CONNECTING,
+        SecureChannel::Status::DISCONNECTED
+      }
+  });
+}
+
+TEST_F(CryptAuthSecureChannelTest, DisconnectBeforeAuthentication) {
+  secure_channel_->Initialize();
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::DISCONNECTED,
+        SecureChannel::Status::CONNECTING
+      }
+  });
+
+  fake_connection_->Disconnect();
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::CONNECTING,
+        SecureChannel::Status::DISCONNECTED
+      }
+  });
+}
+
+TEST_F(CryptAuthSecureChannelTest, AuthenticationFails_Disconnect) {
+  secure_channel_->Initialize();
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::DISCONNECTED,
+        SecureChannel::Status::CONNECTING
+      }
+  });
+
+  fake_connection_->CompleteInProgressConnection(/* success */ true);
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::CONNECTING,
+        SecureChannel::Status::CONNECTED
+      },
+      {
+        SecureChannel::Status::CONNECTED,
+        SecureChannel::Status::AUTHENTICATING
+      }
+  });
+
+  FailAuthentication(Authenticator::Result::DISCONNECTED);
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::AUTHENTICATING,
+        SecureChannel::Status::DISCONNECTED
+      }
+  });
+}
+
+TEST_F(CryptAuthSecureChannelTest, AuthenticationFails_Failure) {
+  secure_channel_->Initialize();
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::DISCONNECTED,
+        SecureChannel::Status::CONNECTING
+      }
+  });
+
+  fake_connection_->CompleteInProgressConnection(/* success */ true);
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::CONNECTING,
+        SecureChannel::Status::CONNECTED
+      },
+      {
+        SecureChannel::Status::CONNECTED,
+        SecureChannel::Status::AUTHENTICATING
+      }
+  });
+
+  FailAuthentication(Authenticator::Result::FAILURE);
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::AUTHENTICATING,
+        SecureChannel::Status::DISCONNECTED
+      }
+  });
+}
+
+TEST_F(CryptAuthSecureChannelTest, SendMessage_DisconnectWhileSending) {
+  ConnectAndAuthenticate();
+  StartSendingMessage("feature", "payload");
+
+  fake_connection_->Disconnect();
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::AUTHENTICATED,
+        SecureChannel::Status::DISCONNECTED
+      }
+  });
+
+  fake_connection_->FinishSendingMessageWithSuccess(false);
+  // No further state change should have occurred.
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>());
+}
+
+TEST_F(
+    CryptAuthSecureChannelTest,
+    SendMessage_DisconnectWhileSending_ThenSendCompletedOccurs) {
+  ConnectAndAuthenticate();
+  StartSendingMessage("feature", "payload");
+
+  fake_connection_->Disconnect();
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::AUTHENTICATED,
+        SecureChannel::Status::DISCONNECTED
+      }
+  });
+
+  // If, due to a race condition, a disconnection occurs and |SendCompleted()|
+  // is called in the success case, nothing should occur.
+  fake_connection_->FinishSendingMessageWithSuccess(true);
+
+  // No further state change should have occurred.
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange>());
+}
+
+TEST_F(CryptAuthSecureChannelTest, SendMessage_Failure) {
+  ConnectAndAuthenticate();
+  StartAndFinishSendingMessage("feature", "payload", /* success */ false);
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::AUTHENTICATED,
+        SecureChannel::Status::DISCONNECTED
+      }
+  });
+}
+
+TEST_F(CryptAuthSecureChannelTest, SendMessage_Success) {
+  ConnectAndAuthenticate();
+  StartAndFinishSendingMessage("feature", "payload", /* success */ true);
+}
+
+TEST_F(CryptAuthSecureChannelTest, SendMessage_MultipleMessages_Success) {
+  ConnectAndAuthenticate();
+
+  // Send a second message before the first has completed.
+  secure_channel_->SendMessage("feature1", "payload1");
+  secure_channel_->SendMessage("feature2", "payload2");
+
+  // The first message should still be sending.
+  VerifyMessageBeingSent("feature1", "payload1");
+
+  // Send the first message.
+  fake_connection_->FinishSendingMessageWithSuccess(true);
+
+  // Now, the second message should be sending.
+  VerifyMessageBeingSent("feature2", "payload2");
+  fake_connection_->FinishSendingMessageWithSuccess(true);
+}
+
+TEST_F(CryptAuthSecureChannelTest, SendMessage_MultipleMessages_FirstFails) {
+  ConnectAndAuthenticate();
+
+  // Send a second message before the first has completed.
+  secure_channel_->SendMessage("feature1", "payload1");
+  secure_channel_->SendMessage("feature2", "payload2");
+
+  // The first message should still be sending.
+  VerifyMessageBeingSent("feature1", "payload1");
+
+  // Fail sending the first message.
+  fake_connection_->FinishSendingMessageWithSuccess(false);
+
+  // The connection should have become disconnected.
+  VerifyConnectionStateChanges(std::vector<SecureChannelStatusChange> {
+      {
+        SecureChannel::Status::AUTHENTICATED,
+        SecureChannel::Status::DISCONNECTED
+      }
+  });
+
+  // The first message failed, so no other ones should be tried afterward.
+  VerifyNoMessageBeingSent();
+}
+
+TEST_F(CryptAuthSecureChannelTest, ReceiveMessage) {
+  ConnectAndAuthenticate();
+
+  // Note: FakeSecureContext's Encode() function simply adds ", but encoded" to
+  // the end of the message.
+  fake_connection_->ReceiveMessage("feature", "payload, but encoded");
+  VerifyReceivedMessages(std::vector<ReceivedMessage> {
+      {"feature", "payload"}
+  });
+}
+
+TEST_F(CryptAuthSecureChannelTest, SendAndReceiveMessages) {
+  ConnectAndAuthenticate();
+
+  StartAndFinishSendingMessage("feature", "request1", /* success */ true);
+
+  // Note: FakeSecureContext's Encode() function simply adds ", but encoded" to
+  // the end of the message.
+  fake_connection_->ReceiveMessage("feature", "response1, but encoded");
+  VerifyReceivedMessages(std::vector<ReceivedMessage> {
+      {"feature", "response1"}
+  });
+
+  StartAndFinishSendingMessage("feature", "request2", /* success */ true);
+
+  fake_connection_->ReceiveMessage("feature", "response2, but encoded");
+  VerifyReceivedMessages(std::vector<ReceivedMessage> {
+      {"feature", "response2"}
+  });
+}
+
+}  // namespace cryptauth
diff --git a/components/leveldb/leveldb_app.cc b/components/leveldb/leveldb_app.cc
index cff8bc3..cb15293d 100644
--- a/components/leveldb/leveldb_app.cc
+++ b/components/leveldb/leveldb_app.cc
@@ -4,14 +4,13 @@
 
 #include "components/leveldb/leveldb_app.h"
 
-#include "base/threading/thread_task_runner_handle.h"
 #include "components/leveldb/leveldb_service_impl.h"
 #include "services/service_manager/public/cpp/interface_registry.h"
 #include "services/service_manager/public/cpp/service_context.h"
 
 namespace leveldb {
 
-LevelDBApp::LevelDBApp() {}
+LevelDBApp::LevelDBApp() : file_thread_("LevelDBFile") {}
 
 LevelDBApp::~LevelDBApp() {}
 
@@ -27,8 +26,12 @@
 
 void LevelDBApp::Create(const service_manager::Identity& remote_identity,
                         leveldb::mojom::LevelDBServiceRequest request) {
-  if (!service_)
-    service_.reset(new LevelDBServiceImpl(base::ThreadTaskRunnerHandle::Get()));
+  if (!service_) {
+    if (!file_thread_.IsRunning())
+      file_thread_.Start();
+    service_.reset(
+        new LevelDBServiceImpl(file_thread_.message_loop()->task_runner()));
+  }
   bindings_.AddBinding(service_.get(), std::move(request));
 }
 
diff --git a/components/leveldb/leveldb_app.h b/components/leveldb/leveldb_app.h
index fcaa15f..b69efe8 100644
--- a/components/leveldb/leveldb_app.h
+++ b/components/leveldb/leveldb_app.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "base/threading/thread.h"
 #include "components/leveldb/public/interfaces/leveldb.mojom.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
 #include "services/service_manager/public/cpp/interface_factory.h"
@@ -36,6 +37,8 @@
   std::unique_ptr<mojom::LevelDBService> service_;
   mojo::BindingSet<mojom::LevelDBService> bindings_;
 
+  base::Thread file_thread_;
+
   DISALLOW_COPY_AND_ASSIGN(LevelDBApp);
 };
 
diff --git a/components/leveldb/leveldb_mojo_proxy.cc b/components/leveldb/leveldb_mojo_proxy.cc
index 74446206..97fcde7e6 100644
--- a/components/leveldb/leveldb_mojo_proxy.cc
+++ b/components/leveldb/leveldb_mojo_proxy.cc
@@ -28,7 +28,9 @@
 
 LevelDBMojoProxy::LevelDBMojoProxy(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : task_runner_(std::move(task_runner)), outstanding_opaque_dirs_(0) {}
+    : task_runner_(std::move(task_runner)), outstanding_opaque_dirs_(0) {
+  DCHECK(!task_runner_->BelongsToCurrentThread());
+}
 
 LevelDBMojoProxy::OpaqueDir* LevelDBMojoProxy::RegisterDirectory(
     filesystem::mojom::DirectoryPtr directory) {
diff --git a/components/leveldb/leveldb_service_impl.cc b/components/leveldb/leveldb_service_impl.cc
index f2f0228..2f754112 100644
--- a/components/leveldb/leveldb_service_impl.cc
+++ b/components/leveldb/leveldb_service_impl.cc
@@ -21,8 +21,8 @@
 namespace leveldb {
 
 LevelDBServiceImpl::LevelDBServiceImpl(
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : thread_(new LevelDBMojoProxy(std::move(task_runner))) {}
+    scoped_refptr<base::SingleThreadTaskRunner> file_task_runner)
+    : thread_(new LevelDBMojoProxy(std::move(file_task_runner))) {}
 
 LevelDBServiceImpl::~LevelDBServiceImpl() {}
 
diff --git a/components/leveldb/leveldb_service_impl.h b/components/leveldb/leveldb_service_impl.h
index a9f5bef..3cc1210 100644
--- a/components/leveldb/leveldb_service_impl.h
+++ b/components/leveldb/leveldb_service_impl.h
@@ -15,7 +15,11 @@
 // Creates LevelDBDatabases based scoped to a |directory|/|dbname|.
 class LevelDBServiceImpl : public mojom::LevelDBService {
  public:
-  LevelDBServiceImpl(scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+  // The |file_task_runner| is used to run tasks to interact with the
+  // file_service. Specifically this task runner must NOT be the same as the
+  // task runner this implementation runs on, or deadlock might occur.
+  LevelDBServiceImpl(
+      scoped_refptr<base::SingleThreadTaskRunner> file_task_runner);
   ~LevelDBServiceImpl() override;
 
   // Overridden from LevelDBService:
diff --git a/components/metrics/proto/ukm/source.proto b/components/metrics/proto/ukm/source.proto
index 44afe3a..e48f252 100644
--- a/components/metrics/proto/ukm/source.proto
+++ b/components/metrics/proto/ukm/source.proto
@@ -24,6 +24,6 @@
   // events related to this Source will generally be relative to this timestamp.
   optional int64 navigation_time_msec = 3;
 
-  // Time between navigation and the first meaningful paint, in milliseconds.
-  optional int64 first_meaningful_paint_msec = 4;
+  // Time between navigation and the first contentful paint, in milliseconds.
+  optional int64 first_contentful_paint_msec = 4;
 }
diff --git a/components/proximity_auth/messenger_impl_unittest.cc b/components/proximity_auth/messenger_impl_unittest.cc
index 7f7257e..fa88a735 100644
--- a/components/proximity_auth/messenger_impl_unittest.cc
+++ b/components/proximity_auth/messenger_impl_unittest.cc
@@ -32,6 +32,7 @@
 namespace proximity_auth {
 namespace {
 
+const char kTestFeature[] = "testFeature";
 const char kChallenge[] = "a most difficult challenge";
 
 class MockMessengerObserver : public MessengerObserver {
@@ -206,7 +207,8 @@
   messenger.GetFakeConnection()->FinishSendingMessageWithSuccess(true);
 
   EXPECT_CALL(observer, OnDecryptResponseProxy(std::string()));
-  messenger.GetFakeConnection()->ReceiveMessageWithPayload(
+  messenger.GetFakeConnection()->ReceiveMessage(
+      std::string(kTestFeature),
       "{\"type\":\"decrypt_response\"}, but encoded");
 }
 
@@ -218,7 +220,8 @@
   messenger.GetFakeConnection()->FinishSendingMessageWithSuccess(true);
 
   EXPECT_CALL(observer, OnDecryptResponseProxy(std::string()));
-  messenger.GetFakeConnection()->ReceiveMessageWithPayload(
+  messenger.GetFakeConnection()->ReceiveMessage(
+      std::string(kTestFeature),
       "{"
       "\"type\":\"decrypt_response\","
       "\"data\":\"not a base64-encoded string\""
@@ -233,7 +236,8 @@
   messenger.GetFakeConnection()->FinishSendingMessageWithSuccess(true);
 
   EXPECT_CALL(observer, OnDecryptResponseProxy("a winner is you"));
-  messenger.GetFakeConnection()->ReceiveMessageWithPayload(
+  messenger.GetFakeConnection()->ReceiveMessage(
+      std::string(kTestFeature),
       "{"
       "\"type\":\"decrypt_response\","
       "\"data\":\"YSB3aW5uZXIgaXMgeW91\""  // "a winner is you", base64-encoded
@@ -249,7 +253,8 @@
   messenger.GetFakeConnection()->FinishSendingMessageWithSuccess(true);
 
   EXPECT_CALL(observer, OnDecryptResponseProxy("\xFF\xE6"));
-  messenger.GetFakeConnection()->ReceiveMessageWithPayload(
+  messenger.GetFakeConnection()->ReceiveMessage(
+      std::string(kTestFeature),
       "{"
       "\"type\":\"decrypt_response\","
       "\"data\":\"_-Y=\""  // "\0xFF\0xE6", base64url-encoded.
@@ -301,8 +306,8 @@
   messenger.GetFakeConnection()->FinishSendingMessageWithSuccess(true);
 
   EXPECT_CALL(observer, OnUnlockResponse(true));
-  messenger.GetFakeConnection()->ReceiveMessageWithPayload(
-      "{\"type\":\"unlock_response\"}, but encoded");
+  messenger.GetFakeConnection()->ReceiveMessage(
+      std::string(kTestFeature), "{\"type\":\"unlock_response\"}, but encoded");
 }
 
 TEST(ProximityAuthMessengerImplTest,
@@ -312,8 +317,8 @@
 
   // Receive a status update message that's missing all the data.
   EXPECT_CALL(observer, OnRemoteStatusUpdate(_)).Times(0);
-  messenger.GetFakeConnection()->ReceiveMessageWithPayload(
-      "{\"type\":\"status_update\"}, but encoded");
+  messenger.GetFakeConnection()->ReceiveMessage(
+      std::string(kTestFeature), "{\"type\":\"status_update\"}, but encoded");
 }
 
 TEST(ProximityAuthMessengerImplTest,
@@ -328,7 +333,8 @@
                               SECURE_SCREEN_LOCK_ENABLED),
                         Field(&RemoteStatusUpdate::trust_agent_state,
                               TRUST_AGENT_UNSUPPORTED))));
-  messenger.GetFakeConnection()->ReceiveMessageWithPayload(
+  messenger.GetFakeConnection()->ReceiveMessage(
+      std::string(kTestFeature),
       "{"
       "\"type\":\"status_update\","
       "\"user_presence\":\"present\","
@@ -344,8 +350,8 @@
   messenger.GetFakeConnection()->FinishSendingMessageWithSuccess(true);
 
   // The StrictMock will verify that no observer methods are called.
-  messenger.GetFakeConnection()->ReceiveMessageWithPayload(
-      "Not JSON, but encoded");
+  messenger.GetFakeConnection()->ReceiveMessage(std::string(kTestFeature),
+                                                "Not JSON, but encoded");
 }
 
 TEST(ProximityAuthMessengerImplTest, OnMessageReceived_MissingTypeField) {
@@ -355,7 +361,8 @@
   messenger.GetFakeConnection()->FinishSendingMessageWithSuccess(true);
 
   // The StrictMock will verify that no observer methods are called.
-  messenger.GetFakeConnection()->ReceiveMessageWithPayload(
+  messenger.GetFakeConnection()->ReceiveMessage(
+      std::string(kTestFeature),
       "{\"some key that's not 'type'\":\"some value\"}, but encoded");
 }
 
@@ -364,8 +371,8 @@
   StrictMock<MockMessengerObserver> observer(&messenger);
 
   // The StrictMock will verify that no observer methods are called.
-  messenger.GetFakeConnection()->ReceiveMessageWithPayload(
-      "{\"type\":\"unlock_response\"}, but encoded");
+  messenger.GetFakeConnection()->ReceiveMessage(
+      std::string(kTestFeature), "{\"type\":\"unlock_response\"}, but encoded");
 }
 
 TEST(ProximityAuthMessengerImplTest,
@@ -377,8 +384,8 @@
   messenger.GetFakeConnection()->FinishSendingMessageWithSuccess(true);
 
   // The StrictMock will verify that no observer methods are called.
-  messenger.GetFakeConnection()->ReceiveMessageWithPayload(
-      "{\"type\":\"unlock_response\"}, but encoded");
+  messenger.GetFakeConnection()->ReceiveMessage(
+      std::string(kTestFeature), "{\"type\":\"unlock_response\"}, but encoded");
 }
 
 TEST(ProximityAuthMessengerImplTest,
@@ -390,7 +397,8 @@
   messenger.GetFakeConnection()->FinishSendingMessageWithSuccess(true);
 
   // The StrictMock will verify that no observer methods are called.
-  messenger.GetFakeConnection()->ReceiveMessageWithPayload(
+  messenger.GetFakeConnection()->ReceiveMessage(
+      std::string(kTestFeature),
       "{"
       "\"type\":\"decrypt_response\","
       "\"data\":\"YSB3aW5uZXIgaXMgeW91\""
@@ -427,7 +435,8 @@
 
   // Now simulate a response arriving for the original decryption request.
   EXPECT_CALL(observer, OnDecryptResponseProxy("a winner is you"));
-  messenger.GetFakeConnection()->ReceiveMessageWithPayload(
+  messenger.GetFakeConnection()->ReceiveMessage(
+      std::string(kTestFeature),
       "{"
       "\"type\":\"decrypt_response\","
       "\"data\":\"YSB3aW5uZXIgaXMgeW91\""
diff --git a/components/ukm/BUILD.gn b/components/ukm/BUILD.gn
index 5b97d07..4cd8a195 100644
--- a/components/ukm/BUILD.gn
+++ b/components/ukm/BUILD.gn
@@ -17,6 +17,8 @@
     "ukm_pref_names.h",
     "ukm_service.cc",
     "ukm_service.h",
+    "ukm_source.cc",
+    "ukm_source.h",
   ]
 
   deps = [
@@ -25,6 +27,7 @@
     "//components/metrics",
     "//components/prefs",
     "//components/variations",
+    "//url",
   ]
 }
 
@@ -41,6 +44,23 @@
   ]
 }
 
+static_library("test_support") {
+  testonly = true
+  sources = [
+    "test_ukm_service.cc",
+    "test_ukm_service.h",
+  ]
+
+  public_deps = [
+    ":ukm",
+  ]
+  deps = [
+    "//base",
+    "//components/metrics:test_support",
+    "//components/prefs:test_support",
+  ]
+}
+
 source_set("unit_tests") {
   testonly = true
   sources = [
@@ -48,6 +68,7 @@
   ]
 
   deps = [
+    ":test_support",
     ":ukm",
     "//base",
     "//base/test:test_support",
@@ -56,6 +77,7 @@
     "//components/prefs:test_support",
     "//net:test_support",
     "//testing/gtest",
+    "//third_party/zlib:compression_utils",
     "//url",
   ]
 }
diff --git a/components/ukm/DEPS b/components/ukm/DEPS
index 02103f4..6a9008e 100644
--- a/components/ukm/DEPS
+++ b/components/ukm/DEPS
@@ -2,4 +2,5 @@
   "+components/metrics",
   "+components/prefs",
   "+components/variations",
+  "+third_party/zlib/google",
 ]
diff --git a/components/ukm/test_ukm_service.cc b/components/ukm/test_ukm_service.cc
new file mode 100644
index 0000000..5b72405
--- /dev/null
+++ b/components/ukm/test_ukm_service.cc
@@ -0,0 +1,30 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/ukm/test_ukm_service.h"
+
+namespace ukm {
+
+UkmServiceTestingHarness::UkmServiceTestingHarness() {
+  UkmService::RegisterPrefs(test_prefs_.registry());
+  test_prefs_.ClearPref(prefs::kUkmClientId);
+  test_prefs_.ClearPref(prefs::kUkmPersistedLogs);
+
+  test_ukm_service_ = base::MakeUnique<TestUkmService>(&test_prefs_);
+}
+
+UkmServiceTestingHarness::~UkmServiceTestingHarness() = default;
+
+TestUkmService::TestUkmService(PrefService* prefs_service)
+    : UkmService(prefs_service, &test_metrics_service_client_) {
+  DisableReporting();
+}
+
+TestUkmService::~TestUkmService() = default;
+
+const UkmSource* TestUkmService::GetSource(size_t source_num) const {
+  return sources_for_testing()[source_num].get();
+}
+
+}  // namespace ukm
diff --git a/components/ukm/test_ukm_service.h b/components/ukm/test_ukm_service.h
new file mode 100644
index 0000000..42b814ef
--- /dev/null
+++ b/components/ukm/test_ukm_service.h
@@ -0,0 +1,53 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_UKM_TEST_UKM_SERVICE_H_
+#define COMPONENTS_UKM_TEST_UKM_SERVICE_H_
+
+#include <stddef.h>
+#include <memory>
+
+#include "components/metrics/test_metrics_service_client.h"
+#include "components/prefs/testing_pref_service.h"
+#include "components/ukm/ukm_pref_names.h"
+#include "components/ukm/ukm_service.h"
+
+namespace ukm {
+
+// Wraps an UkmService with additional accessors used for testing.
+class TestUkmService : public UkmService {
+ public:
+  explicit TestUkmService(PrefService* pref_service);
+  ~TestUkmService() override;
+
+  size_t sources_count() const { return sources_for_testing().size(); }
+  const UkmSource* GetSource(size_t source_num) const;
+
+ private:
+  metrics::TestMetricsServiceClient test_metrics_service_client_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestUkmService);
+};
+
+// Convenience harness used for testing; creates a TestUkmService and
+// supplies it with a prefs service with a longer lifespan.
+class UkmServiceTestingHarness {
+ public:
+  UkmServiceTestingHarness();
+  virtual ~UkmServiceTestingHarness();
+
+  const TestUkmService& test_ukm_service() const {
+    return *test_ukm_service_.get();
+  }
+
+ private:
+  TestingPrefServiceSimple test_prefs_;
+  std::unique_ptr<TestUkmService> test_ukm_service_;
+
+  DISALLOW_COPY_AND_ASSIGN(UkmServiceTestingHarness);
+};
+
+}  // namespace ukm
+
+#endif  // COMPONENTS_UKM_TEST_UKM_SERVICE_H_
diff --git a/components/ukm/ukm_service.cc b/components/ukm/ukm_service.cc
index cbab848..2822b7ba 100644
--- a/components/ukm/ukm_service.cc
+++ b/components/ukm/ukm_service.cc
@@ -18,11 +18,13 @@
 #include "components/metrics/metrics_log_uploader.h"
 #include "components/metrics/metrics_service_client.h"
 #include "components/metrics/proto/ukm/report.pb.h"
+#include "components/metrics/proto/ukm/source.pb.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/ukm/metrics_reporting_scheduler.h"
 #include "components/ukm/persisted_logs_metrics_impl.h"
 #include "components/ukm/ukm_pref_names.h"
+#include "components/ukm/ukm_source.h"
 #include "components/variations/variations_associated_data.h"
 
 namespace ukm {
@@ -54,6 +56,10 @@
 // limit is exceeded.
 constexpr size_t kMaxLogRetransmitSize = 100 * 1024;
 
+// Maximum number of Sources we'll keep in memory before discarding any
+// new ones being added.
+const size_t kMaxSources = 100;
+
 std::string GetServerUrl() {
   std::string server_url =
       variations::GetVariationParamValueByFeature(kUkmFeature, "ServerUrl");
@@ -147,7 +153,7 @@
 void UkmService::Purge() {
   DVLOG(1) << "UkmService::Purge";
   persisted_logs_.Purge();
-  // TODO(oystein): Delete any stored sources.
+  sources_.clear();
 }
 
 // static
@@ -187,7 +193,14 @@
   Report report;
   report.set_client_id(client_id_);
   // TODO(holte): Populate system_profile.
-  // TODO(oystein): Populate sources.
+
+  for (const auto& source : sources_) {
+    Source* proto_source = report.add_sources();
+    source->PopulateProto(proto_source);
+  }
+  UMA_HISTOGRAM_COUNTS_1000("UKM.Sources.SerializedCount", sources_.size());
+  sources_.clear();
+
   std::string serialized_log;
   report.SerializeToString(&serialized_log);
   persisted_logs_.StoreLog(serialized_log);
@@ -244,4 +257,13 @@
   scheduler_->UploadFinished(server_is_healthy, !persisted_logs_.empty());
 }
 
+void UkmService::RecordSource(std::unique_ptr<UkmSource> source) {
+  if (sources_.size() >= kMaxSources) {
+    UMA_HISTOGRAM_BOOLEAN("UKM.Sources.MaxSourcesHit", true);
+    return;
+  }
+
+  sources_.push_back(std::move(source));
+}
+
 }  // namespace ukm
diff --git a/components/ukm/ukm_service.h b/components/ukm/ukm_service.h
index 9ffd417d..d154c7ce 100644
--- a/components/ukm/ukm_service.h
+++ b/components/ukm/ukm_service.h
@@ -26,6 +26,8 @@
 
 namespace ukm {
 
+class UkmSource;
+
 // This feature controls whether UkmService should be created.
 extern const base::Feature kUkmFeature;
 
@@ -48,6 +50,10 @@
   void EnableReporting();
   void DisableReporting();
 
+  // Adds a new source of UKM metrics, which will be stored
+  // until periodically serialized for upload, and then deleted.
+  void RecordSource(std::unique_ptr<UkmSource> source);
+
   // Record any collected data into logs, and write to disk.
   void Flush();
 
@@ -58,6 +64,11 @@
   // the provided PrefRegistry.
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
+ protected:
+  const std::vector<std::unique_ptr<UkmSource>>& sources_for_testing() const {
+    return sources_;
+  }
+
  private:
   // Start metrics client initialization.
   void StartInitTask();
@@ -104,6 +115,10 @@
   bool initialize_complete_;
   bool log_upload_in_progress_;
 
+  // Contains newly added sources of UKM metrics which periodically
+  // get serialized and cleared by BuildAndStoreLog().
+  std::vector<std::unique_ptr<UkmSource>> sources_;
+
   // Weak pointers factory used to post task on different threads. All weak
   // pointers managed by this factory have the same lifetime as UkmService.
   base::WeakPtrFactory<UkmService> self_ptr_factory_;
diff --git a/components/ukm/ukm_service_unittest.cc b/components/ukm/ukm_service_unittest.cc
index 2bdf94af..0b80e5c 100644
--- a/components/ukm/ukm_service_unittest.cc
+++ b/components/ukm/ukm_service_unittest.cc
@@ -6,10 +6,15 @@
 
 #include "base/test/test_simple_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "components/metrics/proto/ukm/report.pb.h"
+#include "components/metrics/proto/ukm/source.pb.h"
 #include "components/metrics/test_metrics_service_client.h"
 #include "components/prefs/testing_pref_service.h"
+#include "components/ukm/persisted_logs_metrics_impl.h"
 #include "components/ukm/ukm_pref_names.h"
+#include "components/ukm/ukm_source.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/zlib/google/compression_utils.h"
 
 namespace ukm {
 
@@ -31,6 +36,26 @@
     return list_value->GetSize();
   }
 
+  Report GetPersistedReport() {
+    metrics::PersistedLogs result_persisted_logs(
+        base::MakeUnique<ukm::PersistedLogsMetricsImpl>(), &prefs_,
+        prefs::kUkmPersistedLogs,
+        3,     // log count limit
+        1000,  // byte limit
+        0);
+
+    result_persisted_logs.DeserializeLogs();
+    result_persisted_logs.StageLog();
+
+    std::string uncompressed_log_data;
+    EXPECT_TRUE(compression::GzipUncompress(result_persisted_logs.staged_log(),
+                                            &uncompressed_log_data));
+
+    Report report;
+    EXPECT_TRUE(report.ParseFromString(uncompressed_log_data));
+    return report;
+  }
+
  protected:
   TestingPrefServiceSimple prefs_;
   metrics::TestMetricsServiceClient client_;
@@ -73,4 +98,34 @@
   EXPECT_EQ(GetPersistedLogCount(), 0);
 }
 
+TEST_F(UkmServiceTest, SourceSerialization) {
+  UkmService service(&prefs_, &client_);
+  EXPECT_EQ(GetPersistedLogCount(), 0);
+  service.Initialize();
+  task_runner_->RunUntilIdle();
+  service.EnableReporting();
+
+  std::unique_ptr<UkmSource> source = base::WrapUnique(new UkmSource());
+  source->set_committed_url(GURL("https://google.com"));
+  base::Time test_time;
+  source->set_navigation_start(test_time);
+  source->set_first_contentful_paint(base::TimeDelta::FromMilliseconds(300));
+
+  service.RecordSource(std::move(source));
+
+  service.Flush();
+  EXPECT_EQ(GetPersistedLogCount(), 1);
+
+  Report proto_report = GetPersistedReport();
+  EXPECT_EQ(1, proto_report.sources_size());
+  const Source& proto_source = proto_report.sources(0);
+
+  EXPECT_EQ(GURL("https://google.com").spec(), proto_source.url());
+  base::Time navigation_time =
+      base::Time::UnixEpoch() +
+      base::TimeDelta::FromMilliseconds(proto_source.navigation_time_msec());
+  EXPECT_EQ(test_time, navigation_time);
+  EXPECT_EQ(300, proto_source.first_contentful_paint_msec());
+}
+
 }  // namespace ukm
diff --git a/components/ukm/ukm_source.cc b/components/ukm/ukm_source.cc
new file mode 100644
index 0000000..ca0fc0a
--- /dev/null
+++ b/components/ukm/ukm_source.cc
@@ -0,0 +1,26 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/ukm/ukm_source.h"
+#include "components/metrics/proto/ukm/source.pb.h"
+
+namespace ukm {
+
+UkmSource::UkmSource() = default;
+
+UkmSource::~UkmSource() = default;
+
+void UkmSource::PopulateProto(Source* proto_source) {
+  proto_source->set_url(committed_url_.spec());
+
+  base::TimeDelta navigation_start_in_msec =
+      navigation_start_ - base::Time::UnixEpoch();
+  proto_source->set_navigation_time_msec(
+      navigation_start_in_msec.InMilliseconds());
+
+  proto_source->set_first_contentful_paint_msec(
+      first_contentful_paint_.InMilliseconds());
+}
+
+}  // namespace ukm
diff --git a/components/ukm/ukm_source.h b/components/ukm/ukm_source.h
new file mode 100644
index 0000000..32b2a8e
--- /dev/null
+++ b/components/ukm/ukm_source.h
@@ -0,0 +1,54 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_UKM_UKM_SOURCE_H_
+#define COMPONENTS_UKM_UKM_SOURCE_H_
+
+#include <stddef.h>
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "url/gurl.h"
+
+namespace ukm {
+
+class Source;
+
+// Contains UKM data for a single navigation entry.
+class UkmSource {
+ public:
+  UkmSource();
+  ~UkmSource();
+
+  const GURL& committed_url() const { return committed_url_; }
+  void set_committed_url(const GURL& committed_url) {
+    committed_url_ = committed_url;
+  }
+
+  base::Time navigation_start() const { return navigation_start_; }
+  void set_navigation_start(base::Time navigation_start) {
+    navigation_start_ = navigation_start;
+  }
+
+  base::TimeDelta first_contentful_paint() const {
+    return first_contentful_paint_;
+  }
+  void set_first_contentful_paint(base::TimeDelta first_contentful_paint) {
+    first_contentful_paint_ = first_contentful_paint;
+  }
+
+  // Serializes the members of the class into the supplied proto.
+  void PopulateProto(Source* proto_source);
+
+ private:
+  GURL committed_url_;
+  base::Time navigation_start_;
+  base::TimeDelta first_contentful_paint_;
+
+  DISALLOW_COPY_AND_ASSIGN(UkmSource);
+};
+
+}  // namespace ukm
+
+#endif  // COMPONENTS_UKM_UKM_SOURCE_H_
diff --git a/components/zoom/zoom_controller.cc b/components/zoom/zoom_controller.cc
index a28a01d..8d258a5 100644
--- a/components/zoom/zoom_controller.cc
+++ b/components/zoom/zoom_controller.cc
@@ -9,6 +9,7 @@
 #include "content/public/browser/host_zoom_map.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
@@ -284,14 +285,16 @@
   zoom_mode_ = ZOOM_MODE_DEFAULT;
 }
 
-void ZoomController::DidNavigateMainFrame(
-    const content::LoadCommittedDetails& details,
-    const content::FrameNavigateParams& params) {
-  if (details.entry && details.entry->GetPageType() == content::PAGE_TYPE_ERROR)
+void ZoomController::DidFinishNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted())
+    return;
+
+  if (navigation_handle->IsErrorPage())
     content::HostZoomMap::SendErrorPageZoomLevelRefresh(web_contents());
 
-  if (!details.is_in_page)
-    ResetZoomModeOnNavigationIfNeeded(params.url);
+  if (!navigation_handle->IsSamePage())
+    ResetZoomModeOnNavigationIfNeeded(navigation_handle->GetURL());
 
   // If the main frame's content has changed, the new page may have a different
   // zoom level from the old one.
diff --git a/components/zoom/zoom_controller.h b/components/zoom/zoom_controller.h
index 159b748..b0ecd4cf 100644
--- a/components/zoom/zoom_controller.h
+++ b/components/zoom/zoom_controller.h
@@ -149,9 +149,8 @@
   bool PageScaleFactorIsOne() const;
 
   // content::WebContentsObserver overrides:
-  void DidNavigateMainFrame(
-      const content::LoadCommittedDetails& details,
-      const content::FrameNavigateParams& params) override;
+  void DidFinishNavigation(
+      content::NavigationHandle* navigation_handle) override;
   void WebContentsDestroyed() override;
   void RenderFrameHostChanged(content::RenderFrameHost* old_host,
                               content::RenderFrameHost* new_host) override;
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 665a572..78b7f69 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -571,6 +571,8 @@
     "download/download_item_impl.h",
     "download/download_item_impl_delegate.cc",
     "download/download_item_impl_delegate.h",
+    "download/download_job.cc",
+    "download/download_job.h",
     "download/download_manager_impl.cc",
     "download/download_manager_impl.h",
     "download/download_net_log_parameters.cc",
diff --git a/content/browser/dom_storage/local_storage_context_mojo_unittest.cc b/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
index ae68d8e..afd7fac 100644
--- a/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
+++ b/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
@@ -662,7 +662,8 @@
     : public service_manager::test::ServiceTest {
  public:
   LocalStorageContextMojoTestWithService()
-      : ServiceTest("content_unittests", false) {}
+      : ServiceTest("content_unittests", false),
+        thread_bundle_(TestBrowserThreadBundle::REAL_FILE_THREAD) {}
   ~LocalStorageContextMojoTestWithService() override {}
 
  protected:
diff --git a/content/browser/download/download_job.cc b/content/browser/download/download_job.cc
new file mode 100644
index 0000000..c54428d1
--- /dev/null
+++ b/content/browser/download/download_job.cc
@@ -0,0 +1,43 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/download/download_job.h"
+
+namespace content {
+
+// Unknown download progress.
+const int kDownloadProgressUnknown = -1;
+
+// Unknown download speed.
+const int kDownloadSpeedUnknown = -1;
+
+DownloadJob::DownloadJob() : manager_(nullptr) {}
+
+DownloadJob::~DownloadJob() = default;
+
+void DownloadJob::OnAttached(DownloadJob::Manager* manager) {
+  DCHECK(!manager_) << "DownloadJob::Manager has already been attached.";
+  manager_ = manager;
+}
+
+void DownloadJob::OnBeforeDetach() {
+  manager_ = nullptr;
+}
+
+void DownloadJob::StartedSavingResponse() {
+  if (manager_)
+    manager_->OnSavingStarted(this);
+}
+
+void DownloadJob::Interrupt(DownloadInterruptReason reason) {
+  if (manager_)
+    manager_->OnDownloadInterrupted(this, reason);
+}
+
+void DownloadJob::Complete() {
+  if (manager_)
+    manager_->OnDownloadComplete(this);
+}
+
+}  // namespace content
diff --git a/content/browser/download/download_job.h b/content/browser/download/download_job.h
new file mode 100644
index 0000000..2192d410
--- /dev/null
+++ b/content/browser/download/download_job.h
@@ -0,0 +1,122 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_JOB_H_
+#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_JOB_H_
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/download_danger_type.h"
+#include "content/public/browser/download_interrupt_reasons.h"
+
+namespace content {
+class WebContents;
+
+// Unknown download progress.
+extern const int kDownloadProgressUnknown;
+
+// Unknown download speed.
+extern const int kDownloadSpeedUnknown;
+
+// DownloadJob contains internal download logic.
+// The owner of DownloadJob(e.g DownloadItemImpl) should implement
+// DownloadJob::Manager to be informed with important changes from
+// DownloadJob and modify its states accordingly.
+class CONTENT_EXPORT DownloadJob {
+ public:
+  // The interface used to interact with the owner of the download job.
+  class CONTENT_EXPORT Manager {
+   public:
+    // Called when |download_job| becomes actively download data.
+    virtual void OnSavingStarted(DownloadJob* download_job) = 0;
+
+    // Called when |download_job| is interrupted.
+    virtual void OnDownloadInterrupted(DownloadJob* download_job,
+                                       DownloadInterruptReason reason) = 0;
+
+    // Called when |download_job| is completed and inform the manager.
+    virtual void OnDownloadComplete(DownloadJob* download_job) = 0;
+
+    // Sets the download danger type.
+    virtual void SetDangerType(DownloadDangerType danger_type) = 0;
+  };
+
+  DownloadJob();
+  virtual ~DownloadJob();
+
+  DownloadJob::Manager* manager() { return manager_; }
+
+  // Called when DownloadJob is attached to DownloadJob::Manager.
+  // |manager| can be nullptr.
+  virtual void OnAttached(DownloadJob::Manager* manager);
+
+  // Called before DownloadJob is detached from its manager.
+  virtual void OnBeforeDetach();
+
+  // Download operations.
+  virtual void Cancel(bool user_cancel) = 0;
+  virtual void Pause() = 0;
+  virtual void Resume() = 0;
+
+  // Return if the download file can be opened.
+  // See |DownloadItem::CanOpenDownload|.
+  virtual bool CanOpen() const = 0;
+
+  // Return if the download job can be resumed.
+  virtual bool CanResume() const = 0;
+
+  // See |DownloadItem::CanShowInFolder|.
+  virtual bool CanShowInFolder() const = 0;
+
+  // Return if the download job is actively downloading.
+  virtual bool IsActive() const = 0;
+
+  // Return if the download job is paused.
+  virtual bool IsPaused() const = 0;
+
+  // Return a number between 0 and 100 to represent the percentage progress of
+  // the download. Return |kDownloadProgressUnknown| if the progress is
+  // indeterminate.
+  virtual int PercentComplete() const = 0;
+
+  // Return the estimated current download speed in bytes per second.
+  // Or return kDownloadSpeedUnknown if the download speed is not measurable.
+  virtual int64_t CurrentSpeed() const = 0;
+
+  // Set the estimated remaining time of the download to |remaining| and return
+  // true if time remaining is available, otherwise return false.
+  virtual bool TimeRemaining(base::TimeDelta* remaining) const = 0;
+
+  // Return the WebContents associated with the download. Usually used to
+  // associate a browser window for any UI that needs to be displayed to the
+  // user.
+  // Or return nullptr if the download is not associated with an active
+  // WebContents.
+  virtual WebContents* GetWebContents() const = 0;
+
+  // Print the debug string including internal states of the download job.
+  virtual std::string DebugString(bool verbose) const = 0;
+
+ protected:
+  // Mark the download as being active.
+  void StartedSavingResponse();
+
+  // Mark the download as interrupted.
+  void Interrupt(DownloadInterruptReason reason);
+
+  // Mark the download job as completed.
+  void Complete();
+
+  // Owner of this DownloadJob, Only valid between OnAttached() and
+  // OnBeforeDetach(), inclusive. Otherwise set to nullptr.
+  DownloadJob::Manager* manager_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DownloadJob);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_JOB_H_
diff --git a/content/browser/download/download_job_unittest.cc b/content/browser/download/download_job_unittest.cc
new file mode 100644
index 0000000..acdc5f1
--- /dev/null
+++ b/content/browser/download/download_job_unittest.cc
@@ -0,0 +1,52 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "base/memory/ptr_util.h"
+#include "content/browser/download/download_job.h"
+#include "content/browser/download/mock_download_job.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class MockDownloadJobManager : public DownloadJob::Manager {
+ public:
+  MockDownloadJobManager() = default;
+  ~MockDownloadJobManager() = default;
+
+  MOCK_METHOD1(OnSavingStarted, void(DownloadJob* download_job));
+  MOCK_METHOD1(SetDangerType, void(DownloadDangerType));
+  MOCK_METHOD2(OnDownloadInterrupted,
+               void(DownloadJob* download_job, DownloadInterruptReason reason));
+  MOCK_METHOD1(OnDownloadComplete, void(DownloadJob* download_job));
+};
+
+// Test for DownloadJob base class functionalities.
+class DownloadJobTest : public testing::Test {
+ public:
+  DownloadJobTest() = default;
+  ~DownloadJobTest() override = default;
+
+  void SetUp() override {
+    download_job_manager_ = base::MakeUnique<MockDownloadJobManager>();
+    EXPECT_TRUE(download_job_manager_.get());
+    download_job_ = base::MakeUnique<MockDownloadJob>();
+  }
+
+  std::unique_ptr<MockDownloadJobManager> download_job_manager_;
+  std::unique_ptr<MockDownloadJob> download_job_;
+};
+
+TEST_F(DownloadJobTest, AttachAndDetach) {
+  // Ensure the manager should be valid only between attach and detach call.
+  EXPECT_FALSE(download_job_->manager());
+  download_job_->OnAttached(download_job_manager_.get());
+  EXPECT_TRUE(download_job_->manager());
+  download_job_->OnBeforeDetach();
+  EXPECT_FALSE(download_job_->manager());
+}
+
+}  // namespace content
diff --git a/content/browser/download/mock_download_job.cc b/content/browser/download/mock_download_job.cc
new file mode 100644
index 0000000..9108e61
--- /dev/null
+++ b/content/browser/download/mock_download_job.cc
@@ -0,0 +1,13 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/download/mock_download_job.h"
+
+namespace content {
+
+MockDownloadJob::MockDownloadJob() = default;
+
+MockDownloadJob::~MockDownloadJob() = default;
+
+}  // namespace content
diff --git a/content/browser/download/mock_download_job.h b/content/browser/download/mock_download_job.h
new file mode 100644
index 0000000..39ea72e
--- /dev/null
+++ b/content/browser/download/mock_download_job.h
@@ -0,0 +1,40 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DOWNLOAD_MOCK_DOWNLOAD_JOB_H_
+#define CONTENT_BROWSER_DOWNLOAD_MOCK_DOWNLOAD_JOB_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "content/browser/download/download_job.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class MockDownloadJob : public DownloadJob {
+ public:
+  MockDownloadJob();
+  ~MockDownloadJob() override;
+
+  // DownloadJob implementation.
+  MOCK_METHOD1(Cancel, void(bool));
+  MOCK_METHOD0(Pause, void());
+  MOCK_METHOD0(Resume, void());
+  MOCK_CONST_METHOD0(CanOpen, bool());
+  MOCK_CONST_METHOD0(CanResume, bool());
+  MOCK_CONST_METHOD0(CanShowInFolder, bool());
+  MOCK_CONST_METHOD0(IsActive, bool());
+  MOCK_CONST_METHOD0(IsPaused, bool());
+  MOCK_CONST_METHOD0(PercentComplete, int());
+  MOCK_CONST_METHOD0(CurrentSpeed, int64_t());
+  MOCK_CONST_METHOD1(TimeRemaining, bool(base::TimeDelta* remaining));
+  MOCK_CONST_METHOD0(GetWebContents, WebContents*());
+  MOCK_CONST_METHOD1(DebugString, std::string(bool));
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_DOWNLOAD_MOCK_DOWNLOAD_JOB_H_
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
index c6bcc56a..e9952e5 100644
--- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -4702,25 +4702,11 @@
     message_loop_runner_->Quit();
   }
 
-  void DidFailProvisionalLoad(
-      RenderFrameHost* render_frame_host,
-      const GURL& validated_url,
-      int error_code,
-      const base::string16& error_description,
-      bool was_ignored_by_handler) override {
-    RenderFrameHostImpl* rfh =
-        static_cast<RenderFrameHostImpl*>(render_frame_host);
-    if (rfh->frame_tree_node()->frame_tree_node_id() != frame_tree_node_id_)
-      return;
-
-    message_loop_runner_->Quit();
-  }
-
   void DidFinishNavigation(NavigationHandle* handle) override {
-    if (handle->GetFrameTreeNodeId() != frame_tree_node_id_)
+    if (handle->HasCommitted() ||
+        handle->GetFrameTreeNodeId() != frame_tree_node_id_) {
       return;
-    if (handle->HasCommitted())
-      return;
+    }
 
     message_loop_runner_->Quit();
   }
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 752f7234..fd3a626 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -443,11 +443,11 @@
   params.mutator_host = animation_host_.get();
   host_ = cc::LayerTreeHost::CreateSingleThreaded(this, &params);
   DCHECK(!host_->IsVisible());
-  host_->GetLayerTree()->SetRootLayer(root_window_->GetLayer());
+  host_->SetRootLayer(root_window_->GetLayer());
   host_->SetFrameSinkId(frame_sink_id_);
-  host_->GetLayerTree()->SetViewportSize(size_);
+  host_->SetViewportSize(size_);
   SetHasTransparentBackground(false);
-  host_->GetLayerTree()->SetDeviceScaleFactor(1);
+  host_->SetDeviceScaleFactor(1);
 
   if (needs_animate_)
     host_->SetNeedsAnimate();
@@ -481,7 +481,7 @@
 
   size_ = size;
   if (host_)
-    host_->GetLayerTree()->SetViewportSize(size);
+    host_->SetViewportSize(size);
   if (display_)
     display_->Resize(size);
   root_window_->GetLayer()->SetBounds(size);
@@ -490,7 +490,7 @@
 void CompositorImpl::SetHasTransparentBackground(bool transparent) {
   has_transparent_background_ = transparent;
   if (host_) {
-    host_->GetLayerTree()->set_has_transparent_background(transparent);
+    host_->set_has_transparent_background(transparent);
 
     // Give a delay in setting the background color to avoid the color for
     // the normal mode (white) affecting the UI transition.
@@ -504,7 +504,7 @@
 }
 
 void CompositorImpl::SetBackgroundColor(int color) {
-  host_->GetLayerTree()->set_background_color(color);
+  host_->set_background_color(color);
 }
 
 void CompositorImpl::SetNeedsComposite() {
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 9491607e..024d90d 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1596,6 +1596,15 @@
 }
 
 void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) {
+#if defined(OS_WIN)
+  if (event->type() == ui::ET_MOUSE_MOVED) {
+    if (event->location() == last_mouse_move_location_) {
+      event->SetHandled();
+      return;
+    }
+    last_mouse_move_location_ = event->location();
+  }
+#endif
   event_handler_->OnMouseEvent(event);
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index 7e784fb..377aa1c5 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -558,6 +558,8 @@
   bool virtual_keyboard_requested_;
 
   std::unique_ptr<ui::OnScreenKeyboardObserver> keyboard_observer_;
+
+  gfx::Point last_mouse_move_location_;
 #endif
 
   bool has_snapped_to_boundary_;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index fb5cfd4..e8e354dc 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -4177,8 +4177,8 @@
   EXPECT_EQ("1 0", delegate.GetMouseButtonCountsAndReset());
 
   // Simulate mouse events, ensure they are forwarded to delegate.
-  mouse_event = ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(),
-                               ui::EventTimeForNow(), 0, 0);
+  mouse_event = ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(1, 1),
+                               gfx::Point(), ui::EventTimeForNow(), 0, 0);
   view_->OnMouseEvent(&mouse_event);
   EXPECT_EQ("0 1 0", delegate.GetMouseMotionCountsAndReset());
 
diff --git a/content/browser/webui/url_data_manager_backend.cc b/content/browser/webui/url_data_manager_backend.cc
index 47deeb8..247fc00 100644
--- a/content/browser/webui/url_data_manager_backend.cc
+++ b/content/browser/webui/url_data_manager_backend.cc
@@ -510,24 +510,6 @@
 
 namespace {
 
-// Gets mime type for data that is available from |source| by |path|.
-// After that, notifies |job| that mime type is available. This method
-// should be called on the UI thread, but notification is performed on
-// the IO thread.
-void GetMimeTypeOnUI(URLDataSourceImpl* source,
-                     const std::string& path,
-                     const base::WeakPtr<URLRequestChromeJob>& job) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  std::string mime_type = source->source()->GetMimeType(path);
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::Bind(&URLRequestChromeJob::MimeTypeAvailable, job, mime_type));
-}
-
-}  // namespace
-
-namespace {
-
 bool IsValidNetworkErrorCode(int error_code) {
   std::unique_ptr<base::DictionaryValue> error_codes = net::GetNetConstants();
   const base::DictionaryValue* net_error_codes_dict = nullptr;
@@ -735,7 +717,8 @@
 
   // TODO(dschuyler): improve filtering of which resource to run template
   // replacements upon.
-  if (source->source()->GetMimeType(path) == "text/html")
+  std::string mime_type = source->source()->GetMimeType(path);
+  if (mime_type == "text/html")
     job->SetReplacements(source->GetReplacements());
 
   std::string origin = GetOriginHeaderValue(request);
@@ -747,23 +730,19 @@
     job->set_access_control_allow_origin(header);
   }
 
+  // Also notifies that the headers are complete.
+  job->MimeTypeAvailable(mime_type);
+
   // Look up additional request info to pass down.
-  int child_id = -1;
   ResourceRequestInfo::WebContentsGetter wc_getter;
   const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
-  if (info) {
-    child_id = info->GetChildID();
+  if (info)
     wc_getter = info->GetWebContentsGetterForRequest();
-  }
 
   // Forward along the request to the data source.
   scoped_refptr<base::SingleThreadTaskRunner> target_runner =
       source->source()->TaskRunnerForRequestPath(path);
   if (!target_runner) {
-    job->MimeTypeAvailable(source->source()->GetMimeType(path));
-    // Eliminate potentially dangling pointer to avoid future use.
-    job = nullptr;
-
     // The DataSource is agnostic to which thread StartDataRequest is called
     // on for this path.  Call directly into it from this thread, the IO
     // thread.
@@ -771,20 +750,12 @@
         path, wc_getter,
         base::Bind(&URLDataSourceImpl::SendResponse, source, request_id));
   } else {
-    // URLRequestChromeJob should receive mime type before data. This
-    // is guaranteed because request for mime type is placed in the
-    // message loop before request for data. And correspondingly their
-    // replies are put on the IO thread in the same order.
-    target_runner->PostTask(
-        FROM_HERE, base::Bind(&GetMimeTypeOnUI, base::RetainedRef(source), path,
-                              job->AsWeakPtr()));
-
     // The DataSource wants StartDataRequest to be called on a specific thread,
     // usually the UI thread, for this path.
     target_runner->PostTask(
-        FROM_HERE, base::Bind(&URLDataManagerBackend::CallStartRequest,
-                              base::RetainedRef(source), path, child_id,
-                              wc_getter, request_id));
+        FROM_HERE,
+        base::Bind(&URLDataManagerBackend::CallStartRequest,
+                   base::RetainedRef(source), path, wc_getter, request_id));
   }
   return true;
 }
@@ -810,19 +781,8 @@
 void URLDataManagerBackend::CallStartRequest(
     scoped_refptr<URLDataSourceImpl> source,
     const std::string& path,
-    int child_id,
     const ResourceRequestInfo::WebContentsGetter& wc_getter,
     int request_id) {
-  if (BrowserThread::CurrentlyOn(BrowserThread::UI) && child_id != -1 &&
-      !RenderProcessHost::FromID(child_id)) {
-    // Make the request fail if its initiating renderer is no longer valid.
-    // This can happen when the IO thread posts this task just before the
-    // renderer shuts down.
-    // Note we check the process id instead of wc_getter because requests from
-    // workers wouldn't have a WebContents.
-    source->SendResponse(request_id, nullptr);
-    return;
-  }
   source->source()->StartDataRequest(
       path,
       wc_getter,
diff --git a/content/browser/webui/url_data_manager_backend.h b/content/browser/webui/url_data_manager_backend.h
index 053b9b5..20002c7 100644
--- a/content/browser/webui/url_data_manager_backend.h
+++ b/content/browser/webui/url_data_manager_backend.h
@@ -80,7 +80,6 @@
   static void CallStartRequest(
       scoped_refptr<URLDataSourceImpl> source,
       const std::string& path,
-      int child_id,
       const ResourceRequestInfo::WebContentsGetter& wc_getter,
       int request_id);
 
diff --git a/content/public/browser/url_data_source.h b/content/public/browser/url_data_source.h
index fc2814a..ef3f538 100644
--- a/content/public/browser/url_data_source.h
+++ b/content/public/browser/url_data_source.h
@@ -50,6 +50,9 @@
   typedef base::Callback<void(scoped_refptr<base::RefCountedMemory>)>
       GotDataCallback;
 
+  // Must be called on the task runner specified by TaskRunnerForRequestPath,
+  // or the IO thread if TaskRunnerForRequestPath returns nullptr.
+  //
   // Called by URLDataSource to request data at |path|. The string parameter is
   // the path of the request. The child class should run |callback| when the
   // data is available or if the request could not be satisfied. This can be
@@ -62,12 +65,12 @@
       const ResourceRequestInfo::WebContentsGetter& wc_getter,
       const GotDataCallback& callback) = 0;
 
+  // The following methods are all called on the IO thread.
+
   // Return the mimetype that should be sent with this response, or empty
   // string to specify no mime type.
   virtual std::string GetMimeType(const std::string& path) const = 0;
 
-  // The following methods are all called on the IO thread.
-
   // Returns the TaskRunner on which the delegate wishes to have
   // StartDataRequest called to handle the request for |path|. The default
   // implementation returns BrowserThread::UI. If the delegate does not care
diff --git a/content/renderer/gpu/actions_parser.cc b/content/renderer/gpu/actions_parser.cc
index 438c584d..650fd439 100644
--- a/content/renderer/gpu/actions_parser.cc
+++ b/content/renderer/gpu/actions_parser.cc
@@ -33,6 +33,8 @@
     return SyntheticGestureParams::TOUCH_INPUT;
   else if (source_type == "mouse")
     return SyntheticGestureParams::MOUSE_INPUT;
+  else if (source_type == "pen")
+    return SyntheticGestureParams::PEN_INPUT;
   else
     return SyntheticGestureParams::DEFAULT_INPUT;
 }
@@ -60,7 +62,8 @@
 
 bool ActionsParser::ParsePointerActionSequence() {
   const base::ListValue* pointer_list;
-  if (!pointer_actions_value_->GetAsList(&pointer_list)) {
+  if (!pointer_actions_value_ ||
+      !pointer_actions_value_->GetAsList(&pointer_list)) {
     error_message_ =
         base::StringPrintf("pointer_list is missing or not a list");
     return false;
@@ -106,7 +109,7 @@
         base::StringPrintf("source type is missing or not a string");
     return false;
   } else if (source_type != "touch" && source_type != "mouse" &&
-             source_type != "pointer") {
+             source_type != "pen") {
     error_message_ =
         base::StringPrintf("source type is an unsupported input source");
     return false;
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.cc b/content/renderer/gpu/gpu_benchmarking_extension.cc
index e9034af..c2b6563 100644
--- a/content/renderer/gpu/gpu_benchmarking_extension.cc
+++ b/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -17,6 +17,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "cc/layers/layer.h"
+#include "cc/trees/layer_tree_host.h"
 #include "content/common/child_process_messages.h"
 #include "content/common/input/synthetic_gesture_params.h"
 #include "content/common/input/synthetic_pinch_gesture_params.h"
@@ -136,7 +137,7 @@
   // Each layer in the tree is serialized into a separate skp file
   // in the given directory.
   void Serialize(const cc::Layer* root_layer) {
-    for (auto* layer : *root_layer->GetLayerTree()) {
+    for (auto* layer : *root_layer->layer_tree_host()) {
       sk_sp<SkPicture> picture = layer->GetPicture();
       if (!picture)
         continue;
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index 48cabd27..fef0b8f 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -587,7 +587,7 @@
 }
 
 void RenderWidgetCompositor::SetNeedsDisplayOnAllLayers() {
-  layer_tree_host_->GetLayerTree()->SetNeedsDisplayOnAllLayers();
+  layer_tree_host_->SetNeedsDisplayOnAllLayers();
 }
 
 void RenderWidgetCompositor::SetRasterizeOnlyVisibleContent() {
@@ -634,7 +634,7 @@
 }
 
 const cc::Layer* RenderWidgetCompositor::GetRootLayer() const {
-  return layer_tree_host_->GetLayerTree()->root_layer();
+  return layer_tree_host_->root_layer();
 }
 
 int RenderWidgetCompositor::ScheduleMicroBenchmark(
@@ -652,12 +652,12 @@
 }
 
 void RenderWidgetCompositor::setRootLayer(const blink::WebLayer& layer) {
-  layer_tree_host_->GetLayerTree()->SetRootLayer(
+  layer_tree_host_->SetRootLayer(
       static_cast<const cc_blink::WebLayerImpl*>(&layer)->layer());
 }
 
 void RenderWidgetCompositor::clearRootLayer() {
-  layer_tree_host_->GetLayerTree()->SetRootLayer(scoped_refptr<cc::Layer>());
+  layer_tree_host_->SetRootLayer(scoped_refptr<cc::Layer>());
 }
 
 cc::AnimationHost* RenderWidgetCompositor::compositorAnimationHost() {
@@ -666,11 +666,11 @@
 
 void RenderWidgetCompositor::setViewportSize(
     const WebSize& device_viewport_size) {
-  layer_tree_host_->GetLayerTree()->SetViewportSize(device_viewport_size);
+  layer_tree_host_->SetViewportSize(device_viewport_size);
 }
 
 WebSize RenderWidgetCompositor::getViewportSize() const {
-  return layer_tree_host_->GetLayerTree()->device_viewport_size();
+  return layer_tree_host_->device_viewport_size();
 }
 
 WebFloatPoint RenderWidgetCompositor::adjustEventPointForPinchZoom(
@@ -679,15 +679,15 @@
 }
 
 void RenderWidgetCompositor::setDeviceScaleFactor(float device_scale) {
-  layer_tree_host_->GetLayerTree()->SetDeviceScaleFactor(device_scale);
+  layer_tree_host_->SetDeviceScaleFactor(device_scale);
 }
 
 void RenderWidgetCompositor::setBackgroundColor(blink::WebColor color) {
-  layer_tree_host_->GetLayerTree()->set_background_color(color);
+  layer_tree_host_->set_background_color(color);
 }
 
 void RenderWidgetCompositor::setHasTransparentBackground(bool transparent) {
-  layer_tree_host_->GetLayerTree()->set_has_transparent_background(transparent);
+  layer_tree_host_->set_has_transparent_background(transparent);
 }
 
 void RenderWidgetCompositor::setVisible(bool visible) {
@@ -699,8 +699,8 @@
 
 void RenderWidgetCompositor::setPageScaleFactorAndLimits(
     float page_scale_factor, float minimum, float maximum) {
-  layer_tree_host_->GetLayerTree()->SetPageScaleFactorAndLimits(
-      page_scale_factor, minimum, maximum);
+  layer_tree_host_->SetPageScaleFactorAndLimits(page_scale_factor, minimum,
+                                                maximum);
 }
 
 void RenderWidgetCompositor::startPageScaleAnimation(
@@ -710,13 +710,13 @@
     double duration_sec) {
   base::TimeDelta duration = base::TimeDelta::FromMicroseconds(
       duration_sec * base::Time::kMicrosecondsPerSecond);
-  layer_tree_host_->GetLayerTree()->StartPageScaleAnimation(
+  layer_tree_host_->StartPageScaleAnimation(
       gfx::Vector2d(destination.x, destination.y), use_anchor, new_page_scale,
       duration);
 }
 
 bool RenderWidgetCompositor::hasPendingPageScaleAnimation() const {
-  return layer_tree_host_->GetLayerTree()->HasPendingPageScaleAnimation();
+  return layer_tree_host_->HasPendingPageScaleAnimation();
 }
 
 void RenderWidgetCompositor::heuristicsForGpuRasterizationUpdated(
@@ -741,7 +741,7 @@
     const blink::WebLayer* pageScaleLayer,
     const blink::WebLayer* innerViewportScrollLayer,
     const blink::WebLayer* outerViewportScrollLayer) {
-  layer_tree_host_->GetLayerTree()->RegisterViewportLayers(
+  layer_tree_host_->RegisterViewportLayers(
       // TODO(bokan): This check can probably be removed now, but it looks
       // like overscroll elasticity may still be NULL until VisualViewport
       // registers its layers.
@@ -767,20 +767,19 @@
 }
 
 void RenderWidgetCompositor::clearViewportLayers() {
-  layer_tree_host_->GetLayerTree()->RegisterViewportLayers(
+  layer_tree_host_->RegisterViewportLayers(
       scoped_refptr<cc::Layer>(), scoped_refptr<cc::Layer>(),
       scoped_refptr<cc::Layer>(), scoped_refptr<cc::Layer>());
 }
 
 void RenderWidgetCompositor::registerSelection(
     const blink::WebSelection& selection) {
-  layer_tree_host_->GetLayerTree()->RegisterSelection(
-      ConvertWebSelection(selection));
+  layer_tree_host_->RegisterSelection(ConvertWebSelection(selection));
 }
 
 void RenderWidgetCompositor::clearSelection() {
   cc::LayerSelection empty_selection;
-  layer_tree_host_->GetLayerTree()->RegisterSelection(empty_selection);
+  layer_tree_host_->RegisterSelection(empty_selection);
 }
 
 void RenderWidgetCompositor::setMutatorClient(
@@ -822,7 +821,7 @@
 void RenderWidgetCompositor::setEventListenerProperties(
     blink::WebEventListenerClass eventClass,
     blink::WebEventListenerProperties properties) {
-  layer_tree_host_->GetLayerTree()->SetEventListenerProperties(
+  layer_tree_host_->SetEventListenerProperties(
       static_cast<cc::EventListenerClass>(eventClass),
       static_cast<cc::EventListenerProperties>(properties));
 }
@@ -851,7 +850,7 @@
       touch_end_cancel_properties ==
           WebEventListenerProperties::BlockingAndPassive;
 
-  cc::Layer* root_layer = layer_tree_host_->GetLayerTree()->root_layer();
+  cc::Layer* root_layer = layer_tree_host_->root_layer();
   cc::Region touch_handler_region;
   if (has_touch_handlers)
     touch_handler_region = gfx::Rect(gfx::Point(), root_layer->bounds());
@@ -862,16 +861,16 @@
 RenderWidgetCompositor::eventListenerProperties(
     blink::WebEventListenerClass event_class) const {
   return static_cast<blink::WebEventListenerProperties>(
-      layer_tree_host_->GetLayerTree()->event_listener_properties(
+      layer_tree_host_->event_listener_properties(
           static_cast<cc::EventListenerClass>(event_class)));
 }
 
 void RenderWidgetCompositor::setHaveScrollEventHandlers(bool has_handlers) {
-  layer_tree_host_->GetLayerTree()->SetHaveScrollEventHandlers(has_handlers);
+  layer_tree_host_->SetHaveScrollEventHandlers(has_handlers);
 }
 
 bool RenderWidgetCompositor::haveScrollEventHandlers() const {
-  return layer_tree_host_->GetLayerTree()->have_scroll_event_handlers();
+  return layer_tree_host_->have_scroll_event_handlers();
 }
 
 void CompositeAndReadbackAsyncCallback(
@@ -1000,15 +999,15 @@
 
 void RenderWidgetCompositor::setBrowserControlsHeight(float height,
                                                       bool shrink) {
-  layer_tree_host_->GetLayerTree()->SetBrowserControlsHeight(height, shrink);
+  layer_tree_host_->SetBrowserControlsHeight(height, shrink);
 }
 
 void RenderWidgetCompositor::setBrowserControlsShownRatio(float ratio) {
-  layer_tree_host_->GetLayerTree()->SetBrowserControlsShownRatio(ratio);
+  layer_tree_host_->SetBrowserControlsShownRatio(ratio);
 }
 
 void RenderWidgetCompositor::setBottomControlsHeight(float height) {
-  layer_tree_host_->GetLayerTree()->SetBottomControlsHeight(height);
+  layer_tree_host_->SetBottomControlsHeight(height);
 }
 
 void RenderWidgetCompositor::WillBeginMainFrame() {
@@ -1121,12 +1120,12 @@
 
 void RenderWidgetCompositor::SetPaintedDeviceScaleFactor(
     float device_scale) {
-  layer_tree_host_->GetLayerTree()->SetPaintedDeviceScaleFactor(device_scale);
+  layer_tree_host_->SetPaintedDeviceScaleFactor(device_scale);
 }
 
 void RenderWidgetCompositor::SetDeviceColorSpace(
     const gfx::ColorSpace& color_space) {
-  layer_tree_host_->GetLayerTree()->SetDeviceColorSpace(color_space);
+  layer_tree_host_->SetDeviceColorSpace(color_space);
 }
 
 void RenderWidgetCompositor::SetIsForOopif(bool is_for_oopif) {
diff --git a/content/renderer/pepper/pepper_compositor_host.cc b/content/renderer/pepper/pepper_compositor_host.cc
index 8df4f6ce..c0038dc 100644
--- a/content/renderer/pepper/pepper_compositor_host.cc
+++ b/content/renderer/pepper/pepper_compositor_host.cc
@@ -410,8 +410,8 @@
   // We need to force a commit for each CommitLayers() call, even if no layers
   // changed since the last call to CommitLayers(). This is so
   // WiewInitiatedPaint() will always be called.
-  if (layer_->GetLayerTree())
-    layer_->GetLayerTree()->SetNeedsCommit();
+  if (layer_->layer_tree_host())
+    layer_->layer_tree_host()->SetNeedsCommit();
 
   // If the host is not bound to the instance, return PP_OK immediately.
   if (!bound_instance_)
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index e90b015..13f946f 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -20,7 +20,6 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "build/build_config.h"
-#include "cc/trees/layer_tree.h"
 #include "cc/trees/layer_tree_host.h"
 #include "content/child/request_extra_data.h"
 #include "content/child/service_worker/service_worker_network_provider.h"
@@ -556,7 +555,6 @@
     EXPECT_EQ(compositor_dsf, view()
                                   ->compositor()
                                   ->layer_tree_host()
-                                  ->GetLayerTree()
                                   ->device_scale_factor());
   }
 };
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index fc848215..a797669 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -2332,12 +2332,6 @@
     BrowserPluginManager::Get()->UpdateFocusState();
 }
 
-void RenderViewImpl::RenderWidgetDidSetColorProfile(
-    const gfx::ICCProfile& profile) {
-  if (webview())
-    webview()->setDeviceColorProfile(profile);
-}
-
 void RenderViewImpl::DidCompletePageScaleAnimation() {
   GetWidget()->FocusChangeComplete();
 }
@@ -2610,6 +2604,24 @@
   OnResize(params);
 }
 
+void RenderViewImpl::SetDeviceColorProfileForTesting(
+    const gfx::ICCProfile& icc_profile) {
+  if (webview())
+    webview()->setDeviceColorProfile(icc_profile);
+
+  ResizeParams params;
+  params.screen_info = screen_info_;
+  params.screen_info.icc_profile = icc_profile;
+  params.new_size = size();
+  params.visible_viewport_size = visible_viewport_size_;
+  params.physical_backing_size = physical_backing_size_;
+  params.browser_controls_shrink_blink_size = false;
+  params.top_controls_height = 0.f;
+  params.is_fullscreen_granted = is_fullscreen_granted();
+  params.display_mode = display_mode_;
+  OnResize(params);
+}
+
 void RenderViewImpl::ForceResizeForTesting(const gfx::Size& new_size) {
   gfx::Rect new_window_rect(rootWindowRect().x,
                             rootWindowRect().y,
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index 57d38b4..18e359d 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -92,6 +92,10 @@
 #endif
 }  // namespace blink
 
+namespace gfx {
+class ICCProfile;
+}
+
 namespace content {
 
 class RendererDateTimePicker;
@@ -235,6 +239,9 @@
   // Change the device scale factor and force the compositor to resize.
   void SetDeviceScaleFactorForTesting(float factor);
 
+  // Change the device ICC color profile while running a layout test.
+  void SetDeviceColorProfileForTesting(const gfx::ICCProfile& icc_profile);
+
   // Used to force the size of a window when running layout tests.
   void ForceResizeForTesting(const gfx::Size& new_size);
 
@@ -484,8 +491,6 @@
 
   // RenderWidgetOwnerDelegate implementation ----------------------------------
 
-  void RenderWidgetDidSetColorProfile(
-      const gfx::ICCProfile& color_profile) override;
   void RenderWidgetFocusChangeComplete() override;
   bool DoesRenderWidgetHaveTouchEventHandlersAt(
       const gfx::Point& point) const override;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index d251ad7..2ef8c177 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -38,10 +38,12 @@
 #include "content/common/swapped_out_messages.h"
 #include "content/common/text_input_state.h"
 #include "content/common/view_messages.h"
+#include "content/public/common/content_client.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/context_menu_params.h"
 #include "content/public/common/drop_data.h"
+#include "content/public/renderer/content_renderer_client.h"
 #include "content/renderer/cursor_utils.h"
 #include "content/renderer/devtools/render_widget_screen_metrics_emulator.h"
 #include "content/renderer/drop_data_builder.h"
@@ -1983,12 +1985,6 @@
   UpdateCompositionInfo(false /* not an immediate request */);
 }
 
-void RenderWidget::SetDeviceColorProfileForTesting(
-    const gfx::ICCProfile& color_profile) {
-  if (owner_delegate_)
-    owner_delegate_->RenderWidgetDidSetColorProfile(color_profile);
-}
-
 void RenderWidget::DidAutoResize(const gfx::Size& new_size) {
   WebRect new_size_in_window(0, 0, new_size.width(), new_size.height());
   convertViewportToWindow(&new_size_in_window);
@@ -2073,6 +2069,7 @@
 blink::WebScreenInfo RenderWidget::screenInfo() {
   blink::WebScreenInfo web_screen_info;
   web_screen_info.deviceScaleFactor = screen_info_.device_scale_factor;
+  web_screen_info.iccProfile = screen_info_.icc_profile;
   web_screen_info.depth = screen_info_.depth;
   web_screen_info.depthPerComponent = screen_info_.depth_per_component;
   web_screen_info.isMonochrome = screen_info_.is_monochrome;
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index 5abe3ce2..f1b6289 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -89,7 +89,6 @@
 }
 
 namespace gfx {
-class ICCProfile;
 class Range;
 }
 
@@ -388,9 +387,6 @@
   // the browser even if the composition info is not changed.
   void UpdateCompositionInfo(bool immediate_request);
 
-  // Change the device ICC color profile while running a layout test.
-  void SetDeviceColorProfileForTesting(const gfx::ICCProfile& color_profile);
-
   // Called when the Widget has changed size as a result of an auto-resize.
   void DidAutoResize(const gfx::Size& new_size);
 
diff --git a/content/renderer/render_widget_owner_delegate.h b/content/renderer/render_widget_owner_delegate.h
index 3e08ebb..81bfb52 100644
--- a/content/renderer/render_widget_owner_delegate.h
+++ b/content/renderer/render_widget_owner_delegate.h
@@ -12,7 +12,6 @@
 }
 
 namespace gfx {
-class ICCProfile;
 class Point;
 }
 
@@ -26,10 +25,6 @@
 //  are disentangled; see http://crbug.com/583347 and http://crbug.com/478281.
 class CONTENT_EXPORT RenderWidgetOwnerDelegate {
  public:
-  // The RenderWidget set a color profile.
-  virtual void RenderWidgetDidSetColorProfile(
-      const gfx::ICCProfile& color_profile) = 0;
-
   // As in RenderWidgetInputHandlerDelegate.
   virtual void RenderWidgetFocusChangeComplete() = 0;
   virtual bool DoesRenderWidgetHaveTouchEventHandlersAt(
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 1fcd658..d34f3fc 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -31,6 +31,8 @@
   sources = [
     "../browser/download/mock_download_file.cc",
     "../browser/download/mock_download_file.h",
+    "../browser/download/mock_download_job.cc",
+    "../browser/download/mock_download_job.h",
     "../browser/media/session/mock_media_session_observer.cc",
     "../browser/media/session/mock_media_session_observer.h",
     "../browser/service_worker/embedded_worker_test_helper.cc",
@@ -1034,6 +1036,7 @@
     "../browser/download/base_file_win_unittest.cc",
     "../browser/download/download_file_unittest.cc",
     "../browser/download/download_item_impl_unittest.cc",
+    "../browser/download/download_job_unittest.cc",
     "../browser/download/download_manager_impl_unittest.cc",
     "../browser/download/rate_estimator_unittest.cc",
     "../browser/download/save_package_unittest.cc",
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc
index 8f7c7722..e21ab4e 100644
--- a/content/test/layouttest_support.cc
+++ b/content/test/layouttest_support.cc
@@ -509,9 +509,8 @@
 
 void SetDeviceColorProfile(
     RenderView* render_view, const gfx::ICCProfile& icc_profile) {
-  static_cast<RenderViewImpl*>(render_view)
-      ->GetWidget()
-      ->SetDeviceColorProfileForTesting(icc_profile);
+  static_cast<RenderViewImpl*>(render_view)->
+      SetDeviceColorProfileForTesting(icc_profile);
 }
 
 void SetTestBluetoothScanDuration() {
diff --git a/ios/web/shell/test/context_menu_egtest.mm b/ios/web/shell/test/context_menu_egtest.mm
index 5484c5a..bb8fbfbf 100644
--- a/ios/web/shell/test/context_menu_egtest.mm
+++ b/ios/web/shell/test/context_menu_egtest.mm
@@ -33,14 +33,8 @@
 
 @implementation ContextMenuTestCase
 
-// TODO(crbug.com/675399): Re-enable this test on device.
-#if TARGET_IPHONE_SIMULATOR
-#define MAYBE_testContextMenu testContextMenu
-#else
-#define MAYBE_testContextMenu FLAKY_testContextMenu
-#endif
 // Tests context menu appears on a regular link.
-- (void)MAYBE_testContextMenu {
+- (void)testContextMenu {
   // Create map of canned responses and set up the test HTML server.
   std::map<GURL, std::string> responses;
   GURL initialURL = web::test::HttpServer::MakeUrl("http://contextMenuOpen");
@@ -75,16 +69,8 @@
   [[EarlGrey selectElementWithMatcher:copyItem] assertWithMatcher:grey_nil()];
 }
 
-// TODO(crbug.com/675399): Re-enable this test on device.
-#if TARGET_IPHONE_SIMULATOR
-#define MAYBE_testContextMenuWebkitTouchCalloutNone \
-  testContextMenuWebkitTouchCalloutNone
-#else
-#define MAYBE_testContextMenuWebkitTouchCalloutNone \
-  FLAKY_testContextMenuWebkitTouchCalloutNone
-#endif
 // Tests context menu on element that has WebkitTouchCallout set to none.
-- (void)MAYBE_testContextMenuWebkitTouchCalloutNone {
+- (void)testContextMenuWebkitTouchCalloutNone {
   // Create map of canned responses and set up the test HTML server.
   std::map<GURL, std::string> responses;
   GURL initialURL =
@@ -112,17 +98,9 @@
   [[EarlGrey selectElementWithMatcher:copyItem] assertWithMatcher:grey_nil()];
 }
 
-// TODO(crbug.com/675399): Re-enable this test on device.
-#if TARGET_IPHONE_SIMULATOR
-#define MAYBE_testContextMenuWebkitTouchCalloutNoneFromAncestor \
-  testContextMenuWebkitTouchCalloutNoneFromAncestor
-#else
-#define MAYBE_testContextMenuWebkitTouchCalloutNoneFromAncestor \
-  FLAKY_testContextMenuWebkitTouchCalloutNoneFromAncestor
-#endif
 // Tests context menu on element that has WebkitTouchCallout set to none from an
 // ancestor.
-- (void)MAYBE_testContextMenuWebkitTouchCalloutNoneFromAncestor {
+- (void)testContextMenuWebkitTouchCalloutNoneFromAncestor {
   // Create map of canned responses and set up the test HTML server.
   std::map<GURL, std::string> responses;
   GURL initialURL =
@@ -151,17 +129,9 @@
   [[EarlGrey selectElementWithMatcher:copyItem] assertWithMatcher:grey_nil()];
 }
 
-// TODO(crbug.com/675399): Re-enable this test on device.
-#if TARGET_IPHONE_SIMULATOR
-#define MAYBE_testContextMenuWebkitTouchCalloutOverride \
-  testContextMenuWebkitTouchCalloutOverride
-#else
-#define MAYBE_testContextMenuWebkitTouchCalloutOverride \
-  FLAKY_testContextMenuWebkitTouchCalloutOverride
-#endif
 // Tests context menu on element that has WebkitTouchCallout set to none from an
 // ancestor and overridden.
-- (void)MAYBE_testContextMenuWebkitTouchCalloutOverride {
+- (void)testContextMenuWebkitTouchCalloutOverride {
   // Create map of canned responses and set up the test HTML server.
   std::map<GURL, std::string> responses;
   GURL initialURL =
diff --git a/ios/web/shell/test/page_state_egtest.mm b/ios/web/shell/test/page_state_egtest.mm
index a0d11aa..7c3e1e0 100644
--- a/ios/web/shell/test/page_state_egtest.mm
+++ b/ios/web/shell/test/page_state_egtest.mm
@@ -28,29 +28,13 @@
     "http://ios/web/shell/test/http_server_files/tall_page.html?2";
 
 // Test scroll offsets.
-const CGFloat kScrollOffset1 = 20.0f;
-const CGFloat kScrollOffset2 = 40.0f;
-
-// Returns a matcher for asserting that element's content offset matches the
-// given |offset|.
-id<GREYMatcher> ContentOffset(CGPoint offset) {
-  MatchesBlock matches = ^BOOL(UIScrollView* element) {
-    return CGPointEqualToPoint([element contentOffset], offset);
-  };
-  DescribeToBlock describe = ^(id<GREYDescription> description) {
-    [description appendText:@"contentOffset"];
-  };
-  return grey_allOf(
-      grey_kindOfClass([UIScrollView class]),
-      [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
-                                           descriptionBlock:describe],
-      nil);
-}
+const CGFloat kOffset1 = 20.0f;
+const CGFloat kOffset2 = 40.0f;
 
 // Waits for the web view scroll view is scrolled to |y_offset|.
 void WaitForOffset(CGFloat y_offset) {
-  CGPoint content_offset = CGPointMake(0.0, y_offset);
-  NSString* content_offset_string = NSStringFromCGPoint(content_offset);
+  CGPoint offset = CGPointMake(0.0, y_offset);
+  NSString* content_offset_string = NSStringFromCGPoint(offset);
   NSString* name =
       [NSString stringWithFormat:@"Wait for scroll view to scroll to %@.",
                                  content_offset_string];
@@ -60,7 +44,7 @@
                     NSError* error = nil;
                     [[EarlGrey
                         selectElementWithMatcher:web::WebViewScrollView()]
-                        assertWithMatcher:ContentOffset(content_offset)
+                        assertWithMatcher:grey_scrollViewContentOffset(offset)
                                     error:&error];
                     return (error == nil);
                   }];
@@ -90,28 +74,28 @@
 
   // Scroll the first page and verify the offset.
   [[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
-      performAction:grey_scrollInDirection(kGREYDirectionDown, kScrollOffset1)];
+      performAction:grey_scrollInDirection(kGREYDirectionDown, kOffset1)];
   [[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
-      assertWithMatcher:ContentOffset(CGPointMake(0, kScrollOffset1))];
+      assertWithMatcher:grey_scrollViewContentOffset(CGPointMake(0, kOffset1))];
 
   // Load second URL, which is also a long page.
   [ShellEarlGrey loadURL:HttpServer::MakeUrl(kLongPage2)];
 
   // Scroll the second page and verify the offset.
   [[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
-      performAction:grey_scrollInDirection(kGREYDirectionDown, kScrollOffset2)];
+      performAction:grey_scrollInDirection(kGREYDirectionDown, kOffset2)];
   [[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
-      assertWithMatcher:ContentOffset(CGPointMake(0, kScrollOffset2))];
+      assertWithMatcher:grey_scrollViewContentOffset(CGPointMake(0, kOffset2))];
 
   // Go back and verify that the first page offset has been restored.
   [[EarlGrey selectElementWithMatcher:web::BackButton()]
       performAction:grey_tap()];
-  WaitForOffset(kScrollOffset1);
+  WaitForOffset(kOffset1);
 
   // Go forward and verify that the second page offset has been restored.
   [[EarlGrey selectElementWithMatcher:web::ForwardButton()]
       performAction:grey_tap()];
-  WaitForOffset(kScrollOffset2);
+  WaitForOffset(kOffset2);
 }
 
 @end
diff --git a/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc b/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc
index 3d864af9..e24f9ea 100644
--- a/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc
+++ b/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc
@@ -6,6 +6,7 @@
 
 #if ENABLE_SYNC_CALL_RESTRICTIONS
 
+#include "base/debug/leak_annotations.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/threading/thread_local.h"
@@ -45,6 +46,7 @@
   SyncCallSettings* result = g_sync_call_settings.Pointer()->Get();
   if (!result) {
     result = new SyncCallSettings();
+    ANNOTATE_LEAKING_OBJECT_PTR(result);
     DCHECK_EQ(result, g_sync_call_settings.Pointer()->Get());
   }
   return result;
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
index 24b095a..ada7ceb 100644
--- a/net/http/http_network_session.cc
+++ b/net/http/http_network_session.cc
@@ -157,7 +157,7 @@
       quic_do_not_mark_as_broken_on_network_change(false),
       proxy_delegate(nullptr),
       enable_token_binding(false),
-      http_09_on_non_default_ports_enabled(true),
+      http_09_on_non_default_ports_enabled(false),
       restrict_to_one_preconnect_for_proxies(false) {
   quic_supported_versions.push_back(QUIC_VERSION_35);
 }
diff --git a/net/spdy/spdy_frame_builder.h b/net/spdy/spdy_frame_builder.h
index a332345..2432c19d 100644
--- a/net/spdy/spdy_frame_builder.h
+++ b/net/spdy/spdy_frame_builder.h
@@ -11,6 +11,7 @@
 #include <memory>
 #include <string>
 
+#include "base/gtest_prod_util.h"
 #include "base/strings/string_piece.h"
 #include "base/sys_byteorder.h"
 #include "net/base/net_export.h"
@@ -39,14 +40,6 @@
   // multiple frames.
   size_t length() const { return offset_ + length_; }
 
-  // Returns a writeable buffer of given size in bytes, to be appended to the
-  // currently written frame. Does bounds checking on length but does not
-  // increment the underlying iterator. To do so, consumers should subsequently
-  // call Seek().
-  // In general, consumers should use Write*() calls instead of this.
-  // Returns NULL on failure.
-  char* GetWritableBuffer(size_t length);
-
   // Seeks forward by the given number of bytes. Useful in conjunction with
   // GetWriteableBuffer() above.
   bool Seek(size_t length);
@@ -113,6 +106,16 @@
   bool OverwriteLength(const SpdyFramer& framer, size_t length);
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(SpdyFrameBuilderTest, GetWritableBuffer);
+
+  // Returns a writeable buffer of given size in bytes, to be appended to the
+  // currently written frame. Does bounds checking on length but does not
+  // increment the underlying iterator. To do so, consumers should subsequently
+  // call Seek().
+  // In general, consumers should use Write*() calls instead of this.
+  // Returns NULL on failure.
+  char* GetWritableBuffer(size_t length);
+
   // Checks to make sure that there is an appropriate amount of space for a
   // write of given size, in bytes.
   bool CanWrite(size_t length) const;
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index db062809..2038b39f 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -144,8 +144,8 @@
                        CompressionOption option)
     : current_frame_buffer_(kControlFrameBufferSize),
       expect_continuation_(0),
-      visitor_(NULL),
-      debug_visitor_(NULL),
+      visitor_(nullptr),
+      debug_visitor_(nullptr),
       header_handler_(nullptr),
       compression_option_(option),
       probable_http_response_(false),
@@ -1489,7 +1489,7 @@
     set_error(SPDY_GOAWAY_FRAME_CORRUPT);
   } else if (remaining_data_length_ == 0) {
     // Signal that there is not more opaque data.
-    visitor_->OnGoAwayFrameData(NULL, 0);
+    visitor_->OnGoAwayFrameData(nullptr, 0);
     CHANGE_STATE(SPDY_FRAME_COMPLETE);
   }
   return original_len;
diff --git a/net/spdy/spdy_header_block_test.cc b/net/spdy/spdy_header_block_test.cc
index c2c4a8f..1f0f619 100644
--- a/net/spdy/spdy_header_block_test.cc
+++ b/net/spdy/spdy_header_block_test.cc
@@ -16,7 +16,6 @@
 using base::StringPiece;
 using std::make_pair;
 using std::string;
-using std::vector;
 using ::testing::ElementsAre;
 
 namespace net {
@@ -197,7 +196,7 @@
 }
 
 TEST(JoinTest, JoinEmpty) {
-  vector<StringPiece> empty;
+  std::vector<StringPiece> empty;
   StringPiece separator = ", ";
   char buf[10] = "";
   size_t written = Join(buf, empty, separator);
@@ -205,7 +204,7 @@
 }
 
 TEST(JoinTest, JoinOne) {
-  vector<StringPiece> v = {"one"};
+  std::vector<StringPiece> v = {"one"};
   StringPiece separator = ", ";
   char buf[15];
   size_t written = Join(buf, v, separator);
@@ -214,7 +213,7 @@
 }
 
 TEST(JoinTest, JoinMultiple) {
-  vector<StringPiece> v = {"one", "two", "three"};
+  std::vector<StringPiece> v = {"one", "two", "three"};
   StringPiece separator = ", ";
   char buf[15];
   size_t written = Join(buf, v, separator);
diff --git a/net/spdy/spdy_headers_block_parser_test.cc b/net/spdy/spdy_headers_block_parser_test.cc
index 00f8fc4..5c9e56c 100644
--- a/net/spdy/spdy_headers_block_parser_test.cc
+++ b/net/spdy/spdy_headers_block_parser_test.cc
@@ -37,14 +37,10 @@
 
 class SpdyHeadersBlockParserTest : public ::testing::Test {
  public:
+  SpdyHeadersBlockParserTest() : parser_(&handler_) {}
   ~SpdyHeadersBlockParserTest() override {}
 
  protected:
-  void SetUp() override {
-    // Create a parser using the mock handler.
-    parser_.reset(new SpdyHeadersBlockParser(&handler_));
-  }
-
   // Create a header block with a specified number of headers.
   string CreateHeaders(uint32_t num_headers, bool insert_nulls) {
     string headers;
@@ -87,7 +83,7 @@
   }
 
   MockSpdyHeadersHandler handler_;
-  std::unique_ptr<SpdyHeadersBlockParser> parser_;
+  SpdyHeadersBlockParser parser_;
 
   static const char *const kBaseKey;
   static const char *const kBaseValue;
@@ -117,9 +113,9 @@
   } else {
     EXPECT_CALL(handler_, OnHeaderBlockEnd(headers.length())).Times(1);
   }
-  EXPECT_TRUE(parser_->
-      HandleControlFrameHeadersData(1, headers.c_str(), headers.length()));
-  EXPECT_EQ(SpdyHeadersBlockParser::NO_PARSER_ERROR, parser_->get_error());
+  EXPECT_TRUE(parser_.HandleControlFrameHeadersData(1, headers.c_str(),
+                                                    headers.length()));
+  EXPECT_EQ(SpdyHeadersBlockParser::NO_PARSER_ERROR, parser_.get_error());
 }
 
 TEST_F(SpdyHeadersBlockParserTest, NullsSupportedTest) {
@@ -139,9 +135,9 @@
     EXPECT_CALL(handler_, OnHeaderBlockEnd(headers.length())).Times(1);
   }
 
-  EXPECT_TRUE(parser_->
-      HandleControlFrameHeadersData(1, headers.c_str(), headers.length()));
-  EXPECT_EQ(SpdyHeadersBlockParser::NO_PARSER_ERROR, parser_->get_error());
+  EXPECT_TRUE(parser_.HandleControlFrameHeadersData(1, headers.c_str(),
+                                                    headers.length()));
+  EXPECT_EQ(SpdyHeadersBlockParser::NO_PARSER_ERROR, parser_.get_error());
 }
 
 TEST_F(SpdyHeadersBlockParserTest, MultipleBlocksAndHeadersWithPartialData) {
@@ -175,12 +171,11 @@
     for (string::iterator it = headers.begin(); it != headers.end(); ++it) {
       if ((it + 1) == headers.end()) {
         // Last byte completes the block.
-        EXPECT_TRUE(parser_->HandleControlFrameHeadersData(i, &(*it), 1));
-        EXPECT_EQ(SpdyHeadersBlockParser::NO_PARSER_ERROR,
-                  parser_->get_error());
+        EXPECT_TRUE(parser_.HandleControlFrameHeadersData(i, &(*it), 1));
+        EXPECT_EQ(SpdyHeadersBlockParser::NO_PARSER_ERROR, parser_.get_error());
       } else {
-        EXPECT_FALSE(parser_->HandleControlFrameHeadersData(i, &(*it), 1));
-        EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_->get_error());
+        EXPECT_FALSE(parser_.HandleControlFrameHeadersData(i, &(*it), 1));
+        EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_.get_error());
       }
     }
   }
@@ -205,35 +200,34 @@
   for (string::iterator it = headers.begin(); it != headers.end(); ++it) {
     if ((it + 1) == headers.end()) {
       // Last byte completes the block.
-      EXPECT_TRUE(parser_->HandleControlFrameHeadersData(1, &(*it), 1));
-      EXPECT_EQ(SpdyHeadersBlockParser::NO_PARSER_ERROR, parser_->get_error());
+      EXPECT_TRUE(parser_.HandleControlFrameHeadersData(1, &(*it), 1));
+      EXPECT_EQ(SpdyHeadersBlockParser::NO_PARSER_ERROR, parser_.get_error());
     } else {
-      EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, &(*it), 1));
-      EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_->get_error());
-      EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, NULL, 0));
+      EXPECT_FALSE(parser_.HandleControlFrameHeadersData(1, &(*it), 1));
+      EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_.get_error());
+      EXPECT_FALSE(parser_.HandleControlFrameHeadersData(1, NULL, 0));
     }
   }
 }
 
-TEST_F(SpdyHeadersBlockParserTest, LargeBlocksDiscardedTest) {
+TEST_F(SpdyHeadersBlockParserTest, TooManyHeadersTest) {
   // Header block with too many headers.
-  {
-    string headers = EncodeLength(parser_->MaxNumberOfHeaders() + 1);
-    EXPECT_FALSE(parser_->
-        HandleControlFrameHeadersData(1, headers.c_str(), headers.length()));
-    EXPECT_EQ(SpdyHeadersBlockParser::HEADER_BLOCK_TOO_LARGE,
-              parser_->get_error());
-  }
-  parser_.reset(new SpdyHeadersBlockParser(&handler_));
+  string headers = EncodeLength(parser_.MaxNumberOfHeaders() + 1);
+  EXPECT_FALSE(parser_.HandleControlFrameHeadersData(1, headers.c_str(),
+                                                     headers.length()));
+  EXPECT_EQ(SpdyHeadersBlockParser::HEADER_BLOCK_TOO_LARGE,
+            parser_.get_error());
+}
+
+TEST_F(SpdyHeadersBlockParserTest, TooLongKeyTest) {
   // Header block with one header, which has a too-long key.
-  {
-    string headers = EncodeLength(1) + EncodeLength(
-        SpdyHeadersBlockParser::kMaximumFieldLength + 1);
-    EXPECT_FALSE(parser_->
-        HandleControlFrameHeadersData(1, headers.c_str(), headers.length()));
-    EXPECT_EQ(SpdyHeadersBlockParser::HEADER_FIELD_TOO_LARGE,
-              parser_->get_error());
-  }
+  string headers =
+      EncodeLength(1) +
+      EncodeLength(SpdyHeadersBlockParser::kMaximumFieldLength + 1);
+  EXPECT_FALSE(parser_.HandleControlFrameHeadersData(1, headers.c_str(),
+                                                     headers.length()));
+  EXPECT_EQ(SpdyHeadersBlockParser::HEADER_FIELD_TOO_LARGE,
+            parser_.get_error());
 }
 
 TEST_F(SpdyHeadersBlockParserTest, ExtraDataTest) {
@@ -251,31 +245,31 @@
     EXPECT_CALL(handler_, OnHeaderBlockEnd(headers.length())).Times(1);
   }
 
-  EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, headers.c_str(),
-                                                      headers.length()));
-  EXPECT_EQ(SpdyHeadersBlockParser::TOO_MUCH_DATA, parser_->get_error());
+  EXPECT_FALSE(parser_.HandleControlFrameHeadersData(1, headers.c_str(),
+                                                     headers.length()));
+  EXPECT_EQ(SpdyHeadersBlockParser::TOO_MUCH_DATA, parser_.get_error());
 }
 
 TEST_F(SpdyHeadersBlockParserTest, WrongStreamIdTest) {
   string headers(CreateHeaders(kNumHeadersInBlock, false));
-  EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, headers.data(), 1));
-  EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_->get_error());
+  EXPECT_FALSE(parser_.HandleControlFrameHeadersData(1, headers.data(), 1));
+  EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_.get_error());
   bool result;
   EXPECT_SPDY_BUG(
-      result = parser_->HandleControlFrameHeadersData(2, headers.data() + 1, 1),
+      result = parser_.HandleControlFrameHeadersData(2, headers.data() + 1, 1),
       "Unexpected stream id: 2 \\(expected 1\\)");
   EXPECT_FALSE(result);
-  EXPECT_EQ(SpdyHeadersBlockParser::UNEXPECTED_STREAM_ID, parser_->get_error());
+  EXPECT_EQ(SpdyHeadersBlockParser::UNEXPECTED_STREAM_ID, parser_.get_error());
 }
 
 TEST_F(SpdyHeadersBlockParserTest, InvalidStreamIdTest) {
   string headers(CreateHeaders(kNumHeadersInBlock, false));
   bool result;
   EXPECT_SPDY_BUG(
-      result = parser_->HandleControlFrameHeadersData(0, headers.data(), 1),
+      result = parser_.HandleControlFrameHeadersData(0, headers.data(), 1),
       "Expected nonzero stream id, saw: 0");
   EXPECT_FALSE(result);
-  EXPECT_EQ(SpdyHeadersBlockParser::UNEXPECTED_STREAM_ID, parser_->get_error());
+  EXPECT_EQ(SpdyHeadersBlockParser::UNEXPECTED_STREAM_ID, parser_.get_error());
 }
 
 }  // namespace net
diff --git a/services/file/file_service.cc b/services/file/file_service.cc
index 2e4bd50..a8b7eee7 100644
--- a/services/file/file_service.cc
+++ b/services/file/file_service.cc
@@ -48,8 +48,9 @@
     : public base::SupportsWeakPtr<LevelDBServiceObjects> {
  public:
   // Created on the main thread.
-  LevelDBServiceObjects(scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-      : task_runner_(std::move(task_runner)) {}
+  LevelDBServiceObjects(
+      scoped_refptr<base::SingleThreadTaskRunner> file_task_runner)
+      : file_task_runner_(std::move(file_task_runner)) {}
 
   // Destroyed on the |leveldb_service_runner_|.
   ~LevelDBServiceObjects() {}
@@ -58,12 +59,13 @@
   void OnLevelDBServiceRequest(const service_manager::Identity& remote_identity,
                                leveldb::mojom::LevelDBServiceRequest request) {
     if (!leveldb_service_)
-      leveldb_service_.reset(new leveldb::LevelDBServiceImpl(task_runner_));
+      leveldb_service_.reset(
+          new leveldb::LevelDBServiceImpl(file_task_runner_));
     leveldb_bindings_.AddBinding(leveldb_service_.get(), std::move(request));
   }
 
  private:
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_;
 
   // Variables that are only accessible on the |leveldb_service_runner_| thread.
   std::unique_ptr<leveldb::mojom::LevelDBService> leveldb_service_;
@@ -94,7 +96,7 @@
   file_system_objects_.reset(new FileService::FileSystemObjects(
       GetUserDirForUserId(context()->identity().user_id())));
   leveldb_objects_.reset(
-      new FileService::LevelDBServiceObjects(leveldb_service_runner_));
+      new FileService::LevelDBServiceObjects(file_service_runner_));
 }
 
 bool FileService::OnConnect(const service_manager::ServiceInfo& remote_info,
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index 7ed4bbb2..c353889 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -380,7 +380,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -413,7 +413,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -446,7 +446,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -482,7 +482,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -515,7 +515,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -548,7 +548,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -584,7 +584,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -620,7 +620,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -653,7 +653,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -686,7 +686,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -719,7 +719,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -755,7 +755,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -788,7 +788,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -821,7 +821,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -854,7 +854,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -887,7 +887,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -920,7 +920,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -953,7 +953,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -986,7 +986,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1019,7 +1019,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1052,7 +1052,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1085,7 +1085,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1118,7 +1118,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1154,7 +1154,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1187,7 +1187,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1220,7 +1220,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1253,7 +1253,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1286,7 +1286,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1319,7 +1319,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1352,7 +1352,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1385,7 +1385,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index d84eda5..1cc22fe6 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -17,7 +17,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -49,7 +49,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -80,7 +80,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -111,7 +111,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -143,7 +143,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -174,7 +174,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -205,7 +205,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -239,7 +239,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -271,7 +271,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -302,7 +302,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -336,7 +336,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -368,7 +368,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -399,7 +399,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -430,7 +430,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -461,7 +461,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -492,7 +492,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -523,7 +523,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -555,7 +555,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -586,7 +586,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -617,7 +617,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -648,7 +648,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -679,7 +679,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -711,7 +711,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -743,7 +743,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -775,7 +775,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -807,7 +807,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -842,7 +842,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -874,7 +874,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -905,7 +905,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -936,7 +936,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -967,7 +967,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -998,7 +998,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1029,7 +1029,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1060,7 +1060,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1091,7 +1091,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1288,7 +1288,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1321,7 +1321,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1357,7 +1357,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1390,7 +1390,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1423,7 +1423,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1456,7 +1456,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1489,7 +1489,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1522,7 +1522,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1555,7 +1555,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1588,7 +1588,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1621,7 +1621,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1654,7 +1654,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1687,7 +1687,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1720,7 +1720,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1753,7 +1753,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1786,7 +1786,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1819,7 +1819,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1852,7 +1852,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1885,7 +1885,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1921,7 +1921,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1954,7 +1954,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1987,7 +1987,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2020,7 +2020,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2053,7 +2053,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2086,7 +2086,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2119,7 +2119,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2152,7 +2152,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2188,7 +2188,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2224,7 +2224,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2260,7 +2260,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2296,7 +2296,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2438,7 +2438,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2472,7 +2472,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2503,7 +2503,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2534,7 +2534,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2568,7 +2568,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2599,7 +2599,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2630,7 +2630,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2665,7 +2665,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2699,7 +2699,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2730,7 +2730,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2761,7 +2761,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2792,7 +2792,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2826,7 +2826,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2857,7 +2857,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2888,7 +2888,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2919,7 +2919,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2950,7 +2950,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2981,7 +2981,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3012,7 +3012,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3043,7 +3043,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3074,7 +3074,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3105,7 +3105,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3136,7 +3136,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3167,7 +3167,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3201,7 +3201,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3232,7 +3232,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3263,7 +3263,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3294,7 +3294,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3325,7 +3325,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3356,7 +3356,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3387,7 +3387,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -3418,7 +3418,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index 5547a65c..bb609f85 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -33,7 +33,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -65,7 +65,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -96,7 +96,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -127,7 +127,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -159,7 +159,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -190,7 +190,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -221,7 +221,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -255,7 +255,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -290,7 +290,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -322,7 +322,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -353,7 +353,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -384,7 +384,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -419,7 +419,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -451,7 +451,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -482,7 +482,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -513,7 +513,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -544,7 +544,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -575,7 +575,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -607,7 +607,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -638,7 +638,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -669,7 +669,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -700,7 +700,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -731,7 +731,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -763,7 +763,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -795,7 +795,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -827,7 +827,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -859,7 +859,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -894,7 +894,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -926,7 +926,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -957,7 +957,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -988,7 +988,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1019,7 +1019,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1050,7 +1050,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1081,7 +1081,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1112,7 +1112,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1143,7 +1143,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1245,7 +1245,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1277,7 +1277,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1308,7 +1308,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1339,7 +1339,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1371,7 +1371,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1402,7 +1402,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1433,7 +1433,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1467,7 +1467,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1502,7 +1502,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1534,7 +1534,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1565,7 +1565,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1596,7 +1596,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1631,7 +1631,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1663,7 +1663,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1694,7 +1694,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1725,7 +1725,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1756,7 +1756,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1787,7 +1787,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1819,7 +1819,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1850,7 +1850,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1881,7 +1881,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1912,7 +1912,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1943,7 +1943,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -1975,7 +1975,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2007,7 +2007,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2039,7 +2039,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2071,7 +2071,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2106,7 +2106,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2138,7 +2138,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2169,7 +2169,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2200,7 +2200,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2231,7 +2231,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2262,7 +2262,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2293,7 +2293,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2324,7 +2324,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
@@ -2355,7 +2355,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+              "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6"
             }
           ],
           "dimension_sets": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
index 34a8f1e..8212055 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -1625,6 +1625,9 @@
 crbug.com/157218 compositing/overflow/border-radius-styles-with-composited-child.html [ Failure ]
 crbug.com/157218 compositing/overflow/siblings-with-border-radius-ancestor.html [ Failure ]
 crbug.com/157218 compositing/overflow/siblings-composited-with-border-radius-ancestor.html [ Failure ]
+crbug.com/157218 compositing/overflow/grandchild-composited-with-border-radius-ancestor.html [ Failure ]
+crbug.com/157218 compositing/overflow/grandchild-with-border-radius-ancestor.html [ Failure ]
+crbug.com/157218 compositing/overflow/siblings-composited-with-border-radius-ancestor-one-clipped.html [ Failure ]
 
 # Notes about rebaselined tests:
 #
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index e4454cb..15d7197 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -800,9 +800,6 @@
 crbug.com/498539 [ Win7 ] inspector/console/console-dir-es6.html [ Failure Pass ]
 crbug.com/498539 [ Win7 ] inspector/elements/styles-4/styles-update-from-js.html [ Crash Pass ]
 
-crbug.com/645398 fast/text/ellipsis-with-list-marker-in-ltr-flow.html [ NeedsRebaseline ]
-crbug.com/645398 fast/text/ellipsis-with-list-marker-in-rtl-flow.html [ NeedsRebaseline ]
-
 crbug.com/596968 [ Win ] inspector-protocol/input/eventTimestamp.html [ Failure Pass ]
 
 crbug.com/487281 [ Mac ] fast/forms/select/menulist-narrow-width.html [ Failure ]
@@ -821,7 +818,7 @@
 
 crbug.com/685851 [ Win ] fast/table/backgr_position-table-column-group.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_position-table-column-group-collapsed-border.html [ Pass Failure ]
-crbug.com/685851 [ Win10 ] fast/table/backgr_layers-show-collapsed-border.html [ Failure Pass ]
+crbug.com/685851 [ Win ] fast/table/backgr_layers-show-collapsed-border.html [ Failure Pass ]
 crbug.com/685851 [ Win ] fast/table/backgr_simple-table-column.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_position-table-row.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_border-table-row.html [ Pass Failure ]
@@ -833,7 +830,7 @@
 crbug.com/685851 [ Win ] fast/table/backgr_position-table-column-collapsed-border.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_simple-table-collapsed-border.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_border-table-row-group.html [ Pass Failure ]
-crbug.com/685851 [ Win10 ] fast/table/backgr_simple-table-cell.html [ Failure Pass ]
+crbug.com/685851 [ Win ] fast/table/backgr_simple-table-cell.html [ Failure Pass ]
 crbug.com/685851 [ Win ] fast/table/backgr_position-table.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_simple-table-row-group.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_border-table-collapsed-border.html [ Pass Failure ]
@@ -843,22 +840,22 @@
 crbug.com/685851 [ Win ] fast/table/backgr_border-table-row-collapsed-border.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_border-table-column-group-collapsed-border.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_simple-table.html [ Pass Failure ]
-crbug.com/685851 [ Win10 ] fast/table/backgr_simple-table-row.html [ Failure Pass ]
+crbug.com/685851 [ Win ] fast/table/backgr_simple-table-row.html [ Failure Pass ]
 crbug.com/685851 [ Win ] fast/table/backgr_border-table-cell-collapsed-border.html [ Pass Failure ]
-crbug.com/685851 [ Win10 ] fast/table/backgr_simple-table-row-group-collapsed-border.html [ Failure Pass ]
+crbug.com/685851 [ Win ] fast/table/backgr_simple-table-row-group-collapsed-border.html [ Failure Pass ]
 crbug.com/685851 [ Win ] fast/table/backgr_simple-table-cell-collapsed-border.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_position-table-row-group.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_simple-table-column-group.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_simple-table-column-group-collapsed-border.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_border-table-column.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_position-table-cell-collapsed-border.html [ Pass Failure ]
-crbug.com/685851 [ Win10 ] fast/table/backgr_layers-show.html [ Failure Pass ]
+crbug.com/685851 [ Win ] fast/table/backgr_layers-show.html [ Failure Pass ]
 crbug.com/685851 [ Win ] fast/table/backgr_border-table-row-group-collapsed-border.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_border-table-quirks.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_border-table-quirks-collapsed-border.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_border-table-column-group.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_simple-table-column-collapsed-border.html [ Pass Failure ]
-crbug.com/685851 [ Win10 ] fast/table/backgr_position-table-cell.html [ Failure Pass ]
+crbug.com/685851 [ Win ] fast/table/backgr_position-table-cell.html [ Failure Pass ]
 crbug.com/685851 [ Win ] fast/table/backgr_border-table.html [ Pass Failure ]
 crbug.com/685851 [ Win ] fast/table/backgr_layers-hide-collapsed-border.html [ Pass Failure ]
 
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/notifications/notification-after-disconnection.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/notifications/notification-after-disconnection.html
new file mode 100644
index 0000000..591596a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/notifications/notification-after-disconnection.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../../resources/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+  // The iframe we create will subscribe to notifications and will ensure
+  // that the browser keeps receiving notifications even after this frame's
+  // device disconnects.
+  let iframe_connected = new Promise(resolve => {
+    window.onmessage = messageEvent => {
+      if (messageEvent.data === 'Ready') {
+        let iframe = document.querySelector('iframe');
+        callWithKeyDown(() => {
+          iframe.contentWindow.postMessage('RequestAndConnect', '*');
+        });
+      } else if (messageEvent.data === 'Connected') {
+        let iframe = document.querySelector('iframe');
+        iframe.contentWindow.postMessage('StartNotifications', '*');
+      } else if (messageEvent.data === 'NotificationsStarted') {
+        resolve();
+      } else {
+        reject();
+      }
+    }
+  });
+
+  return setBluetoothFakeAdapter('HeartRateAdapter')
+    .then(() => {
+      let iframe = document.createElement('iframe');
+      iframe.src = '../../../resources/bluetooth/heart-rate-iframe.html';
+      document.body.appendChild(iframe);
+
+      return iframe_connected
+        .then(() => requestDeviceWithKeyDown(
+          {filters: [{services: ['heart_rate']}]}))
+        .then(device => device.gatt.connect())
+        .then(gatt => gatt.getPrimaryService('heart_rate'))
+        .then(service => service.getCharacteristic('heart_rate_measurement'))
+        .then(characteristic => characteristic.startNotifications())
+        .then(characteristic => new Promise(resolve => {
+          // Make sure we are receiving events.
+          let event_listener = e => {
+            characteristic.removeEventListener(
+              'characteristicvaluechanged', event_listener);
+            resolve(characteristic);
+          };
+          characteristic.addEventListener(
+            'characteristicvaluechanged', event_listener);
+        }))
+        .then(characteristic => {
+          characteristic.service.device.gatt.disconnect()
+          // The browser still receives notifications because of the iframe but
+          // no events should be dispatched on this characteristic because
+          // the characteristic's device disconnected.
+          return assert_no_events(characteristic,
+                                  'characteristicvaluechanged');
+        });
+    });
+}, 'Characteristic sends notification after disconnection. Should not ' +
+   'fire an event.');
+</script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/server/connect/garbage-collection-ran-during-error-expected.txt b/third_party/WebKit/LayoutTests/bluetooth/server/connect/garbage-collection-ran-during-error-expected.txt
deleted file mode 100644
index 187bb4ec..0000000
--- a/third_party/WebKit/LayoutTests/bluetooth/server/connect/garbage-collection-ran-during-error-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-CONSOLE ERROR: Uncaught (in promise) NetworkError: Authentication canceled.
-This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = Authentication canceled.
-PASS Garbage collection ran during a connect call that fails. Should not crash. 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/bluetooth/server/connect/garbage-collection-ran-during-error.html b/third_party/WebKit/LayoutTests/bluetooth/server/connect/garbage-collection-ran-during-error.html
index 29e4933..9aa12e3 100644
--- a/third_party/WebKit/LayoutTests/bluetooth/server/connect/garbage-collection-ran-during-error.html
+++ b/third_party/WebKit/LayoutTests/bluetooth/server/connect/garbage-collection-ran-during-error.html
@@ -4,12 +4,12 @@
 <script src="../../../resources/bluetooth/bluetooth-helpers.js"></script>
 <script>
 'use strict';
-promise_test(() => {
+promise_test(t => {
   return setBluetoothFakeAdapter('FailingConnectionsAdapter')
     .then(() => requestDeviceWithKeyDown({
       filters: [{services: [errorUUID(0x1) /* in progress error */]}]}))
     .then(device => {
-      device.gatt.connect();
+      promise_rejects(t, 'NetworkError', device.gatt.connect());
     })
     .then(runGarbageCollection);
 }, 'Garbage collection ran during a connect call that fails. ' +
diff --git a/third_party/WebKit/LayoutTests/bluetooth/server/disconnect/detach-gc.html b/third_party/WebKit/LayoutTests/bluetooth/server/disconnect/detach-gc.html
index cab5e4b..7a8a5908 100644
--- a/third_party/WebKit/LayoutTests/bluetooth/server/disconnect/detach-gc.html
+++ b/third_party/WebKit/LayoutTests/bluetooth/server/disconnect/detach-gc.html
@@ -10,7 +10,7 @@
       if (messageEvent.data === 'Ready') {
         let iframe = document.querySelector('iframe');
         callWithKeyDown(() => {
-          iframe.contentWindow.postMessage('Go', '*');
+          iframe.contentWindow.postMessage('RequestAndConnect', '*');
         });
       } else if (messageEvent.data === 'Connected') {
         // Detach
@@ -25,7 +25,7 @@
     setBluetoothFakeAdapter('HeartRateAdapter')
       .then(() => {
         let iframe = document.createElement('iframe');
-        iframe.src = '../../../resources/bluetooth/connect-iframe.html';
+        iframe.src = '../../../resources/bluetooth/heart-rate-iframe.html';
         document.body.appendChild(iframe);
       });
   }, 'Detach frame then garbage collect. We shouldn\'t crash.');
diff --git a/third_party/WebKit/LayoutTests/bluetooth/server/disconnect/gc-detach.html b/third_party/WebKit/LayoutTests/bluetooth/server/disconnect/gc-detach.html
index 3534b67b..edfb869 100644
--- a/third_party/WebKit/LayoutTests/bluetooth/server/disconnect/gc-detach.html
+++ b/third_party/WebKit/LayoutTests/bluetooth/server/disconnect/gc-detach.html
@@ -10,7 +10,7 @@
       if (messageEvent.data === 'Ready') {
         let iframe = document.querySelector('iframe');
         callWithKeyDown(() => {
-          iframe.contentWindow.postMessage('Go', '*');
+          iframe.contentWindow.postMessage('RequestAndConnect', '*');
         });
       } else if (messageEvent.data === 'Connected') {
         let iframe = document.querySelector('iframe');
@@ -27,7 +27,7 @@
     setBluetoothFakeAdapter('HeartRateAdapter')
       .then(() => {
         let iframe = document.createElement('iframe');
-        iframe.src = '../../../resources/bluetooth/connect-iframe.html';
+        iframe.src = '../../../resources/bluetooth/heart-rate-iframe.html';
         document.body.appendChild(iframe);
       });
   }, 'Garbage collect then detach frame. We shouldn\'t crash.');
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-composited-with-border-radius-ancestor-expected.png b/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-composited-with-border-radius-ancestor-expected.png
new file mode 100644
index 0000000..a887344
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-composited-with-border-radius-ancestor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-composited-with-border-radius-ancestor-expected.txt b/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-composited-with-border-radius-ancestor-expected.txt
new file mode 100644
index 0000000..a2d4758
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-composited-with-border-radius-ancestor-expected.txt
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+layer at (8,8) size 208x208 clip at (12,12) size 200x200 scrollHeight 260
+  LayoutBlockFlow {DIV} at (0,0) size 208x208 [border: (4px solid #000000)]
+layer at (12,-18) size 10x260 backgroundClip at (12,12) size 200x200 clip at (12,12) size 200x200
+  LayoutBlockFlow (relative positioned) {DIV} at (4,4) size 10x260 [bgcolor=#008000]
+layer at (202,-48) size 10x260 backgroundClip at (12,12) size 200x200 clip at (12,12) size 200x200
+  LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 10x260
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-composited-with-border-radius-ancestor.html b/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-composited-with-border-radius-ancestor.html
new file mode 100644
index 0000000..b2eec1c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-composited-with-border-radius-ancestor.html
@@ -0,0 +1,36 @@
+<style>
+.outermost {
+  border: 4px solid #000;
+  border-radius: 40px;
+  width: 200px;
+  height: 200px;
+  overflow: hidden;
+}
+
+.inner1 {
+  background-color: green;
+  width: 10px;
+  height: 260px;
+  position: relative;
+  left: 0px;
+  top: -30px;
+  will-change: transform;
+}
+
+.inner2 {
+  background-color: green;
+  width: 10px;
+  height: 260px;
+  position: relative;
+  left: 190px;
+  top: -30px;
+  will-change: transform;
+}
+</style>
+
+<div class="outermost">
+  <div class="inner1">
+    <div class="inner2"></div>
+  </div>
+</div>
+
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-with-border-radius-ancestor-expected.png b/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-with-border-radius-ancestor-expected.png
new file mode 100644
index 0000000..a887344
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-with-border-radius-ancestor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-with-border-radius-ancestor-expected.txt b/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-with-border-radius-ancestor-expected.txt
new file mode 100644
index 0000000..a2d4758
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-with-border-radius-ancestor-expected.txt
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+layer at (8,8) size 208x208 clip at (12,12) size 200x200 scrollHeight 260
+  LayoutBlockFlow {DIV} at (0,0) size 208x208 [border: (4px solid #000000)]
+layer at (12,-18) size 10x260 backgroundClip at (12,12) size 200x200 clip at (12,12) size 200x200
+  LayoutBlockFlow (relative positioned) {DIV} at (4,4) size 10x260 [bgcolor=#008000]
+layer at (202,-48) size 10x260 backgroundClip at (12,12) size 200x200 clip at (12,12) size 200x200
+  LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 10x260
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-with-border-radius-ancestor.html b/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-with-border-radius-ancestor.html
new file mode 100644
index 0000000..e07300f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/grandchild-with-border-radius-ancestor.html
@@ -0,0 +1,35 @@
+<style>
+.outermost {
+  border: 4px solid #000;
+  border-radius: 40px;
+  width: 200px;
+  height: 200px;
+  overflow: hidden;
+}
+
+.inner1 {
+  background-color: green;
+  width: 10px;
+  height: 260px;
+  position: relative;
+  left: 0px;
+  top: -30px;
+  will-change: transform;
+}
+
+.inner2 {
+  background-color: green;
+  width: 10px;
+  height: 260px;
+  position: relative;
+  left: 190px;
+  top: -30px;
+}
+</style>
+
+<div class="outermost">
+  <div class="inner1">
+    <div class="inner2"></div>
+  </div>
+</div>
+
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor-expected.txt b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor-expected.txt
index 0bb6a6d..bc60c248 100644
--- a/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor-expected.txt
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor-expected.txt
@@ -3,9 +3,9 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-layer at (8,8) size 208x208 clip at (12,12) size 200x200 scrollHeight 260
+layer at (8,8) size 208x208 clip at (12,12) size 200x200 scrollHeight 520
   LayoutBlockFlow {DIV} at (0,0) size 208x208 [border: (4px solid #000000)]
 layer at (12,-18) size 10x260 backgroundClip at (12,12) size 200x200 clip at (12,12) size 200x200
   LayoutBlockFlow (relative positioned) {DIV} at (4,4) size 10x260 [bgcolor=#008000]
-layer at (202,-18) size 10x260 backgroundClip at (12,12) size 200x200 clip at (12,12) size 200x200
-  LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 10x260
+layer at (202,12) size 10x260 backgroundClip at (12,12) size 200x200 clip at (12,12) size 200x200
+  LayoutBlockFlow (relative positioned) {DIV} at (4,264) size 10x260 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor-one-clipped-expected.png b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor-one-clipped-expected.png
new file mode 100644
index 0000000..7b9ed33
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor-one-clipped-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor-one-clipped-expected.txt b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor-one-clipped-expected.txt
new file mode 100644
index 0000000..22b15ba
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor-one-clipped-expected.txt
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+layer at (8,8) size 208x208 clip at (12,12) size 200x200 scrollHeight 310
+  LayoutBlockFlow {DIV} at (0,0) size 208x208 [border: (4px solid #000000)]
+layer at (62,62) size 50x50
+  LayoutBlockFlow (relative positioned) {DIV} at (4,4) size 50x50 [bgcolor=#008000]
+layer at (202,-38) size 10x260 backgroundClip at (12,12) size 200x200 clip at (12,12) size 200x200
+  LayoutBlockFlow (relative positioned) {DIV} at (4,54) size 10x260 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor-one-clipped.html b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor-one-clipped.html
new file mode 100644
index 0000000..70d2c8fa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor-one-clipped.html
@@ -0,0 +1,34 @@
+<style>
+.outermost {
+  border: 4px solid #000;
+  border-radius: 40px;
+  width: 200px;
+  height: 200px;
+  overflow: hidden;
+}
+
+.inner1 {
+  background-color: green;
+  width: 50px;
+  height: 50px;
+  position: relative;
+  left: 50px;
+  top: 50px;
+  will-change: transform;
+}
+
+.inner2 {
+  background-color: green;
+  width: 10px;
+  height: 260px;
+  position: relative;
+  left: 190px;
+  top: -100px;
+  will-change: transform;
+}
+</style>
+
+<div class="outermost">
+  <div class="inner1"></div>
+  <div class="inner2"></div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor.html b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor.html
index 996e256..8795193 100644
--- a/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor.html
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-composited-with-border-radius-ancestor.html
@@ -23,15 +23,13 @@
   height: 260px;
   position: relative;
   left: 190px;
-  top: 0px;
+  top: -260px;
   will-change: transform;
 }
 </style>
 
 <div class="outermost">
-  <div class="inner1">
-    <div class="inner2">
-    </div>
-  </div>
+  <div class="inner1"></div>
+  <div class="inner2"></div>
 </div>
 
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/siblings-with-border-radius-ancestor-expected.png b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-with-border-radius-ancestor-expected.png
index a887344..2ccc2bf 100644
--- a/third_party/WebKit/LayoutTests/compositing/overflow/siblings-with-border-radius-ancestor-expected.png
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-with-border-radius-ancestor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/siblings-with-border-radius-ancestor-expected.txt b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-with-border-radius-ancestor-expected.txt
index a2d4758..bc60c248 100644
--- a/third_party/WebKit/LayoutTests/compositing/overflow/siblings-with-border-radius-ancestor-expected.txt
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-with-border-radius-ancestor-expected.txt
@@ -3,9 +3,9 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-layer at (8,8) size 208x208 clip at (12,12) size 200x200 scrollHeight 260
+layer at (8,8) size 208x208 clip at (12,12) size 200x200 scrollHeight 520
   LayoutBlockFlow {DIV} at (0,0) size 208x208 [border: (4px solid #000000)]
 layer at (12,-18) size 10x260 backgroundClip at (12,12) size 200x200 clip at (12,12) size 200x200
   LayoutBlockFlow (relative positioned) {DIV} at (4,4) size 10x260 [bgcolor=#008000]
-layer at (202,-48) size 10x260 backgroundClip at (12,12) size 200x200 clip at (12,12) size 200x200
-  LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 10x260
+layer at (202,12) size 10x260 backgroundClip at (12,12) size 200x200 clip at (12,12) size 200x200
+  LayoutBlockFlow (relative positioned) {DIV} at (4,264) size 10x260 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/siblings-with-border-radius-ancestor.html b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-with-border-radius-ancestor.html
index c2f7e4a..c860fab 100644
--- a/third_party/WebKit/LayoutTests/compositing/overflow/siblings-with-border-radius-ancestor.html
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/siblings-with-border-radius-ancestor.html
@@ -23,14 +23,12 @@
   height: 260px;
   position: relative;
   left: 190px;
-  top: -30px;
+  top: -260px;
 }
 </style>
 
 <div class="outermost">
-  <div class="inner1">
-    <div class="inner2">
-    </div>
-  </div>
+  <div class="inner1"></div>
+  <div class="inner2"></div>
 </div>
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt_automation/pointerevents/pointerevent_common_input.js b/third_party/WebKit/LayoutTests/external/wpt_automation/pointerevents/pointerevent_common_input.js
index 50e9b52..5e3b1de 100644
--- a/third_party/WebKit/LayoutTests/external/wpt_automation/pointerevents/pointerevent_common_input.js
+++ b/third_party/WebKit/LayoutTests/external/wpt_automation/pointerevents/pointerevent_common_input.js
@@ -295,9 +295,12 @@
 // Pen inputs.
 function penMoveToDocument() {
   return new Promise(function(resolve, reject) {
-    if (window.eventSender) {
-      eventSender.mouseMoveTo(0, 0, [], "pen", 0);
-      resolve();
+    if (window.chrome && chrome.gpuBenchmarking) {
+      chrome.gpuBenchmarking.pointerActionSequence( [
+        {"source": "pen",
+         "actions": [
+            { "name": "pointerMove", "x": 0, "y": 0 }
+        ]}], resolve);
     } else {
       reject();
     }
@@ -315,11 +318,16 @@
     frameTop = frameRect.top;
   }
   return new Promise(function(resolve, reject) {
-    if (window.eventSender) {
+    if (window.chrome && chrome.gpuBenchmarking) {
       var target = targetDocument.querySelector(targetSelector);
       var targetRect = target.getBoundingClientRect();
-      eventSender.mouseMoveTo(frameLeft + targetRect.left + boundaryOffset, frameTop + targetRect.top + boundaryOffset, [], "pen", 0);
-      resolve();
+      var xPosition = frameLeft + targetRect.left + boundaryOffset;
+      var yPosition = frameTop + targetRect.top + boundaryOffset;
+      chrome.gpuBenchmarking.pointerActionSequence( [
+        {"source": "pen",
+         "actions": [
+            { "name": "pointerMove", "x": xPosition, "y": yPosition }
+        ]}], resolve);
     } else {
       reject();
     }
@@ -327,16 +335,32 @@
 }
 
 function penClickInTarget(targetSelector, targetFrame) {
-  return penMoveIntoTarget(targetSelector, targetFrame).then(function() {
-    return new Promise(function(resolve, reject) {
-      if (window.eventSender) {
-        eventSender.mouseDown(0, [], "pen", 0);
-        eventSender.mouseUp(0, [], "pen", 0);
-        resolve();
-      } else {
-        reject();
-      }
-    });
+  var targetDocument = document;
+  var frameLeft = 0;
+  var frameTop = 0;
+  if (targetFrame !== undefined) {
+    targetDocument = targetFrame.contentDocument;
+    var frameRect = targetFrame.getBoundingClientRect();
+    frameLeft = frameRect.left;
+    frameTop = frameRect.top;
+  }
+  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 = frameLeft + targetRect.left + boundaryOffset;
+      var yPosition = frameTop + targetRect.top + boundaryOffset;
+      chrome.gpuBenchmarking.pointerActionSequence( [
+        {"source": "pen",
+         "actions": [
+            { "name": "pointerMove", "x": xPosition, "y": yPosition },
+            { "name": "pointerDown", "x": xPosition, "y": yPosition },
+            { "name": "pointerUp" }
+        ]}], resolve);
+    } else {
+      reject();
+    }
   });
 }
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/preview-searchable.html b/third_party/WebKit/LayoutTests/http/tests/inspector/network/preview-searchable.html
index 415b6d9..f1ed3d8a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/preview-searchable.html
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/preview-searchable.html
@@ -14,10 +14,10 @@
             view.showSearchField();
             InspectorTest.addResult("Should have found and highlighted all: " + search);
 
-            var foundItems = view.element.querySelectorAll("* /deep/ .highlighted-search-result");
+            var foundItems = view.element.childTextNodes().filter(node => node.parentElement.classList.contains("highlighted-search-result")).map(node => node.parentElement);
             InspectorTest.addResult("Normal search found " + foundItems.length + " results in dom.");
 
-            foundItems = view.element.querySelectorAll("* /deep/ .cm-search-highlight-start");
+            foundItems = view.element.childTextNodes().filter(node => node.parentElement.classList.contains("cm-search-highlight-start")).map(node => node.parentElement);
             InspectorTest.addResult("CodeMirror search found " + foundItems.length + " results in dom.");
             InspectorTest.addResult("");
         }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/lazy-addeventlisteners-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/lazy-addeventlisteners-expected.txt
index 2cac6f7..9beb73e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/lazy-addeventlisteners-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/lazy-addeventlisteners-expected.txt
@@ -1,4 +1,4 @@
-Tests that a warining is shown in the console if addEventListner is called after initial evaluation of the service worker script.
+Tests that a warning is shown in the console if addEventListener is called after initial evaluation of the service worker script.
 
 Message count: 1
 service-worker-lazy-addeventlistener.js:2 Event handler of 'install' event must be added on the initial evaluation of worker script.
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/lazy-addeventlisteners.html b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/lazy-addeventlisteners.html
index 49e144a..1b53adb3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/lazy-addeventlisteners.html
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/lazy-addeventlisteners.html
@@ -17,6 +17,6 @@
 </script>
 </head>
 <body onload="runTest()">
-<p>Tests that a warining is shown in the console if addEventListner is called after initial evaluation of the service worker script.</p>
+<p>Tests that a warning is shown in the console if addEventListener is called after initial evaluation of the service worker script.</p>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-custom-formatters.html b/third_party/WebKit/LayoutTests/inspector/console/console-custom-formatters.html
index 19e2adc..5dbce49 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-custom-formatters.html
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-custom-formatters.html
@@ -142,7 +142,8 @@
         var viewMessages = consoleView._visibleViewMessages;
         for (var i = 0; i < viewMessages.length; ++i) {
             var uiMessage = viewMessages[i];
-            var customElement = uiMessage.contentElement().querySelector("span /deep/ .custom-expandable-section-header");
+            var shadowRoot = uiMessage.contentElement().querySelector(".console-message-text *").shadowRoot;
+            var customElement = shadowRoot ? shadowRoot.querySelector(".custom-expandable-section-header") : null;
             if (customElement)
                 customElement.click();
         }
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-edit-property-value.html b/third_party/WebKit/LayoutTests/inspector/console/console-edit-property-value.html
index b668804..afe9694 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-edit-property-value.html
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-edit-property-value.html
@@ -49,7 +49,7 @@
     function getValueElements()
     {
         var messageElement = Console.ConsoleView.instance()._visibleViewMessages[1].element();
-        return messageElement.querySelectorAll("::shadow .value");
+        return messageElement.querySelector(".console-message-text *").shadowRoot.querySelectorAll(".value");
     }
 
     function doubleClickTypeAndEnter(node, text)
@@ -61,7 +61,7 @@
         InspectorTest.addResult("Node was hidden after dblclick: " + node.classList.contains("hidden"));
 
         var messageElement = Console.ConsoleView.instance()._visibleViewMessages[1].element();
-        var editPrompt = messageElement.querySelector("::shadow .text-prompt");
+        var editPrompt = messageElement.querySelector(".console-message-text *").shadowRoot.querySelector(".text-prompt");
         editPrompt.textContent = text;
         editPrompt.dispatchEvent(InspectorTest.createKeyEvent("Enter"));
     }
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-filter-level-test-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-filter-level-test-expected.txt
index ebfc1e28..371444b 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-filter-level-test-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-filter-level-test-expected.txt
@@ -16,7 +16,6 @@
 >console-filter-level-test.html:6 sample log
 >console-filter-level-test.html:7 sample warning
 onload @ console-filter-level-test.html:7
->console-filter-level-test.html:8 sample debug
 >console-filter-level-test.html:9 sample error
 onload @ console-filter-level-test.html:9
 >console-filter-level-test.html:11 abc info
@@ -28,46 +27,72 @@
 >'Should be always visible'
 >"Should be always visible"
 
-Running: onlyWarning
->console-filter-level-test.html:7 sample warning
-onload @ console-filter-level-test.html:7
->console-filter-level-test.html:14 abc warn
-onload @ console-filter-level-test.html:14
->console-filter-level-test.html:15 def warn
-onload @ console-filter-level-test.html:15
->'Should be always visible'
->"Should be always visible"
-
-Running: onlyInfo
+Running: verbose
 >console-filter-level-test.html:5 sample info
 >console-filter-level-test.html:6 sample log
+>console-filter-level-test.html:7 sample warning
+onload @ console-filter-level-test.html:7
+>console-filter-level-test.html:8 sample debug
+>console-filter-level-test.html:9 sample error
+onload @ console-filter-level-test.html:9
 >console-filter-level-test.html:11 abc info
 >console-filter-level-test.html:12 def info
+>console-filter-level-test.html:14 abc warn
+onload @ console-filter-level-test.html:14
+>console-filter-level-test.html:15 def warn
+onload @ console-filter-level-test.html:15
 >'Should be always visible'
 >"Should be always visible"
 
-Running: onlyErrorDebug
->console-filter-level-test.html:8 sample debug
+Running: info
+>console-filter-level-test.html:5 sample info
+>console-filter-level-test.html:6 sample log
+>console-filter-level-test.html:7 sample warning
+onload @ console-filter-level-test.html:7
+>console-filter-level-test.html:9 sample error
+onload @ console-filter-level-test.html:9
+>console-filter-level-test.html:11 abc info
+>console-filter-level-test.html:12 def info
+>console-filter-level-test.html:14 abc warn
+onload @ console-filter-level-test.html:14
+>console-filter-level-test.html:15 def warn
+onload @ console-filter-level-test.html:15
+>'Should be always visible'
+>"Should be always visible"
+
+Running: warning
+>console-filter-level-test.html:7 sample warning
+onload @ console-filter-level-test.html:7
+>console-filter-level-test.html:9 sample error
+onload @ console-filter-level-test.html:9
+>console-filter-level-test.html:14 abc warn
+onload @ console-filter-level-test.html:14
+>console-filter-level-test.html:15 def warn
+onload @ console-filter-level-test.html:15
+>'Should be always visible'
+>"Should be always visible"
+
+Running: error
 >console-filter-level-test.html:9 sample error
 onload @ console-filter-level-test.html:9
 >'Should be always visible'
 >"Should be always visible"
 
-Running: onlyAbcMessagePlain
+Running: abcMessagePlain
 >console-filter-level-test.html:11 abc info
 >console-filter-level-test.html:14 abc warn
 onload @ console-filter-level-test.html:14
 >'Should be always visible'
 >"Should be always visible"
 
-Running: onlyAbcMessageRegex
+Running: abcMessageRegex
 >console-filter-level-test.html:11 abc info
 >console-filter-level-test.html:14 abc warn
 onload @ console-filter-level-test.html:14
 >'Should be always visible'
 >"Should be always visible"
 
-Running: onlyAbcMessageRegexWarning
+Running: abcMessageRegexWarning
 >console-filter-level-test.html:14 abc warn
 onload @ console-filter-level-test.html:14
 >'Should be always visible'
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-filter-level-test.html b/third_party/WebKit/LayoutTests/inspector/console/console-filter-level-test.html
index 52ac076c..e8e07e81 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-filter-level-test.html
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-filter-level-test.html
@@ -42,38 +42,44 @@
             dumpVisibleMessages();
             next();
         },
-        
-        function onlyWarning(next)
+
+        function verbose(next)
         {
-            Console.ConsoleView.instance()._filter._levelFilterUI._toggleTypeFilter("warning");
+            Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Verbose);
             dumpVisibleMessages();
             next();
         },
         
-        function onlyInfo(next)
+        function info(next)
         {
-            Console.ConsoleView.instance()._filter._levelFilterUI._toggleTypeFilter("info");
+            Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Info);
             dumpVisibleMessages();
             next();
         },
-        
-        function onlyErrorDebug(next)
+
+        function warning(next)
         {
-            Console.ConsoleView.instance()._filter._levelFilterUI._toggleTypeFilter("error");
-            Console.ConsoleView.instance()._filter._levelFilterUI._toggleTypeFilter("verbose", true);
+            Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Warning);
             dumpVisibleMessages();
             next();
         },
-        
-        function onlyAbcMessagePlain(next)
+              
+        function error(next)
         {
-            Console.ConsoleView.instance()._filter._levelFilterUI._toggleTypeFilter(UI.NamedBitSetFilterUI.ALL_TYPES);
+            Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Error);
+            dumpVisibleMessages();
+            next();
+        },
+       
+        function abcMessagePlain(next)
+        {
+            Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Verbose);
             Console.ConsoleView.instance()._filter._textFilterUI.setValue("abc");
             dumpVisibleMessages();
             next();
         },
         
-        function onlyAbcMessageRegex(next)
+        function abcMessageRegex(next)
         {
             Console.ConsoleView.instance()._filter._textFilterUI._regexCheckBox.checked = "checked";
             Console.ConsoleView.instance()._filter._textFilterUI.setValue("ab[a-z]");
@@ -81,9 +87,9 @@
             next();
         },
         
-        function onlyAbcMessageRegexWarning(next)
+        function abcMessageRegexWarning(next)
         {
-            Console.ConsoleView.instance()._filter._levelFilterUI._toggleTypeFilter("warning", false);
+            Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Warning);
             dumpVisibleMessages();
             next();
         }
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-log-before-inspector-open-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-log-before-inspector-open-expected.txt
index c7af7a2e..93dfd983 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-log-before-inspector-open-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-log-before-inspector-open-expected.txt
@@ -1,15 +1,13 @@
 CONSOLE MESSAGE: line 7: log
-CONSOLE DEBUG: line 8: debug
-CONSOLE MESSAGE: line 9: info
-CONSOLE WARNING: line 10: warn
-CONSOLE ERROR: line 11: error
+CONSOLE MESSAGE: line 8: info
+CONSOLE WARNING: line 9: warn
+CONSOLE ERROR: line 10: error
 Tests that Web Inspector won't crash if some console have been logged by the time it's opening.
 
 console-log-before-inspector-open.html:7 log
-console-log-before-inspector-open.html:8 debug
-console-log-before-inspector-open.html:9 info
-console-log-before-inspector-open.html:10 warn
+console-log-before-inspector-open.html:8 info
+console-log-before-inspector-open.html:9 warn
+(anonymous) @ console-log-before-inspector-open.html:9
+console-log-before-inspector-open.html:10 error
 (anonymous) @ console-log-before-inspector-open.html:10
-console-log-before-inspector-open.html:11 error
-(anonymous) @ console-log-before-inspector-open.html:11
 
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-log-before-inspector-open.html b/third_party/WebKit/LayoutTests/inspector/console/console-log-before-inspector-open.html
index 4a0042a..9316bc2 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-log-before-inspector-open.html
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-log-before-inspector-open.html
@@ -5,7 +5,6 @@
 <script>
 
 console.log('log');
-console.debug('debug');
 console.info('info');
 console.warn('warn');
 console.error('error');
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-on-paint-worklet-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-on-paint-worklet-expected.txt
index 066636c1..286caba8 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-on-paint-worklet-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-on-paint-worklet-expected.txt
@@ -1,13 +1,11 @@
-CONSOLE DEBUG: line 1: Debug
-CONSOLE MESSAGE: line 2: Information
-CONSOLE MESSAGE: line 3: Log
-CONSOLE WARNING: line 4: Warning
+CONSOLE MESSAGE: line 1: Information
+CONSOLE MESSAGE: line 2: Log
+CONSOLE WARNING: line 3: Warning
 Tests console output from PaintWorklet.
 
-Message count: 4
-console-worklet-script.js:1 Debug
-console-worklet-script.js:2 Information
-console-worklet-script.js:3 Log
-console-worklet-script.js:4 Warning
-(anonymous) @ console-worklet-script.js:4
+Message count: 3
+console-worklet-script.js:1 Information
+console-worklet-script.js:2 Log
+console-worklet-script.js:3 Warning
+(anonymous) @ console-worklet-script.js:3
 
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-on-paint-worklet.html b/third_party/WebKit/LayoutTests/inspector/console/console-on-paint-worklet.html
index 0f93086..3565c06 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-on-paint-worklet.html
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-on-paint-worklet.html
@@ -10,7 +10,7 @@
 
 function test()
 {
-    InspectorTest.waitForConsoleMessages(4, finish);
+    InspectorTest.waitForConsoleMessages(3, finish);
     InspectorTest.evaluateInPage("importWorklet();");
 
     function finish()
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-search.html b/third_party/WebKit/LayoutTests/inspector/console/console-search.html
index 125cc27..5720458 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-search.html
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-search.html
@@ -43,7 +43,7 @@
 
     function dumpMatches()
     {
-        var matches = document.querySelectorAll("html /deep/ .highlighted-search-result");
+        var matches = consoleView.element.childTextNodes().filter(node => node.parentElement.classList.contains("highlighted-search-result")).map(node => node.parentElement);
         addResult("number of visible matches: " + matches.length);
         for (var i = 0; i < matches.length; ++i)
             addResult("  match " + i + ": " + matches[i].className);
@@ -164,8 +164,8 @@
             function dumpElements(callback)
             {
                 consoleView._searchableView.handleFindNextShortcut();
-                var currentResultElem = document.querySelector("html /deep/ .current-search-result");
-                addResult("matched tree element: " + currentResultElem.innerHTML);
+                var currentResultElem = consoleView.element.childTextNodes().filter(node => node.parentElement.classList.contains("current-search-result"))[0];
+                addResult("matched tree element: " + currentResultElem.textContent);
                 callback();
             }
 
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-tests.html b/third_party/WebKit/LayoutTests/inspector/console/console-tests.html
index 49c1b61..d4b1600 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-tests.html
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-tests.html
@@ -42,6 +42,7 @@
 
 function test()
 {
+    Common.settings.settingForTest('messageLevelFilters2').set(SDK.ConsoleMessage.MessageLevel.Verbose);
     InspectorTest.dumpConsoleMessagesWithClasses();
     InspectorTest.completeTest();
 }
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-worklet-script.js b/third_party/WebKit/LayoutTests/inspector/console/console-worklet-script.js
index 43b144bb..8223cd6 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-worklet-script.js
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-worklet-script.js
@@ -1,4 +1,3 @@
-console.debug('Debug');
 console.info('Information');
 console.log('Log');
 console.warn('Warning');
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/async-call-stack-async-function-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/async-call-stack-async-function-expected.txt
index 6d1f7dd..11c0a34d 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/async-call-stack-async-function-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/async-call-stack-async-function-expected.txt
@@ -2,10 +2,11 @@
 
 Set timer for test function.
 footest.js:6
-boo awaits foo
+boo awaits foocreated:  test.js:2
 bootest.js:12
-testFunction awaits boo
+testFunction awaits boocreated:  test.js:9
 testFunctiontest.js:18
+async function (async)created:  test.js:15
 setTimeout (async)
 scheduleTestFunctiondebugger-test.js:3
 (anonymous)VM:1
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png
index 5bf76a4c..6dbf80f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.txt
index 969aba85..2dbefdb 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.txt
@@ -4,41 +4,26 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x196
     LayoutBlockFlow {BODY} at (8,16) size 784x164
       LayoutBlockFlow {P} at (0,0) size 784x20
-        + RootInlineBox {LayoutBlockFlow P} pos=(0.00,0.00) size=(486.84,19.00) baseline=15/10
-          + InlineTextBox {LayoutText #text} pos=(0.00,0.00) size=(486.84,19.00) baseline=15/10 range=(0,82) "crbug.com/645938: Text in an rtl flow with a list marker should truncate properly."
         LayoutText {#text} at (0,0) size 487x19
           text run at (0,0) width 487: "crbug.com/645938: Text in an rtl flow with a list marker should truncate properly."
       LayoutBlockFlow {P} at (0,36) size 784x20
-        + RootInlineBox {LayoutBlockFlow P} pos=(0.00,0.00) size=(337.34,19.00) baseline=15/10
-          + InlineTextBox {LayoutText #text} pos=(0.00,0.00) size=(107.39,19.00) baseline=15/10 range=(0,18) "You should see ..."
-          + InlineTextBox {LayoutText #text} pos=(107.39,0.00) size=(183.00,19.00) baseline=15/10 range=(18,47) "הנקרא לפעמים גם דמי טקסט או ג"
-          + InlineTextBox {LayoutText #text} pos=(290.39,0.00) size=(46.95,19.00) baseline=15/10 range=(47,55) "' below."
         LayoutText {#text} at (0,0) size 338x19
           text run at (0,0) width 108: "You should see ..."
           text run at (107,0) width 184 RTL: "\x{5D4}\x{5E0}\x{5E7}\x{5E8}\x{5D0} \x{5DC}\x{5E4}\x{5E2}\x{5DE}\x{5D9}\x{5DD} \x{5D2}\x{5DD} \x{5D3}\x{5DE}\x{5D9} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5D5} \x{5D2}"
           text run at (290,0) width 48: "' below."
       LayoutBlockFlow {OL} at (0,72) size 784x20
       LayoutBlockFlow {P} at (0,108) size 784x20
-        + RootInlineBox {LayoutBlockFlow P} pos=(0.00,0.00) size=(326.36,19.00) baseline=15/10
-          + InlineTextBox {LayoutText #text} pos=(0.00,0.00) size=(326.36,19.00) baseline=15/10 range=(0,55) "You should see ...ajdklasd jsakldsja dsjjkl dsjk below."
         LayoutText {#text} at (0,0) size 327x19
           text run at (0,0) width 327: "You should see ...ajdklasd jsakldsja dsjjkl dsjk below."
       LayoutBlockFlow {OL} at (0,144) size 784x20
 layer at (48,88) size 200x20 scrollX 147.00 scrollWidth 347
   LayoutListItem {LI} at (40,0) size 200x20
-    + RootInlineBox {LayoutListItem LI class='case'} pos=(-147.00,0.00) size=(347.00,19.00) baseline=15/10
-      + InlineTextBox {LayoutText #text} pos=(-147.00,0.00) size=(124.00,19.00) baseline=15/10 range=(37,56) "עד שיהיה טקסט אמיתי"
-      + InlineTextBox {LayoutText #text} pos=(-23.00,0.00) size=(223.00,19.00) baseline=15/10 range=(0,36) "הנקרא לפעמים גם דמי טקסט או ג'יבריש "
-      + InlineBox {LayoutListMarker (anonymous)} pos=(200.00,0.00) size=(16.00,19.00) baseline=15/10
     LayoutListMarker (anonymous) at (200,0) size 16x19: "1"
     LayoutText {#text} at (-147,0) size 347x19
       text run at (-147,0) width 124 RTL: "\x{5E2}\x{5D3} \x{5E9}\x{5D9}\x{5D4}\x{5D9}\x{5D4} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5DE}\x{5D9}\x{5EA}\x{5D9}"
       text run at (-23,0) width 223 RTL: "\x{5D4}\x{5E0}\x{5E7}\x{5E8}\x{5D0} \x{5DC}\x{5E4}\x{5E2}\x{5DE}\x{5D9}\x{5DD} \x{5D2}\x{5DD} \x{5D3}\x{5DE}\x{5D9} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5D5} \x{5D2}'\x{5D9}\x{5D1}\x{5E8}\x{5D9}\x{5E9} "
 layer at (48,160) size 200x20 scrollX 189.00 scrollWidth 389
   LayoutListItem {LI} at (40,0) size 200x20
-    + RootInlineBox {LayoutListItem LI class='case'} pos=(-189.00,0.00) size=(389.00,19.00) baseline=15/10
-      + InlineTextBox {LayoutText #text} pos=(-189.00,0.00) size=(389.00,19.00) baseline=15/10 range=(0,67) "dsajkl dsjakld sajkld asjkld sajklds ajdklasd jsakldsja dsjjkl dsjk"
-      + InlineBox {LayoutListMarker (anonymous)} pos=(200.00,0.00) size=(16.00,19.00) baseline=15/10
     LayoutListMarker (anonymous) at (200,0) size 16x19: "1"
     LayoutText {#text} at (-189,0) size 389x19
       text run at (-189,0) width 389: "dsajkl dsjakld sajkld asjkld sajklds ajdklasd jsakldsja dsjjkl dsjk"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.png
new file mode 100644
index 0000000..507963b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png
new file mode 100644
index 0000000..adbc1e0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.png
new file mode 100644
index 0000000..9e567f3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png
new file mode 100644
index 0000000..0fecc18
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.png
new file mode 100644
index 0000000..ed021e74
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.txt
new file mode 100644
index 0000000..a53ea2f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.txt
@@ -0,0 +1,29 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x188
+  LayoutBlockFlow {HTML} at (0,0) size 800x188
+    LayoutBlockFlow {BODY} at (8,16) size 784x156
+      LayoutBlockFlow {P} at (0,0) size 784x18
+        LayoutText {#text} at (0,0) size 524x18
+          text run at (0,0) width 524: "crbug.com/645938: Text in an ltr flow with a list marker should truncate properly."
+      LayoutBlockFlow {P} at (0,34) size 784x19
+        LayoutText {#text} at (0,1) size 390x18
+          text run at (0,1) width 102: "You should see "
+          text run at (101,1) width 231 RTL: "\x{5D0}\x{5D5} \x{5D2}'\x{5D9}\x{5D1}\x{5E8}\x{5D9}\x{5E9} \x{5E2}\x{5D3} \x{5E9}\x{5D9}\x{5D4}\x{5D9}\x{5D4} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5DE}\x{5D9}\x{5EA}\x{5D9}"
+          text run at (331,1) width 59: "... below."
+      LayoutBlockFlow {OL} at (0,69) size 784x19
+      LayoutBlockFlow {P} at (0,104) size 784x18
+        LayoutText {#text} at (0,0) size 343x18
+          text run at (0,0) width 343: "You should see dsajkl dsjakld sajkld asjkld s... below."
+      LayoutBlockFlow {OL} at (0,138) size 784x18
+layer at (48,85) size 200x19 scrollWidth 436
+  LayoutListItem {LI} at (40,0) size 200x19
+    LayoutListMarker (anonymous) at (-16,1) size 16x18: "1"
+    LayoutText {#text} at (0,1) size 437x18
+      text run at (0,1) width 159 RTL: "\x{5E2}\x{5D3} \x{5E9}\x{5D9}\x{5D4}\x{5D9}\x{5D4} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5DE}\x{5D9}\x{5EA}\x{5D9}"
+      text run at (158,1) width 279 RTL: "\x{5D4}\x{5E0}\x{5E7}\x{5E8}\x{5D0} \x{5DC}\x{5E4}\x{5E2}\x{5DE}\x{5D9}\x{5DD} \x{5D2}\x{5DD} \x{5D3}\x{5DE}\x{5D9} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5D5} \x{5D2}'\x{5D9}\x{5D1}\x{5E8}\x{5D9}\x{5E9} "
+layer at (48,154) size 200x18 scrollWidth 409
+  LayoutListItem {LI} at (40,0) size 200x18
+    LayoutListMarker (anonymous) at (-16,0) size 16x18: "1"
+    LayoutText {#text} at (0,0) size 409x18
+      text run at (0,0) width 409: "dsajkl dsjakld sajkld asjkld sajklds ajdklasd jsakldsja dsjjkl dsjk"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png
new file mode 100644
index 0000000..6706f44
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.txt
new file mode 100644
index 0000000..eb0e82634
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.txt
@@ -0,0 +1,29 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x188
+  LayoutBlockFlow {HTML} at (0,0) size 800x188
+    LayoutBlockFlow {BODY} at (8,16) size 784x156
+      LayoutBlockFlow {P} at (0,0) size 784x18
+        LayoutText {#text} at (0,0) size 524x18
+          text run at (0,0) width 524: "crbug.com/645938: Text in an rtl flow with a list marker should truncate properly."
+      LayoutBlockFlow {P} at (0,34) size 784x19
+        LayoutText {#text} at (0,1) size 395x18
+          text run at (0,1) width 114: "You should see ..."
+          text run at (113,1) width 233 RTL: "\x{5D4}\x{5E0}\x{5E7}\x{5E8}\x{5D0} \x{5DC}\x{5E4}\x{5E2}\x{5DE}\x{5D9}\x{5DD} \x{5D2}\x{5DD} \x{5D3}\x{5DE}\x{5D9} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5D5} \x{5D2}"
+          text run at (345,1) width 50: "' below."
+      LayoutBlockFlow {OL} at (0,69) size 784x19
+      LayoutBlockFlow {P} at (0,104) size 784x18
+        LayoutText {#text} at (0,0) size 343x18
+          text run at (0,0) width 343: "You should see ...ajdklasd jsakldsja dsjjkl dsjk below."
+      LayoutBlockFlow {OL} at (0,138) size 784x18
+layer at (48,85) size 200x19 scrollX 236.00 scrollWidth 436
+  LayoutListItem {LI} at (40,0) size 200x19
+    LayoutListMarker (anonymous) at (200,1) size 16x18: "1"
+    LayoutText {#text} at (-236,1) size 437x18
+      text run at (-236,1) width 159 RTL: "\x{5E2}\x{5D3} \x{5E9}\x{5D9}\x{5D4}\x{5D9}\x{5D4} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5DE}\x{5D9}\x{5EA}\x{5D9}"
+      text run at (-77,1) width 277 RTL: "\x{5D4}\x{5E0}\x{5E7}\x{5E8}\x{5D0} \x{5DC}\x{5E4}\x{5E2}\x{5DE}\x{5D9}\x{5DD} \x{5D2}\x{5DD} \x{5D3}\x{5DE}\x{5D9} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5D5} \x{5D2}'\x{5D9}\x{5D1}\x{5E8}\x{5D9}\x{5E9} "
+layer at (48,154) size 200x18 scrollX 208.00 scrollWidth 409
+  LayoutListItem {LI} at (40,0) size 200x18
+    LayoutListMarker (anonymous) at (200,0) size 16x18: "1"
+    LayoutText {#text} at (-208,0) size 409x18
+      text run at (-208,0) width 408: "dsajkl dsjakld sajkld asjkld sajklds ajdklasd jsakldsja dsjjkl dsjk"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.png
new file mode 100644
index 0000000..638e302
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.txt
new file mode 100644
index 0000000..f3fe7f9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-with-list-marker-in-ltr-flow-expected.txt
@@ -0,0 +1,29 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x186
+  LayoutBlockFlow {HTML} at (0,0) size 800x186
+    LayoutBlockFlow {BODY} at (8,16) size 784x154
+      LayoutBlockFlow {P} at (0,0) size 784x18
+        LayoutText {#text} at (0,0) size 524x17
+          text run at (0,0) width 524: "crbug.com/645938: Text in an ltr flow with a list marker should truncate properly."
+      LayoutBlockFlow {P} at (0,34) size 784x18
+        LayoutText {#text} at (0,0) size 343x17
+          text run at (0,0) width 102: "You should see "
+          text run at (101,0) width 184 RTL: "\x{5D0}\x{5D5} \x{5D2}'\x{5D9}\x{5D1}\x{5E8}\x{5D9}\x{5E9} \x{5E2}\x{5D3} \x{5E9}\x{5D9}\x{5D4}\x{5D9}\x{5D4} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5DE}\x{5D9}\x{5EA}\x{5D9}"
+          text run at (284,0) width 59: "... below."
+      LayoutBlockFlow {OL} at (0,68) size 784x18
+      LayoutBlockFlow {P} at (0,102) size 784x18
+        LayoutText {#text} at (0,0) size 343x17
+          text run at (0,0) width 343: "You should see dsajkl dsjakld sajkld asjkld s... below."
+      LayoutBlockFlow {OL} at (0,136) size 784x18
+layer at (48,84) size 200x18 scrollWidth 342
+  LayoutListItem {LI} at (40,0) size 200x18
+    LayoutListMarker (anonymous) at (-16,0) size 16x17: "1"
+    LayoutText {#text} at (0,0) size 343x17
+      text run at (0,0) width 122 RTL: "\x{5E2}\x{5D3} \x{5E9}\x{5D9}\x{5D4}\x{5D9}\x{5D4} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5DE}\x{5D9}\x{5EA}\x{5D9}"
+      text run at (121,0) width 222 RTL: "\x{5D4}\x{5E0}\x{5E7}\x{5E8}\x{5D0} \x{5DC}\x{5E4}\x{5E2}\x{5DE}\x{5D9}\x{5DD} \x{5D2}\x{5DD} \x{5D3}\x{5DE}\x{5D9} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5D5} \x{5D2}'\x{5D9}\x{5D1}\x{5E8}\x{5D9}\x{5E9} "
+layer at (48,152) size 200x18 scrollWidth 409
+  LayoutListItem {LI} at (40,0) size 200x18
+    LayoutListMarker (anonymous) at (-16,0) size 16x17: "1"
+    LayoutText {#text} at (0,0) size 409x17
+      text run at (0,0) width 409: "dsajkl dsjakld sajkld asjkld sajklds ajdklasd jsakldsja dsjjkl dsjk"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png
new file mode 100644
index 0000000..6500867
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.txt
new file mode 100644
index 0000000..d7dd652a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-with-list-marker-in-rtl-flow-expected.txt
@@ -0,0 +1,29 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x186
+  LayoutBlockFlow {HTML} at (0,0) size 800x186
+    LayoutBlockFlow {BODY} at (8,16) size 784x154
+      LayoutBlockFlow {P} at (0,0) size 784x18
+        LayoutText {#text} at (0,0) size 524x17
+          text run at (0,0) width 524: "crbug.com/645938: Text in an rtl flow with a list marker should truncate properly."
+      LayoutBlockFlow {P} at (0,34) size 784x18
+        LayoutText {#text} at (0,0) size 343x17
+          text run at (0,0) width 114: "You should see ..."
+          text run at (113,0) width 181 RTL: "\x{5D4}\x{5E0}\x{5E7}\x{5E8}\x{5D0} \x{5DC}\x{5E4}\x{5E2}\x{5DE}\x{5D9}\x{5DD} \x{5D2}\x{5DD} \x{5D3}\x{5DE}\x{5D9} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5D5} \x{5D2}"
+          text run at (293,0) width 50: "' below."
+      LayoutBlockFlow {OL} at (0,68) size 784x18
+      LayoutBlockFlow {P} at (0,102) size 784x18
+        LayoutText {#text} at (0,0) size 343x17
+          text run at (0,0) width 343: "You should see ...ajdklasd jsakldsja dsjjkl dsjk below."
+      LayoutBlockFlow {OL} at (0,136) size 784x18
+layer at (48,84) size 200x18 scrollX 142.00 scrollWidth 342
+  LayoutListItem {LI} at (40,0) size 200x18
+    LayoutListMarker (anonymous) at (200,0) size 16x17: "1"
+    LayoutText {#text} at (-142,0) size 343x17
+      text run at (-142,0) width 122 RTL: "\x{5E2}\x{5D3} \x{5E9}\x{5D9}\x{5D4}\x{5D9}\x{5D4} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5DE}\x{5D9}\x{5EA}\x{5D9}"
+      text run at (-20,0) width 220 RTL: "\x{5D4}\x{5E0}\x{5E7}\x{5E8}\x{5D0} \x{5DC}\x{5E4}\x{5E2}\x{5DE}\x{5D9}\x{5DD} \x{5D2}\x{5DD} \x{5D3}\x{5DE}\x{5D9} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5D0}\x{5D5} \x{5D2}'\x{5D9}\x{5D1}\x{5E8}\x{5D9}\x{5E9} "
+layer at (48,152) size 200x18 scrollX 208.00 scrollWidth 409
+  LayoutListItem {LI} at (40,0) size 200x18
+    LayoutListMarker (anonymous) at (200,0) size 16x17: "1"
+    LayoutText {#text} at (-208,0) size 409x17
+      text run at (-208,0) width 408: "dsajkl dsjakld sajkld asjkld sajklds ajdklasd jsakldsja dsjjkl dsjk"
diff --git a/third_party/WebKit/LayoutTests/resources/bluetooth/connect-iframe.html b/third_party/WebKit/LayoutTests/resources/bluetooth/connect-iframe.html
deleted file mode 100644
index 09eb9f2..0000000
--- a/third_party/WebKit/LayoutTests/resources/bluetooth/connect-iframe.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<script>
-  window.onmessage = messageEvent => {
-    if (messageEvent.data === 'Go') {
-      navigator.bluetooth.requestDevice({
-        filters: [{services: ['heart_rate']}]
-      })
-      .then(device => device.gatt.connect())
-      .then(gattServer => {
-        parent.postMessage('Connected', '*');
-      }).catch(err => {
-        console.error(err);
-        parent.postMessage('FAIL: ' + err, '*');
-      });
-    }
-  };
-  parent.postMessage("Ready", "*");
-</script>
diff --git a/third_party/WebKit/LayoutTests/resources/bluetooth/heart-rate-iframe.html b/third_party/WebKit/LayoutTests/resources/bluetooth/heart-rate-iframe.html
new file mode 100644
index 0000000..4f1442a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/resources/bluetooth/heart-rate-iframe.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<script>
+  let device;
+  window.onmessage = messageEvent => {
+    if (messageEvent.data === 'RequestAndConnect') {
+      navigator.bluetooth.requestDevice({
+        filters: [{services: ['heart_rate']}]
+      })
+      .then(device => device.gatt.connect())
+      .then(gattServer => {
+        device = gattServer.device;
+        parent.postMessage('Connected', '*');
+      }).catch(err => {
+        console.error(err);
+        parent.postMessage('FAIL: ' + err, '*');
+      });
+    } else if (messageEvent.data === 'StartNotifications') {
+      device.gatt.getPrimaryService('heart_rate')
+        .then(service => service.getCharacteristic('heart_rate_measurement'))
+        .then(char => char.startNotifications())
+        .then(char => {
+          char.addEventListener('characteristicvaluechanged', function() {});
+          parent.postMessage('NotificationsStarted', '*');
+        });
+    }
+  };
+  parent.postMessage("Ready", "*");
+</script>
diff --git a/third_party/WebKit/LayoutTests/screen_orientation/orientationchange-event-subframe.html b/third_party/WebKit/LayoutTests/screen_orientation/orientationchange-event-subframe.html
index d26090b..0e19bbb 100644
--- a/third_party/WebKit/LayoutTests/screen_orientation/orientationchange-event-subframe.html
+++ b/third_party/WebKit/LayoutTests/screen_orientation/orientationchange-event-subframe.html
@@ -17,7 +17,7 @@
         'landscape-secondary'
     ];
 
-    var currentIndex = orientations.indexOf(window.screen.orientation.type);
+    var currentIndex = 0;  // Default orientation for testRunner is 'portrait-primary'.
     var eventsReceived = 0;
 
     function getNextIndex() {
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-automation-clamping-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-automation-clamping-expected.txt
index a39e6a8..648c31d 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-automation-clamping-expected.txt
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-automation-clamping-expected.txt
@@ -1,14 +1,8 @@
-CONSOLE WARNING: line 49: BiquadFilter.frequency.linearRampToValueAtTime value -1000 outside nominal range [0, 24000]; value will be clamped.
-Test Clamping of Automations.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS Clamped signal in frame range [5618, 18382] equals [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...] with an element-wise tolerance of 0.
-PASS Actual Clamp start (5618) is less than or equal to 5618.
-PASS Actual Clamp end (18383) is greater than or equal to 18382.
-PASS Clamping of BiquadFilter.frequency automation performed correctly.
-PASS successfullyParsed is true
-
-TEST COMPLETE
+CONSOLE WARNING: line 48: BiquadFilter.frequency.linearRampToValueAtTime value -1000 outside nominal range [0, 24000]; value will be clamped.
+This is a testharness.js-based test.
+PASS Clamped signal in frame range [5618, 18382] equals [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...] with an element-wise tolerance of 0. 
+PASS Actual Clamp start (5618) is less than or equal to 5618. 
+PASS Actual Clamp end (18383) is greater than or equal to 18382. 
+PASS Clamping of BiquadFilter.frequency automation performed correctly. 
+Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-automation-clamping.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-automation-clamping.html
index d7caa05..822cda7 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-automation-clamping.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-automation-clamping.html
@@ -1,7 +1,8 @@
 <!doctype html>
 <html>
   <head>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
     <title>Test Clamping of Automations</title>
@@ -9,8 +10,6 @@
 
   <body>
     <script>
-      description("Test Clamping of Automations.");
-      window.jsTestIsAsync = true;
 
       // Some arbitrary sample rate for the offline context. 
       var sampleRate = 48000;
@@ -94,18 +93,14 @@
           success == Should("Actual Clamp end",
             actualClampEnd).beGreaterThanOrEqualTo(clampEndFrame) && success;
 
-          if (success)
-            testPassed("Clamping of BiquadFilter.frequency automation performed correctly.")
-          else
-            testFailed(
-              "Clamping of BiquadFilter.frequency automation performed incorrectly.")
-
+          Should("Clamping of BiquadFilter.frequency automation performed",
+              success)
+            .summarize("correctly", "incorrectly");
         }).then(done);
       });
 
       // All done!
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-initial-event-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-initial-event-expected.txt
deleted file mode 100644
index 94e05e06..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-initial-event-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-Test Automation Ramps without Initial Event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS Linear ramp equals [0.5,0.4998958333333333,0.4997916666666667,0.4996875,0.4995833333333333,0.49947916666666664,0.499375,0.49927083333333333,0.49916666666666665,0.4990625,0.49895833333333334,0.49885416666666665,0.49875,0.49864583333333334,0.49854166666666666,0.4984375,...] with an element-wise tolerance of 6.0003e-8.
-PASS Exponential ramp equals [0.5,0.5001444220542908,0.5002889037132263,0.5004333853721619,0.5005779266357422,0.5007225275039673,0.5008671879768372,0.501011848449707,0.5011565685272217,0.5013013482093811,0.5014461278915405,0.5015909671783447,0.5017358660697937,0.5018808245658875,0.5020257830619812,0.5021708011627197,...] with an element-wise tolerance of 0.0000023842.
-PASS Delayed linear ramp equals [0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,...] with an element-wise tolerance of 9.87968e-8.
-PASS Delayed exponential ramp equals [0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,...] with an element-wise tolerance of 0.000013948.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
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 db6c382..c6399fd6 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-initial-event.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-initial-event.html
@@ -2,7 +2,8 @@
 <html>
 
 <head>
-  <script src="../../resources/js-test.js"></script>
+  <script src="../../resources/testharness.js"></script>
+  <script src="../../resources/testharnessreport.js"></script> 
   <script src="../resources/audit-util.js"></script>
   <script src="../resources/audio-testing.js"></script>
   <script src="../resources/audioparam-testing.js"></script>
@@ -11,8 +12,6 @@
 
 <body>
   <script>
-    description("Test Automation Ramps without Initial Event");
-    window.jsTestIsAsync = true;
 
     var sampleRate = 48000;
     // Number of frames in a rendering quantum.
@@ -92,7 +91,6 @@
     });
 
     audit.defineTask("finish", function (done) {
-      finishJSTest();
       done();
     });
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-large-endtime-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-large-endtime-expected.txt
deleted file mode 100644
index a05bba44..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-large-endtime-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-Test AudioParam with Huge Time Value
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS linearRampToValue(0.1, 1e+300) successfully rendered.
-PASS exponentialRampToValue(0.1, 1e+300) successfully rendered.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-large-endtime.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-large-endtime.html
index f97527aa5..0951d34 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-large-endtime.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-large-endtime.html
@@ -1,7 +1,8 @@
 <!doctype html>
 <html>
   <head>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
     <title>AudioParam with Huge End Time</title>
@@ -9,9 +10,6 @@
 
   <body>
     <script>
-      description("Test AudioParam with Huge Time Value")
-      window.jsTestIsAsync = true;
-
       var sampleRate = 48000;
       // Render for some small (but fairly arbitrary) time.
       var renderDuration = 0.125;
@@ -30,7 +28,9 @@
 
         graph.source.start();
         graph.context.startRendering().then(function (buffer) {
-          testPassed("linearRampToValue(0.1, " + largeTime + ") successfully rendered.");
+          Should("linearRampToValue(0.1, " + largeTime + ")", true)
+            .summarize("successfully rendered",
+                       "unsuccessfully rendered");
         }).then(done);
       });
 
@@ -41,12 +41,13 @@
 
         graph.source.start();
         graph.context.startRendering().then(function (buffer) {
-          testPassed("exponentialRampToValue(0.1, " + largeTime + ") successfully rendered.");
+          Should("exponentialRampToValue(0.1, " + largeTime + ")", true)
+            .summarize("successfully rendered",
+                       "unsuccessfully rendered");
         }).then(done);
       });
 
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-linearRamp-value-attribute-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-linearRamp-value-attribute-expected.txt
deleted file mode 100644
index d5ef99a..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-linearRamp-value-attribute-expected.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-Test linearRampToValue Updates the Param Value
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS gain.gain.value at frame 127 is equal to 0.06201171875.
-PASS gain.gain.value at frame 255 is equal to 0.12451171875.
-PASS gain.gain.value at frame 383 is equal to 0.18701171875.
-PASS gain.gain.value at frame 511 is equal to 0.24951171875.
-PASS gain.gain.value at frame 639 is equal to 0.31201171875.
-PASS gain.gain.value at frame 767 is equal to 0.37451171875.
-PASS gain.gain.value at frame 895 is equal to 0.43701171875.
-PASS gain.gain.value at frame 1023 is equal to 0.49951171875.
-PASS gain.gain.value at frame 1151 is equal to 0.56201171875.
-PASS gain.gain.value at frame 1279 is equal to 0.62451171875.
-PASS gain.gain.value at frame 1407 is equal to 0.68701171875.
-PASS gain.gain.value at frame 1535 is equal to 0.74951171875.
-PASS gain.gain.value at frame 1663 is equal to 0.81201171875.
-PASS gain.gain.value at frame 1791 is equal to 0.87451171875.
-PASS gain.gain.value at frame 1919 is equal to 0.93701171875.
-PASS gain.gain.value at frame 2047 is equal to 0.99951171875.
-PASS gain.gain.value at frame 2175 is equal to 1.
-PASS gain.gain.value at frame 2303 is equal to 1.
-PASS gain.gain.value at frame 2431 is equal to 1.
-PASS gain.gain.value at frame 2559 is equal to 1.
-PASS gain.gain.value at frame 2687 is equal to 1.
-PASS gain.gain.value at frame 2815 is equal to 1.
-PASS gain.gain.value at frame 2943 is equal to 1.
-PASS gain.gain.value at frame 3071 is equal to 1.
-PASS gain.gain.value at frame 3199 is equal to 1.
-PASS gain.gain.value at frame 3327 is equal to 1.
-PASS gain.gain.value at frame 3455 is equal to 1.
-PASS gain.gain.value at frame 3583 is equal to 1.
-PASS gain.gain.value at frame 3711 is equal to 1.
-PASS gain.gain.value at frame 3839 is equal to 1.
-PASS gain.gain.value at frame 3967 is equal to 1.
-PASS linearRampToValue properly set the AudioParam value.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-linearRamp-value-attribute.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-linearRamp-value-attribute.html
index fd27bbc..8e58e690 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-linearRamp-value-attribute.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-linearRamp-value-attribute.html
@@ -2,15 +2,14 @@
 <html>
   <head>
     <title>Test linearRampToValue Updates the Param Value</title>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
   </head>
 
   <body>
     <script>
-      description("Test linearRampToValue Updates the Param Value");
-      window.jsTestIsAsync = true;
 
       var renderQuantumSize = 128;
       // Should be a power of two to get rid of rounding errors when converting between time and
@@ -70,15 +69,13 @@
         // Rock and roll!
         source.start();
         context.startRendering().then(function (result) {
-          if (success)
-            testPassed("linearRampToValue properly set the AudioParam value.");
-          else
-            testFailed("linearRampToValue did not properly set the AudioParam value.");
+          Should("linearRampToValue", success)
+            .summarize("properly set the AudioParam value",
+                       "did not properly set the AudioParam value");
         }).then(done);
       });
 
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-method-chaining-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-method-chaining-expected.txt
deleted file mode 100644
index 5802c1e..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-method-chaining-expected.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Test method chaining feature of AudioParam automation methods.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS The return value of AudioParam.setValueAtTime() matches the source AudioParam.
-PASS The return value of AudioParam.linearRampToValueAtTime() matches the source AudioParam.
-PASS The return value of AudioParam.exponentialRampToValueAtTime() matches the source AudioParam.
-PASS The return value of AudioParam.setTargetAtTime() matches the source AudioParam.
-PASS The return value of AudioParam.setValueCurveAtTime() matches the source AudioParam.
-PASS The return value of AudioParam.cancelScheduledValues() matches the source AudioParam.
-PASS Calling setValueAtTime() with a negative end time threw InvalidAccessError: Failed to execute 'setValueAtTime' on 'AudioParam': Time must be a finite non-negative number: -1.
-PASS Calling exponentialRampToValueAtTime() with a zero target value threw InvalidAccessError: Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (0) should not be in the range (-1.40130e-45, 1.40130e-45)..
-PASS The gain value of the first gain node is equal to 1.
-PASS The gain value of the second gain node is equal to 0.5.
-PASS The rendered envelope equals [0,0.000022675736961451248,0.000045351473922902495,0.00006802721088435374,0.00009070294784580499,...] with an element-wise tolerance of 0.0000040532.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-method-chaining.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-method-chaining.html
index 0fac244..f3195add 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-method-chaining.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-method-chaining.html
@@ -2,7 +2,8 @@
 <html>
 
 <head>
-  <script src="../../resources/js-test.js"></script>
+  <script src="../../resources/testharness.js"></script>
+  <script src="../../resources/testharnessreport.js"></script> 
   <script src="../resources/audit-util.js"></script>
   <script src="../resources/audio-testing.js"></script>
   <script src="../resources/audioparam-testing.js"></script>
@@ -10,8 +11,6 @@
 
 <body>
   <script>
-    description('Test method chaining feature of AudioParam automation methods.');
-    window.jsTestIsAsync = true;
 
     var sampleRate = 44100;
 
@@ -29,10 +28,9 @@
     ];
 
     function verifyReturnedParam(config) {
-      if (config.source === config.returned)
-        testPassed('The return value of ' + config.desc + ' matches the source AudioParam.');
-      else
-        testFailed('The return value of ' + config.desc + ' does NOT match source AudioParam.');
+      Should('The return value of ' + config.desc + ' matches the source AudioParam',
+             config.source === config.returned)
+        .beEqualTo(true);
     }
 
     var audit = Audit.createTaskRunner();
@@ -131,7 +129,6 @@
     });
 
     audit.defineTask('finish', function (done) {
-      finishJSTest();
       done();
     });
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-negative-exponentialRamp-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-negative-exponentialRamp-expected.txt
deleted file mode 100644
index e2483a5..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-negative-exponentialRamp-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-Test AudioParam.exponentialRampToValueAtTime() with Negative Values.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS Negative exponential ramp from -1 to -2 is identical to the array [-1,-1.0001155138015747,-1.0002310276031494,-1.0003465414047241,-1.0004620552062988,-1.0005775690078735,-1.0006932020187378,-1.000808835029602,-1.0009244680404663,-1.0010401010513306,-1.0011557340621948,-1.001271367073059,-1.0013870000839233,-1.0015026330947876,-1.0016182661056519,-1.0017340183258057,...].
-PASS Exponential ramp from 2 to -1 contains only the constant 2.
-PASS Exponential ramp from -1 to 1 contains only the constant -1.
-PASS Exponential ramp from -1 to 1 after the end of the linear ramp contains only the constant -1.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-negative-exponentialRamp.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-negative-exponentialRamp.html
index d74819b..fa889485 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-negative-exponentialRamp.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-negative-exponentialRamp.html
@@ -1,7 +1,8 @@
 <!doctype html>
 <html>
   <head>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
     <title>Test Negative AudioParam.exponentialRampToValueAtTime</title>
@@ -9,8 +10,6 @@
 
   <body>
     <script>
-      description("Test AudioParam.exponentialRampToValueAtTime() with Negative Values.");
-      window.jsTestIsAsync = true;
       
       var sampleRate = 48000;
 
@@ -146,7 +145,6 @@
       });
 
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
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 a971d24..d147f772 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,294 +1,266 @@
-CONSOLE WARNING: line 396: Delay.delayTime.value -1 outside nominal range [0, 1.5]; value will be clamped.
-CONSOLE WARNING: line 405: Delay.delayTime.value 4 outside nominal range [0, 1.5]; value will be clamped.
-CONSOLE WARNING: line 396: StereoPanner.pan.value -3 outside nominal range [-1, 1]; value will be clamped.
-CONSOLE WARNING: line 405: StereoPanner.pan.value 3 outside nominal range [-1, 1]; value will be clamped.
-CONSOLE WARNING: line 396: DynamicsCompressor.threshold.value -201 outside nominal range [-100, 0]; value will be clamped.
-CONSOLE WARNING: line 405: DynamicsCompressor.threshold.value 1 outside nominal range [-100, 0]; value will be clamped.
-CONSOLE WARNING: line 396: DynamicsCompressor.knee.value -1 outside nominal range [0, 40]; value will be clamped.
-CONSOLE WARNING: line 405: DynamicsCompressor.knee.value 81 outside nominal range [0, 40]; value will be clamped.
-CONSOLE WARNING: line 405: DynamicsCompressor.ratio.value 41 outside nominal range [1, 20]; value will be clamped.
-CONSOLE WARNING: line 396: DynamicsCompressor.attack.value -1 outside nominal range [0, 1]; value will be clamped.
-CONSOLE WARNING: line 405: DynamicsCompressor.attack.value 3 outside nominal range [0, 1]; value will be clamped.
-CONSOLE WARNING: line 396: DynamicsCompressor.release.value -1 outside nominal range [0, 1]; value will be clamped.
-CONSOLE WARNING: line 405: DynamicsCompressor.release.value 3 outside nominal range [0, 1]; value will be clamped.
-CONSOLE WARNING: line 396: BiquadFilter.frequency.value -1 outside nominal range [0, 24000]; value will be clamped.
-CONSOLE WARNING: line 405: BiquadFilter.frequency.value 48001 outside nominal range [0, 24000]; value will be clamped.
-CONSOLE WARNING: line 396: Oscillator.frequency.value -48001 outside nominal range [-24000, 24000]; value will be clamped.
-CONSOLE WARNING: line 405: Oscillator.frequency.value 48001 outside nominal range [-24000, 24000]; value will be clamped.
+CONSOLE WARNING: line 394: Delay.delayTime.value -1 outside nominal range [0, 1.5]; value will be clamped.
+CONSOLE WARNING: line 403: Delay.delayTime.value 4 outside nominal range [0, 1.5]; value will be clamped.
+CONSOLE WARNING: line 394: StereoPanner.pan.value -3 outside nominal range [-1, 1]; value will be clamped.
+CONSOLE WARNING: line 403: StereoPanner.pan.value 3 outside nominal range [-1, 1]; value will be clamped.
+CONSOLE WARNING: line 394: DynamicsCompressor.threshold.value -201 outside nominal range [-100, 0]; value will be clamped.
+CONSOLE WARNING: line 403: DynamicsCompressor.threshold.value 1 outside nominal range [-100, 0]; value will be clamped.
+CONSOLE WARNING: line 394: DynamicsCompressor.knee.value -1 outside nominal range [0, 40]; value will be clamped.
+CONSOLE WARNING: line 403: DynamicsCompressor.knee.value 81 outside nominal range [0, 40]; value will be clamped.
+CONSOLE WARNING: line 403: DynamicsCompressor.ratio.value 41 outside nominal range [1, 20]; value will be clamped.
+CONSOLE WARNING: line 394: DynamicsCompressor.attack.value -1 outside nominal range [0, 1]; value will be clamped.
+CONSOLE WARNING: line 403: DynamicsCompressor.attack.value 3 outside nominal range [0, 1]; value will be clamped.
+CONSOLE WARNING: line 394: DynamicsCompressor.release.value -1 outside nominal range [0, 1]; value will be clamped.
+CONSOLE WARNING: line 403: DynamicsCompressor.release.value 3 outside nominal range [0, 1]; value will be clamped.
+CONSOLE WARNING: line 394: BiquadFilter.frequency.value -1 outside nominal range [0, 24000]; value will be clamped.
+CONSOLE WARNING: line 403: BiquadFilter.frequency.value 48001 outside nominal range [0, 24000]; value will be clamped.
+CONSOLE WARNING: line 394: Oscillator.frequency.value -48001 outside nominal range [-24000, 24000]; value will be clamped.
+CONSOLE WARNING: line 403: Oscillator.frequency.value 48001 outside nominal range [-24000, 24000]; value will be clamped.
 CONSOLE WARNING: line 325: Delay.delayTime.setValueAtTime value -1 outside nominal range [0, 1]; value will be clamped.
 CONSOLE WARNING: line 326: Delay.delayTime.linearRampToValueAtTime value 2 outside nominal range [0, 1]; value will be clamped.
 CONSOLE WARNING: line 327: Delay.delayTime.exponentialRampToValue value 3 outside nominal range [0, 1]; value will be clamped.
 CONSOLE WARNING: line 328: Delay.delayTime.setTargetAtTime value -1 outside nominal range [0, 1]; value will be clamped.
 CONSOLE WARNING: line 329: Delay.delayTime.setValueCurveAtTime value 1.5 outside nominal range [0, 1]; value will be clamped.
-Test AudioParam Nominal Range Values.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS GainNode.gain.minValue is equal to -3.4028234663852886e+38.
-PASS GainNode.gain.maxValue is equal to 3.4028234663852886e+38.
-PASS GainNode.gain.minValue = Math.PI is not equal to 3.141592653589793.
-PASS GainNode.gain.minValue is read-only.
-PASS GainNode.gain.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS GainNode.gain.maxValue is read-only.
-PASS Nominal ranges for AudioParam(s) of GainNode are correct.
-
-PASS DelayNode.delayTime.minValue is equal to 0.
-PASS DelayNode.delayTime.maxValue is equal to 1.5.
-PASS DelayNode.delayTime.minValue = Math.PI is not equal to 3.141592653589793.
-PASS DelayNode.delayTime.minValue is read-only.
-PASS DelayNode.delayTime.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS DelayNode.delayTime.maxValue is read-only.
-PASS Set DelayNode.delayTime.value = -1 is equal to 0.
-PASS Set DelayNode.delayTime.value = 4 is equal to 1.5.
-PASS DelayNode.delayTime was correctly clipped to lie within the nominal range.
-PASS Nominal ranges for AudioParam(s) of DelayNode are correct.
-
-PASS AudioBufferSourceNode.playbackRate.minValue is equal to -3.4028234663852886e+38.
-PASS AudioBufferSourceNode.playbackRate.maxValue is equal to 3.4028234663852886e+38.
-PASS AudioBufferSourceNode.playbackRate.minValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioBufferSourceNode.playbackRate.minValue is read-only.
-PASS AudioBufferSourceNode.playbackRate.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioBufferSourceNode.playbackRate.maxValue is read-only.
-PASS AudioBufferSourceNode.detune.minValue is equal to -3.4028234663852886e+38.
-PASS AudioBufferSourceNode.detune.maxValue is equal to 3.4028234663852886e+38.
-PASS AudioBufferSourceNode.detune.minValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioBufferSourceNode.detune.minValue is read-only.
-PASS AudioBufferSourceNode.detune.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioBufferSourceNode.detune.maxValue is read-only.
-PASS Nominal ranges for AudioParam(s) of AudioBufferSourceNode are correct.
-
-PASS StereoPannerNode.pan.minValue is equal to -1.
-PASS StereoPannerNode.pan.maxValue is equal to 1.
-PASS StereoPannerNode.pan.minValue = Math.PI is not equal to 3.141592653589793.
-PASS StereoPannerNode.pan.minValue is read-only.
-PASS StereoPannerNode.pan.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS StereoPannerNode.pan.maxValue is read-only.
-PASS Set StereoPannerNode.pan.value = -3 is equal to -1.
-PASS Set StereoPannerNode.pan.value = 3 is equal to 1.
-PASS StereoPannerNode.pan was correctly clipped to lie within the nominal range.
-PASS Nominal ranges for AudioParam(s) of StereoPannerNode are correct.
-
-PASS DynamicsCompressorNode.threshold.minValue is equal to -100.
-PASS DynamicsCompressorNode.threshold.maxValue is equal to 0.
-PASS DynamicsCompressorNode.threshold.minValue = Math.PI is not equal to 3.141592653589793.
-PASS DynamicsCompressorNode.threshold.minValue is read-only.
-PASS DynamicsCompressorNode.threshold.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS DynamicsCompressorNode.threshold.maxValue is read-only.
-PASS Set DynamicsCompressorNode.threshold.value = -201 is equal to -100.
-PASS Set DynamicsCompressorNode.threshold.value = 1 is equal to 0.
-PASS DynamicsCompressorNode.threshold was correctly clipped to lie within the nominal range.
-PASS DynamicsCompressorNode.knee.minValue is equal to 0.
-PASS DynamicsCompressorNode.knee.maxValue is equal to 40.
-PASS DynamicsCompressorNode.knee.minValue = Math.PI is not equal to 3.141592653589793.
-PASS DynamicsCompressorNode.knee.minValue is read-only.
-PASS DynamicsCompressorNode.knee.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS DynamicsCompressorNode.knee.maxValue is read-only.
-PASS Set DynamicsCompressorNode.knee.value = -1 is equal to 0.
-PASS Set DynamicsCompressorNode.knee.value = 81 is equal to 40.
-PASS DynamicsCompressorNode.knee was correctly clipped to lie within the nominal range.
-PASS DynamicsCompressorNode.ratio.minValue is equal to 1.
-PASS DynamicsCompressorNode.ratio.maxValue is equal to 20.
-PASS DynamicsCompressorNode.ratio.minValue = Math.PI is not equal to 3.141592653589793.
-PASS DynamicsCompressorNode.ratio.minValue is read-only.
-PASS DynamicsCompressorNode.ratio.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS DynamicsCompressorNode.ratio.maxValue is read-only.
-PASS Set DynamicsCompressorNode.ratio.value = 1 is equal to 1.
-PASS Set DynamicsCompressorNode.ratio.value = 41 is equal to 20.
-PASS DynamicsCompressorNode.ratio was correctly clipped to lie within the nominal range.
-PASS DynamicsCompressorNode.attack.minValue is equal to 0.
-PASS DynamicsCompressorNode.attack.maxValue is equal to 1.
-PASS DynamicsCompressorNode.attack.minValue = Math.PI is not equal to 3.141592653589793.
-PASS DynamicsCompressorNode.attack.minValue is read-only.
-PASS DynamicsCompressorNode.attack.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS DynamicsCompressorNode.attack.maxValue is read-only.
-PASS Set DynamicsCompressorNode.attack.value = -1 is equal to 0.
-PASS Set DynamicsCompressorNode.attack.value = 3 is equal to 1.
-PASS DynamicsCompressorNode.attack was correctly clipped to lie within the nominal range.
-PASS DynamicsCompressorNode.release.minValue is equal to 0.
-PASS DynamicsCompressorNode.release.maxValue is equal to 1.
-PASS DynamicsCompressorNode.release.minValue = Math.PI is not equal to 3.141592653589793.
-PASS DynamicsCompressorNode.release.minValue is read-only.
-PASS DynamicsCompressorNode.release.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS DynamicsCompressorNode.release.maxValue is read-only.
-PASS Set DynamicsCompressorNode.release.value = -1 is equal to 0.
-PASS Set DynamicsCompressorNode.release.value = 3 is equal to 1.
-PASS DynamicsCompressorNode.release was correctly clipped to lie within the nominal range.
-PASS Nominal ranges for AudioParam(s) of DynamicsCompressorNode are correct.
-
-PASS BiquadFilterNode.frequency.minValue is equal to 0.
-PASS BiquadFilterNode.frequency.maxValue is equal to 24000.
-PASS BiquadFilterNode.frequency.minValue = Math.PI is not equal to 3.141592653589793.
-PASS BiquadFilterNode.frequency.minValue is read-only.
-PASS BiquadFilterNode.frequency.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS BiquadFilterNode.frequency.maxValue is read-only.
-PASS Set BiquadFilterNode.frequency.value = -1 is equal to 0.
-PASS Set BiquadFilterNode.frequency.value = 48001 is equal to 24000.
-PASS BiquadFilterNode.frequency was correctly clipped to lie within the nominal range.
-PASS BiquadFilterNode.detune.minValue is equal to -3.4028234663852886e+38.
-PASS BiquadFilterNode.detune.maxValue is equal to 3.4028234663852886e+38.
-PASS BiquadFilterNode.detune.minValue = Math.PI is not equal to 3.141592653589793.
-PASS BiquadFilterNode.detune.minValue is read-only.
-PASS BiquadFilterNode.detune.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS BiquadFilterNode.detune.maxValue is read-only.
-PASS BiquadFilterNode.Q.minValue is equal to -3.4028234663852886e+38.
-PASS BiquadFilterNode.Q.maxValue is equal to 3.4028234663852886e+38.
-PASS BiquadFilterNode.Q.minValue = Math.PI is not equal to 3.141592653589793.
-PASS BiquadFilterNode.Q.minValue is read-only.
-PASS BiquadFilterNode.Q.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS BiquadFilterNode.Q.maxValue is read-only.
-PASS BiquadFilterNode.gain.minValue is equal to -3.4028234663852886e+38.
-PASS BiquadFilterNode.gain.maxValue is equal to 3.4028234663852886e+38.
-PASS BiquadFilterNode.gain.minValue = Math.PI is not equal to 3.141592653589793.
-PASS BiquadFilterNode.gain.minValue is read-only.
-PASS BiquadFilterNode.gain.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS BiquadFilterNode.gain.maxValue is read-only.
-PASS Nominal ranges for AudioParam(s) of BiquadFilterNode are correct.
-
-PASS OscillatorNode.frequency.minValue is equal to -24000.
-PASS OscillatorNode.frequency.maxValue is equal to 24000.
-PASS OscillatorNode.frequency.minValue = Math.PI is not equal to 3.141592653589793.
-PASS OscillatorNode.frequency.minValue is read-only.
-PASS OscillatorNode.frequency.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS OscillatorNode.frequency.maxValue is read-only.
-PASS Set OscillatorNode.frequency.value = -48001 is equal to -24000.
-PASS Set OscillatorNode.frequency.value = 48001 is equal to 24000.
-PASS OscillatorNode.frequency was correctly clipped to lie within the nominal range.
-PASS OscillatorNode.detune.minValue is equal to -3.4028234663852886e+38.
-PASS OscillatorNode.detune.maxValue is equal to 3.4028234663852886e+38.
-PASS OscillatorNode.detune.minValue = Math.PI is not equal to 3.141592653589793.
-PASS OscillatorNode.detune.minValue is read-only.
-PASS OscillatorNode.detune.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS OscillatorNode.detune.maxValue is read-only.
-PASS Nominal ranges for AudioParam(s) of OscillatorNode are correct.
-
-PASS PannerNode.positionX.minValue is equal to -3.4028234663852886e+38.
-PASS PannerNode.positionX.maxValue is equal to 3.4028234663852886e+38.
-PASS PannerNode.positionX.minValue = Math.PI is not equal to 3.141592653589793.
-PASS PannerNode.positionX.minValue is read-only.
-PASS PannerNode.positionX.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS PannerNode.positionX.maxValue is read-only.
-PASS PannerNode.positionY.minValue is equal to -3.4028234663852886e+38.
-PASS PannerNode.positionY.maxValue is equal to 3.4028234663852886e+38.
-PASS PannerNode.positionY.minValue = Math.PI is not equal to 3.141592653589793.
-PASS PannerNode.positionY.minValue is read-only.
-PASS PannerNode.positionY.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS PannerNode.positionY.maxValue is read-only.
-PASS PannerNode.positionZ.minValue is equal to -3.4028234663852886e+38.
-PASS PannerNode.positionZ.maxValue is equal to 3.4028234663852886e+38.
-PASS PannerNode.positionZ.minValue = Math.PI is not equal to 3.141592653589793.
-PASS PannerNode.positionZ.minValue is read-only.
-PASS PannerNode.positionZ.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS PannerNode.positionZ.maxValue is read-only.
-PASS PannerNode.orientationX.minValue is equal to -3.4028234663852886e+38.
-PASS PannerNode.orientationX.maxValue is equal to 3.4028234663852886e+38.
-PASS PannerNode.orientationX.minValue = Math.PI is not equal to 3.141592653589793.
-PASS PannerNode.orientationX.minValue is read-only.
-PASS PannerNode.orientationX.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS PannerNode.orientationX.maxValue is read-only.
-PASS PannerNode.orientationY.minValue is equal to -3.4028234663852886e+38.
-PASS PannerNode.orientationY.maxValue is equal to 3.4028234663852886e+38.
-PASS PannerNode.orientationY.minValue = Math.PI is not equal to 3.141592653589793.
-PASS PannerNode.orientationY.minValue is read-only.
-PASS PannerNode.orientationY.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS PannerNode.orientationY.maxValue is read-only.
-PASS PannerNode.orientationZ.minValue is equal to -3.4028234663852886e+38.
-PASS PannerNode.orientationZ.maxValue is equal to 3.4028234663852886e+38.
-PASS PannerNode.orientationZ.minValue = Math.PI is not equal to 3.141592653589793.
-PASS PannerNode.orientationZ.minValue is read-only.
-PASS PannerNode.orientationZ.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS PannerNode.orientationZ.maxValue is read-only.
-PASS Nominal ranges for AudioParam(s) of PannerNode are correct.
-
-PASS ConstantSourceNode.offset.minValue is equal to -3.4028234663852886e+38.
-PASS ConstantSourceNode.offset.maxValue is equal to 3.4028234663852886e+38.
-PASS ConstantSourceNode.offset.minValue = Math.PI is not equal to 3.141592653589793.
-PASS ConstantSourceNode.offset.minValue is read-only.
-PASS ConstantSourceNode.offset.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS ConstantSourceNode.offset.maxValue is read-only.
-PASS Nominal ranges for AudioParam(s) of ConstantSourceNode are correct.
-
-PASS AudioBuffer has no AudioParams as expected.
-
-PASS IIRFilterNode has no AudioParams as expected.
-
-PASS WaveShaperNode has no AudioParams as expected.
-
-PASS ConvolverNode has no AudioParams as expected.
-
-PASS AnalyserNode has no AudioParams as expected.
-
-PASS ScriptProcessorNode has no AudioParams as expected.
-
-PASS PeriodicWave has no AudioParams as expected.
-
-PASS ChannelSplitterNode has no AudioParams as expected.
-
-PASS ChannelMergerNode has no AudioParams as expected.
-
-PASS MediaElementAudioSourceNode has no AudioParams as expected.
-
-PASS MediaStreamAudioDestinationNode has no AudioParams as expected.
-
-PASS AudioListener.positionX.minValue is equal to -3.4028234663852886e+38.
-PASS AudioListener.positionX.maxValue is equal to 3.4028234663852886e+38.
-PASS AudioListener.positionX.minValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.positionX.minValue is read-only.
-PASS AudioListener.positionX.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.positionX.maxValue is read-only.
-PASS AudioListener.positionY.minValue is equal to -3.4028234663852886e+38.
-PASS AudioListener.positionY.maxValue is equal to 3.4028234663852886e+38.
-PASS AudioListener.positionY.minValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.positionY.minValue is read-only.
-PASS AudioListener.positionY.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.positionY.maxValue is read-only.
-PASS AudioListener.positionZ.minValue is equal to -3.4028234663852886e+38.
-PASS AudioListener.positionZ.maxValue is equal to 3.4028234663852886e+38.
-PASS AudioListener.positionZ.minValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.positionZ.minValue is read-only.
-PASS AudioListener.positionZ.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.positionZ.maxValue is read-only.
-PASS AudioListener.forwardX.minValue is equal to -3.4028234663852886e+38.
-PASS AudioListener.forwardX.maxValue is equal to 3.4028234663852886e+38.
-PASS AudioListener.forwardX.minValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.forwardX.minValue is read-only.
-PASS AudioListener.forwardX.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.forwardX.maxValue is read-only.
-PASS AudioListener.forwardY.minValue is equal to -3.4028234663852886e+38.
-PASS AudioListener.forwardY.maxValue is equal to 3.4028234663852886e+38.
-PASS AudioListener.forwardY.minValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.forwardY.minValue is read-only.
-PASS AudioListener.forwardY.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.forwardY.maxValue is read-only.
-PASS AudioListener.forwardZ.minValue is equal to -3.4028234663852886e+38.
-PASS AudioListener.forwardZ.maxValue is equal to 3.4028234663852886e+38.
-PASS AudioListener.forwardZ.minValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.forwardZ.minValue is read-only.
-PASS AudioListener.forwardZ.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.forwardZ.maxValue is read-only.
-PASS AudioListener.upX.minValue is equal to -3.4028234663852886e+38.
-PASS AudioListener.upX.maxValue is equal to 3.4028234663852886e+38.
-PASS AudioListener.upX.minValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.upX.minValue is read-only.
-PASS AudioListener.upX.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.upX.maxValue is read-only.
-PASS AudioListener.upY.minValue is equal to -3.4028234663852886e+38.
-PASS AudioListener.upY.maxValue is equal to 3.4028234663852886e+38.
-PASS AudioListener.upY.minValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.upY.minValue is read-only.
-PASS AudioListener.upY.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.upY.maxValue is read-only.
-PASS AudioListener.upZ.minValue is equal to -3.4028234663852886e+38.
-PASS AudioListener.upZ.maxValue is equal to 3.4028234663852886e+38.
-PASS AudioListener.upZ.minValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.upZ.minValue is read-only.
-PASS AudioListener.upZ.maxValue = Math.PI is not equal to 3.141592653589793.
-PASS AudioListener.upZ.maxValue is read-only.
-PASS Nominal ranges for AudioParam(s) of AudioListener are correct.
-
-PASS All nodes were tested.
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
+This is a testharness.js-based test.
+PASS GainNode.gain.minValue is equal to -3.4028234663852886e+38. 
+PASS GainNode.gain.maxValue is equal to 3.4028234663852886e+38. 
+PASS GainNode.gain.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS GainNode.gain.minValue is read-only is equal to true. 
+PASS GainNode.gain.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS GainNode.gain.maxValue is read-only is equal to true. 
+PASS Nominal ranges for AudioParam(s) of GainNode are correct. 
+PASS DelayNode.delayTime.minValue is equal to 0. 
+PASS DelayNode.delayTime.maxValue is equal to 1.5. 
+PASS DelayNode.delayTime.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS DelayNode.delayTime.minValue is read-only is equal to true. 
+PASS DelayNode.delayTime.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS DelayNode.delayTime.maxValue is read-only is equal to true. 
+PASS Set DelayNode.delayTime.value = -1 is equal to 0. 
+PASS Set DelayNode.delayTime.value = 4 is equal to 1.5. 
+PASS DelayNode.delayTimewas clipped to lie within the nominal range is equal to true. 
+PASS Nominal ranges for AudioParam(s) of DelayNode are correct. 
+PASS AudioBufferSourceNode.playbackRate.minValue is equal to -3.4028234663852886e+38. 
+PASS AudioBufferSourceNode.playbackRate.maxValue is equal to 3.4028234663852886e+38. 
+PASS AudioBufferSourceNode.playbackRate.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioBufferSourceNode.playbackRate.minValue is read-only is equal to true. 
+PASS AudioBufferSourceNode.playbackRate.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioBufferSourceNode.playbackRate.maxValue is read-only is equal to true. 
+PASS AudioBufferSourceNode.detune.minValue is equal to -3.4028234663852886e+38. 
+PASS AudioBufferSourceNode.detune.maxValue is equal to 3.4028234663852886e+38. 
+PASS AudioBufferSourceNode.detune.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioBufferSourceNode.detune.minValue is read-only is equal to true. 
+PASS AudioBufferSourceNode.detune.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioBufferSourceNode.detune.maxValue is read-only is equal to true. 
+PASS Nominal ranges for AudioParam(s) of AudioBufferSourceNode are correct. 
+PASS StereoPannerNode.pan.minValue is equal to -1. 
+PASS StereoPannerNode.pan.maxValue is equal to 1. 
+PASS StereoPannerNode.pan.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS StereoPannerNode.pan.minValue is read-only is equal to true. 
+PASS StereoPannerNode.pan.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS StereoPannerNode.pan.maxValue is read-only is equal to true. 
+PASS Set StereoPannerNode.pan.value = -3 is equal to -1. 
+PASS Set StereoPannerNode.pan.value = 3 is equal to 1. 
+PASS StereoPannerNode.panwas clipped to lie within the nominal range is equal to true. 
+PASS Nominal ranges for AudioParam(s) of StereoPannerNode are correct. 
+PASS DynamicsCompressorNode.threshold.minValue is equal to -100. 
+PASS DynamicsCompressorNode.threshold.maxValue is equal to 0. 
+PASS DynamicsCompressorNode.threshold.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS DynamicsCompressorNode.threshold.minValue is read-only is equal to true. 
+PASS DynamicsCompressorNode.threshold.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS DynamicsCompressorNode.threshold.maxValue is read-only is equal to true. 
+PASS Set DynamicsCompressorNode.threshold.value = -201 is equal to -100. 
+PASS Set DynamicsCompressorNode.threshold.value = 1 is equal to 0. 
+PASS DynamicsCompressorNode.thresholdwas clipped to lie within the nominal range is equal to true. 
+PASS DynamicsCompressorNode.knee.minValue is equal to 0. 
+PASS DynamicsCompressorNode.knee.maxValue is equal to 40. 
+PASS DynamicsCompressorNode.knee.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS DynamicsCompressorNode.knee.minValue is read-only is equal to true. 
+PASS DynamicsCompressorNode.knee.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS DynamicsCompressorNode.knee.maxValue is read-only is equal to true. 
+PASS Set DynamicsCompressorNode.knee.value = -1 is equal to 0. 
+PASS Set DynamicsCompressorNode.knee.value = 81 is equal to 40. 
+PASS DynamicsCompressorNode.kneewas clipped to lie within the nominal range is equal to true. 
+PASS DynamicsCompressorNode.ratio.minValue is equal to 1. 
+PASS DynamicsCompressorNode.ratio.maxValue is equal to 20. 
+PASS DynamicsCompressorNode.ratio.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS DynamicsCompressorNode.ratio.minValue is read-only is equal to true. 
+PASS DynamicsCompressorNode.ratio.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS DynamicsCompressorNode.ratio.maxValue is read-only is equal to true. 
+PASS Set DynamicsCompressorNode.ratio.value = 1 is equal to 1. 
+PASS Set DynamicsCompressorNode.ratio.value = 41 is equal to 20. 
+PASS DynamicsCompressorNode.ratiowas clipped to lie within the nominal range is equal to true. 
+PASS DynamicsCompressorNode.attack.minValue is equal to 0. 
+PASS DynamicsCompressorNode.attack.maxValue is equal to 1. 
+PASS DynamicsCompressorNode.attack.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS DynamicsCompressorNode.attack.minValue is read-only is equal to true. 
+PASS DynamicsCompressorNode.attack.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS DynamicsCompressorNode.attack.maxValue is read-only is equal to true. 
+PASS Set DynamicsCompressorNode.attack.value = -1 is equal to 0. 
+PASS Set DynamicsCompressorNode.attack.value = 3 is equal to 1. 
+PASS DynamicsCompressorNode.attackwas clipped to lie within the nominal range is equal to true. 
+PASS DynamicsCompressorNode.release.minValue is equal to 0. 
+PASS DynamicsCompressorNode.release.maxValue is equal to 1. 
+PASS DynamicsCompressorNode.release.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS DynamicsCompressorNode.release.minValue is read-only is equal to true. 
+PASS DynamicsCompressorNode.release.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS DynamicsCompressorNode.release.maxValue is read-only is equal to true. 
+PASS Set DynamicsCompressorNode.release.value = -1 is equal to 0. 
+PASS Set DynamicsCompressorNode.release.value = 3 is equal to 1. 
+PASS DynamicsCompressorNode.releasewas clipped to lie within the nominal range is equal to true. 
+PASS Nominal ranges for AudioParam(s) of DynamicsCompressorNode are correct. 
+PASS BiquadFilterNode.frequency.minValue is equal to 0. 
+PASS BiquadFilterNode.frequency.maxValue is equal to 24000. 
+PASS BiquadFilterNode.frequency.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS BiquadFilterNode.frequency.minValue is read-only is equal to true. 
+PASS BiquadFilterNode.frequency.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS BiquadFilterNode.frequency.maxValue is read-only is equal to true. 
+PASS Set BiquadFilterNode.frequency.value = -1 is equal to 0. 
+PASS Set BiquadFilterNode.frequency.value = 48001 is equal to 24000. 
+PASS BiquadFilterNode.frequencywas clipped to lie within the nominal range is equal to true. 
+PASS BiquadFilterNode.detune.minValue is equal to -3.4028234663852886e+38. 
+PASS BiquadFilterNode.detune.maxValue is equal to 3.4028234663852886e+38. 
+PASS BiquadFilterNode.detune.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS BiquadFilterNode.detune.minValue is read-only is equal to true. 
+PASS BiquadFilterNode.detune.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS BiquadFilterNode.detune.maxValue is read-only is equal to true. 
+PASS BiquadFilterNode.Q.minValue is equal to -3.4028234663852886e+38. 
+PASS BiquadFilterNode.Q.maxValue is equal to 3.4028234663852886e+38. 
+PASS BiquadFilterNode.Q.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS BiquadFilterNode.Q.minValue is read-only is equal to true. 
+PASS BiquadFilterNode.Q.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS BiquadFilterNode.Q.maxValue is read-only is equal to true. 
+PASS BiquadFilterNode.gain.minValue is equal to -3.4028234663852886e+38. 
+PASS BiquadFilterNode.gain.maxValue is equal to 3.4028234663852886e+38. 
+PASS BiquadFilterNode.gain.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS BiquadFilterNode.gain.minValue is read-only is equal to true. 
+PASS BiquadFilterNode.gain.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS BiquadFilterNode.gain.maxValue is read-only is equal to true. 
+PASS Nominal ranges for AudioParam(s) of BiquadFilterNode are correct. 
+PASS OscillatorNode.frequency.minValue is equal to -24000. 
+PASS OscillatorNode.frequency.maxValue is equal to 24000. 
+PASS OscillatorNode.frequency.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS OscillatorNode.frequency.minValue is read-only is equal to true. 
+PASS OscillatorNode.frequency.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS OscillatorNode.frequency.maxValue is read-only is equal to true. 
+PASS Set OscillatorNode.frequency.value = -48001 is equal to -24000. 
+PASS Set OscillatorNode.frequency.value = 48001 is equal to 24000. 
+PASS OscillatorNode.frequencywas clipped to lie within the nominal range is equal to true. 
+PASS OscillatorNode.detune.minValue is equal to -3.4028234663852886e+38. 
+PASS OscillatorNode.detune.maxValue is equal to 3.4028234663852886e+38. 
+PASS OscillatorNode.detune.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS OscillatorNode.detune.minValue is read-only is equal to true. 
+PASS OscillatorNode.detune.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS OscillatorNode.detune.maxValue is read-only is equal to true. 
+PASS Nominal ranges for AudioParam(s) of OscillatorNode are correct. 
+PASS PannerNode.positionX.minValue is equal to -3.4028234663852886e+38. 
+PASS PannerNode.positionX.maxValue is equal to 3.4028234663852886e+38. 
+PASS PannerNode.positionX.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS PannerNode.positionX.minValue is read-only is equal to true. 
+PASS PannerNode.positionX.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS PannerNode.positionX.maxValue is read-only is equal to true. 
+PASS PannerNode.positionY.minValue is equal to -3.4028234663852886e+38. 
+PASS PannerNode.positionY.maxValue is equal to 3.4028234663852886e+38. 
+PASS PannerNode.positionY.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS PannerNode.positionY.minValue is read-only is equal to true. 
+PASS PannerNode.positionY.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS PannerNode.positionY.maxValue is read-only is equal to true. 
+PASS PannerNode.positionZ.minValue is equal to -3.4028234663852886e+38. 
+PASS PannerNode.positionZ.maxValue is equal to 3.4028234663852886e+38. 
+PASS PannerNode.positionZ.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS PannerNode.positionZ.minValue is read-only is equal to true. 
+PASS PannerNode.positionZ.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS PannerNode.positionZ.maxValue is read-only is equal to true. 
+PASS PannerNode.orientationX.minValue is equal to -3.4028234663852886e+38. 
+PASS PannerNode.orientationX.maxValue is equal to 3.4028234663852886e+38. 
+PASS PannerNode.orientationX.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS PannerNode.orientationX.minValue is read-only is equal to true. 
+PASS PannerNode.orientationX.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS PannerNode.orientationX.maxValue is read-only is equal to true. 
+PASS PannerNode.orientationY.minValue is equal to -3.4028234663852886e+38. 
+PASS PannerNode.orientationY.maxValue is equal to 3.4028234663852886e+38. 
+PASS PannerNode.orientationY.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS PannerNode.orientationY.minValue is read-only is equal to true. 
+PASS PannerNode.orientationY.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS PannerNode.orientationY.maxValue is read-only is equal to true. 
+PASS PannerNode.orientationZ.minValue is equal to -3.4028234663852886e+38. 
+PASS PannerNode.orientationZ.maxValue is equal to 3.4028234663852886e+38. 
+PASS PannerNode.orientationZ.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS PannerNode.orientationZ.minValue is read-only is equal to true. 
+PASS PannerNode.orientationZ.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS PannerNode.orientationZ.maxValue is read-only is equal to true. 
+PASS Nominal ranges for AudioParam(s) of PannerNode are correct. 
+PASS ConstantSourceNode.offset.minValue is equal to -3.4028234663852886e+38. 
+PASS ConstantSourceNode.offset.maxValue is equal to 3.4028234663852886e+38. 
+PASS ConstantSourceNode.offset.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS ConstantSourceNode.offset.minValue is read-only is equal to true. 
+PASS ConstantSourceNode.offset.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS ConstantSourceNode.offset.maxValue is read-only is equal to true. 
+PASS Nominal ranges for AudioParam(s) of ConstantSourceNode are correct. 
+PASS AudioBuffer has no AudioParams as expected. 
+PASS IIRFilterNode has no AudioParams as expected. 
+PASS WaveShaperNode has no AudioParams as expected. 
+PASS ConvolverNode has no AudioParams as expected. 
+PASS AnalyserNode has no AudioParams as expected. 
+PASS ScriptProcessorNode has no AudioParams as expected. 
+PASS PeriodicWave has no AudioParams as expected. 
+PASS ChannelSplitterNode has no AudioParams as expected. 
+PASS ChannelMergerNode has no AudioParams as expected. 
+PASS MediaElementAudioSourceNode has no AudioParams as expected. 
+PASS MediaStreamAudioDestinationNode has no AudioParams as expected. 
+PASS AudioListener.positionX.minValue is equal to -3.4028234663852886e+38. 
+PASS AudioListener.positionX.maxValue is equal to 3.4028234663852886e+38. 
+PASS AudioListener.positionX.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.positionX.minValue is read-only is equal to true. 
+PASS AudioListener.positionX.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.positionX.maxValue is read-only is equal to true. 
+PASS AudioListener.positionY.minValue is equal to -3.4028234663852886e+38. 
+PASS AudioListener.positionY.maxValue is equal to 3.4028234663852886e+38. 
+PASS AudioListener.positionY.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.positionY.minValue is read-only is equal to true. 
+PASS AudioListener.positionY.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.positionY.maxValue is read-only is equal to true. 
+PASS AudioListener.positionZ.minValue is equal to -3.4028234663852886e+38. 
+PASS AudioListener.positionZ.maxValue is equal to 3.4028234663852886e+38. 
+PASS AudioListener.positionZ.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.positionZ.minValue is read-only is equal to true. 
+PASS AudioListener.positionZ.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.positionZ.maxValue is read-only is equal to true. 
+PASS AudioListener.forwardX.minValue is equal to -3.4028234663852886e+38. 
+PASS AudioListener.forwardX.maxValue is equal to 3.4028234663852886e+38. 
+PASS AudioListener.forwardX.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.forwardX.minValue is read-only is equal to true. 
+PASS AudioListener.forwardX.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.forwardX.maxValue is read-only is equal to true. 
+PASS AudioListener.forwardY.minValue is equal to -3.4028234663852886e+38. 
+PASS AudioListener.forwardY.maxValue is equal to 3.4028234663852886e+38. 
+PASS AudioListener.forwardY.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.forwardY.minValue is read-only is equal to true. 
+PASS AudioListener.forwardY.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.forwardY.maxValue is read-only is equal to true. 
+PASS AudioListener.forwardZ.minValue is equal to -3.4028234663852886e+38. 
+PASS AudioListener.forwardZ.maxValue is equal to 3.4028234663852886e+38. 
+PASS AudioListener.forwardZ.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.forwardZ.minValue is read-only is equal to true. 
+PASS AudioListener.forwardZ.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.forwardZ.maxValue is read-only is equal to true. 
+PASS AudioListener.upX.minValue is equal to -3.4028234663852886e+38. 
+PASS AudioListener.upX.maxValue is equal to 3.4028234663852886e+38. 
+PASS AudioListener.upX.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.upX.minValue is read-only is equal to true. 
+PASS AudioListener.upX.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.upX.maxValue is read-only is equal to true. 
+PASS AudioListener.upY.minValue is equal to -3.4028234663852886e+38. 
+PASS AudioListener.upY.maxValue is equal to 3.4028234663852886e+38. 
+PASS AudioListener.upY.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.upY.minValue is read-only is equal to true. 
+PASS AudioListener.upY.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.upY.maxValue is read-only is equal to true. 
+PASS AudioListener.upZ.minValue is equal to -3.4028234663852886e+38. 
+PASS AudioListener.upZ.maxValue is equal to 3.4028234663852886e+38. 
+PASS AudioListener.upZ.minValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.upZ.minValue is read-only is equal to true. 
+PASS AudioListener.upZ.maxValue = Math.PI is not equal to 3.141592653589793. 
+PASS AudioListener.upZ.maxValue is read-only is equal to true. 
+PASS Nominal ranges for AudioParam(s) of AudioListener are correct. 
+PASS Number of nodes not tested : 0. 
+Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-nominal-range.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-nominal-range.html
index ff1d0b2..672b1de 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-nominal-range.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-nominal-range.html
@@ -1,7 +1,8 @@
 <!doctype html>
 <html>
   <head>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
     <title>Test AudioParam Nominal Range Values</title>
@@ -9,8 +10,6 @@
 
   <body>
     <script>
-      description("Test AudioParam Nominal Range Values.");
-      window.jsTestIsAsync = true;
 
       // Some arbitrary sample rate for the offline context. 
       var sampleRate = 48000;
@@ -231,7 +230,7 @@
       });
 
       // Create a task for each entry in testConfigs
-      for (var test in testConfigs) {
+      for (let test in testConfigs) {
         var config = testConfigs[test]
         audit.defineTask(config.creator, (function (c) {
           return function (done) {
@@ -304,14 +303,15 @@
 
         // It's a test failure if we didn't test all of the create methods in the context (except
         // createMediaStreamSource, of course).
+        var output = [];
         if (diff.size) {
-          var output = [];
           for (let item of diff)
             output.push(" " + item.substring(6));
-          testFailed("These nodes were not tested:" + output + "\n");
-        } else {
-          testPassed("All nodes were tested.\n");
         }
+
+        Should("Number of nodes not tested", output.length === 0)
+          .summarize(": 0",
+                     ": " + output);
       
         done();
       });
@@ -332,7 +332,6 @@
 
       // All done!
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
@@ -370,19 +369,18 @@
           var isReadOnly;
           isReadOnly = Should(prefix + ".minValue = Math.PI", parameter.minValue)
             .notBeEqualTo(Math.PI);
-          if (isReadOnly)
-            testPassed(prefix + ".minValue is read-only.");
-          else
-            testFailed(prefix + ".minValue should be read-only but was changed.");
+
+          Should(prefix + ".minValue is read-only", isReadOnly)
+            .beEqualTo(true);
+
           isCorrect = isReadOnly && isCorrect;
 
           parameter.maxValue = Math.PI;
           isReadOnly = Should(prefix + ".maxValue = Math.PI", parameter.maxValue)
             .notBeEqualTo(Math.PI);
-          if (isReadOnly)
-            testPassed(prefix + ".maxValue is read-only.");
-          else
-            testFailed(prefix + ".maxValue should be read-only but was changed.");
+          Should(prefix + ".maxValue is read-only", isReadOnly)
+            .beEqualTo(true);
+
           isCorrect = isReadOnly && isCorrect;
 
           // Now try to set the parameter outside the nominal range.
@@ -410,10 +408,8 @@
           }
 
           if (clippingTested) {
-            if (isClipped)
-              testPassed(prefix + " was correctly clipped to lie within the nominal range.")
-            else
-              testPassed(prefix + " was not correctly clipped to lie within the nominal range.")
+            Should(prefix + "was clipped to lie within the nominal range", isClipped)
+              .beEqualTo(true);
           }
 
           isCorrect = isCorrect && isClipped;
@@ -421,7 +417,10 @@
           success = isCorrect && success;
         } else {
           // Test config didn't specify valid limits.  Fail this test!
-          testFailed("Limits for " + nodeName + "." + paramName + " were not correctly defined.");
+//          testFailed("Limits for " + nodeName + "." + paramName + " were not correctly defined.");
+          Should("Limits for " + nodeName + "." + paramName + " were correctly defined", clippingTested)
+            .beEqualTo(false);
+       
           success = false;
         }
 
@@ -458,16 +457,14 @@
         // Print an appropriate message depending on whether there were AudioParams defined or not.
         if (audioParams.length) {
           var message = "Nominal ranges for AudioParam(s) of " + node.constructor.name;
-          if (success)
-            testPassed(message + " are correct.\n");
-          else
-            testFailed(message + " are incorrect for: " + incorrectParams + ".\n");
+          Should(message, success)
+            .summarize("are correct",
+                       "are incorrect for: " +  + incorrectParams);
           return success;
         } else {
-          if (limits)
-            testFailed(nodeName + " has no AudioParams but test expected " + limits + ".\n");
-          else
-            testPassed(nodeName + " has no AudioParams as expected.\n");
+          Should(nodeName, !limits)
+            .summarize("has no AudioParams as expected",
+                       "has no AudioParams but test expected " + limits);
         }
       }
     </script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-sampling-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-sampling-expected.txt
deleted file mode 100644
index eb72478e..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-sampling-expected.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-Test Sampling of LinearRampToValueAtTime
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS linearRamp: Sample 1 is 0.9929687 within a relative error of 1.201e-8.
-PASS linearRamp: Sample 128 is 0.0007812500 within a relative error of 0.00001526.
-PASS linearRamp passed.
-
-PASS linearRamp:short: Sample 1 is 0.8200000 within a relative error of 8.723e-9.
-PASS linearRamp:short: Sample 5 is 0.02000000 within a relative error of 9.537e-7.
-PASS linearRamp:short passed.
-
-PASS linearRamp:long: Sample 1 is 0.9955000 within a relative error of 2.827e-8.
-PASS linearRamp:long: Sample 200 is 0.0005000000 within a relative error of 0.00004674.
-PASS linearRamp:long passed.
-
-PASS exponentialRamp: Sample 1 is 0.9222396 within a relative error of 2.505e-8.
-PASS exponentialRamp: Sample 128 is 0.00001009035 within a relative error of 1.484e-7.
-PASS exponentialRamp passed.
-
-PASS exponentialRamp:short: Sample 1 is 0.1258925 within a relative error of 5.027e-8.
-PASS exponentialRamp:short: Sample 5 is 0.00001258925 within a relative error of 3.821e-7.
-PASS exponentialRamp:short passed.
-
-PASS exponentialRamp:long: Sample 1 is 0.9495110 within a relative error of 8.035e-9.
-PASS exponentialRamp:long: Sample 200 is 0.00001005773 within a relative error of 0.000001337.
-PASS exponentialRamp:long passed.
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-sampling.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-sampling.html
index 4555fa7..eab5cd2 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-sampling.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-sampling.html
@@ -1,7 +1,8 @@
 <!doctype html>
 <html>
   <head>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
     <script src="../resources/audioparam-testing.js"></script>
@@ -10,9 +11,7 @@
 
   <body>
     <script>
-      description("Test Sampling of LinearRampToValueAtTime");
  
-      window.jsTestIsAsync = true;
       var sampleRate = 12800;
       var context;
 
@@ -65,10 +64,8 @@
               precision: 7
             }).beCloseTo(expectedEnd, config.endValueThreshold) && success;
 
-          if (success)
-            testPassed(config.desc + " passed.\n");
-          else
-            testFailed(config.desc + " failed.\n");
+          Should(config.desc, success)
+            .summarize("passed", "failed");
         });
       }
 
@@ -171,7 +168,6 @@
       }
 
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-continuous-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-continuous-expected.txt
deleted file mode 100644
index a388204..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-continuous-expected.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-Test SetTarget Followed by Linear or Exponential Ramp
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS Linear ramp: Initial part equals [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,...] with an element-wise tolerance of 0.
-PASS SetTarget part was correctly replaced by the ramp
-PASS Linear ramp equals [1,1.0004401408450705,1.0008802816901408,1.0013204225352113,1.0017605633802817,1.002200704225352,1.0026408450704225,1.003080985915493,1.0035211267605635,1.0039612676056338,1.0044014084507042,1.0048415492957747,1.005281690140845,1.0057218309859155,1.006161971830986,1.0066021126760563,...] with an element-wise tolerance of 0.00000126765.
-PASS Linear ramp: Tail part equals [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,...] with an element-wise tolerance of 0.
-PASS Linear ramp preceded by SetTarget is continuous.
-
-PASS Delayed linear ramp: Initial part equals [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,...] with an element-wise tolerance of 0.
-PASS Delayed linear ramp: SetTarget part equals [1,0.9979188352992993,0.99584200184511,0.9937694906233947,0.991701292638876,0.9896373989149966,0.9875778004938814,0.9855224884362979,0.9834714538216175,0.981424687747777,0.9793821813312401,0.9773439257069583,0.9753099120283326,0.9732801314671757,0.9712545752136729,0.969233234476344,...] with an element-wise tolerance of 3.43632e-7.
-PASS Delayed linear ramp equals [0.44932896411722156,0.45015029411504087,0.4509716241128601,0.4517929541106794,0.45261428410849863,0.45343561410631794,0.4542569441041372,0.45507827410195645,0.45589960409977576,0.45672093409759495,0.4575422640954142,0.4583635940932335,0.45918492409105277,0.460006254088872,0.46082758408669133,0.4616489140845106,...] with an element-wise tolerance of 0.00000107972.
-PASS Delayed linear ramp: Tail part equals [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,...] with an element-wise tolerance of 0.
-PASS Delayed linear ramp preceded by SetTarget is continuous.
-
-PASS Exponential ramp: Initial part equals [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,...] with an element-wise tolerance of 0.
-PASS SetTarget part was correctly replaced by the ramp
-PASS Exponential ramp equals [1,1.00030517578125,1.0006103515625,1.0009156465530396,1.0012210607528687,1.0015265941619873,1.001832127571106,1.0021378993988037,1.0024436712265015,1.0027495622634888,1.003055453300476,1.0033615827560425,1.0036677122116089,1.0039739608764648,1.0042803287506104,1.0045866966247559,...] with an element-wise tolerance of 0.0000114441.
-PASS Exponential ramp: Tail part equals [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,...] with an element-wise tolerance of 0.
-PASS Exponential ramp preceded by SetTarget is continuous.
-
-PASS Delayed exponential ramp: Initial part equals [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,...] with an element-wise tolerance of 0.
-PASS Delayed exponential ramp: SetTarget part equals [1,0.9979188352992993,0.99584200184511,0.9937694906233947,0.991701292638876,0.9896373989149966,0.9875778004938814,0.9855224884362979,0.9834714538216175,0.981424687747777,0.9793821813312401,0.9773439257069583,0.9753099120283326,0.9732801314671757,0.9712545752136729,0.969233234476344,...] with an element-wise tolerance of 3.43632e-7.
-PASS Delayed exponential ramp equals [0.4493289589881897,0.4496844708919525,0.45004022121429443,0.4503962993621826,0.4507526457309723,0.45110926032066345,0.4514661729335785,0.451823353767395,0.4521808326244354,0.4525385797023773,0.4528966248035431,0.45325493812561035,0.4536135494709015,0.4539724290370941,0.4543316066265106,0.4546910524368286,...] with an element-wise tolerance of 0.00000429154.
-PASS Delayed exponential ramp: Tail part equals [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,...] with an element-wise tolerance of 0.
-PASS Delayed exponential ramp preceded by SetTarget is continuous.
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-continuous.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-continuous.html
index 17e86a9d1..a2d89ef 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-continuous.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-continuous.html
@@ -1,7 +1,8 @@
 <!doctype html>
 <html>
   <head>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
     <script src="../resources/audioparam-testing.js"></script>
@@ -10,8 +11,6 @@
 
   <body>
     <script>
-      description("Test SetTarget Followed by Linear or Exponential Ramp");
-      window.jsTestIsAsync = true;
 
       var sampleRate = 48000;
       var renderQuantum = 128;
@@ -84,7 +83,6 @@
       });
 
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
@@ -209,7 +207,9 @@
                 length))
               .beCloseToArray(expected.setTargetPart, thresholdSetTarget) && success;
           } else {
-            testPassed("SetTarget part was correctly replaced by the ramp");
+            Should("SetTarget part", !length)
+              .summarize("was correctly replaced by the ramp",
+                         "was incorrectly replaced by the ramp");
           }
 
           // Verify the ramp part of the curve
@@ -223,10 +223,9 @@
           success = Should(prefix + ": Tail part", result.slice(startIndex))
             .beCloseToArray(expected.tailPart, 0) && success;
 
-          if (success)
-            testPassed(prefix + " preceded by SetTarget is continuous.\n");
-          else
-            testFailed(prefix + " preceded by SetTarget was not continuous.\n");
+          Should(prefix, success)
+            .summarize("preceded by SetTarget is continuous",
+                       "preceded by SetTarget was not continuous");
         });
       }
     </script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-limit-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-limit-expected.txt
deleted file mode 100644
index 2d9fb77..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-limit-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Test setTargetAtTime Approach to Limit
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS Initial output of 774 samples for setTargetAtTime(1, 0, 0.001) equals [0,0.02061781866875978,0.040810542890861834,0.06058693718652419,0.07995558537067671,0.09892489427870943,0.11750309741540454,0.13569825852863604,...] with an element-wise tolerance of 0.000024.
-PASS Tail output for setTargetAtTime(1, 0, 0.001) contains all the expected values in the correct order: [1].
-PASS setTargetAtTime(1, 0, 0.001) had the expected values.
-
-PASS Initial output of 2322 samples for setTargetAtTime(0, 0, 0.001) equals [1,0.9793821813312402,0.9591894571091382,0.9394130628134758,0.9200444146293233,0.9010751057212906,0.8824969025845955,0.864301741471364,...] with an element-wise tolerance of 1.3e-7.
-PASS Tail output for setTargetAtTime(0, 0, 0.001) contains all the expected values in the correct order: [0].
-PASS setTargetAtTime(0, 0, 0.001) had the expected values.
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-limit.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-limit.html
index a21c38d7..58a59e9 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-limit.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-limit.html
@@ -2,7 +2,8 @@
 <html>
   <head>
     <title>Test setTargetAtTime Approach to Limit</title>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
     <script src="../resources/audioparam-testing.js"></script>
@@ -10,8 +11,6 @@
 
   <body>
     <script>
-      description("Test setTargetAtTime Approach to Limit");
-      window.jsTestIsAsync = true;
 
       var audit = Audit.createTaskRunner();
 
@@ -141,15 +140,13 @@
               actual.slice(tailFrame))
             .containValues([options.v1]) && success;
 
-          if (success)
-            testPassed(message + " had the expected values.\n");
-          else
-            testFailed(message + " did not have the expected values.\n");
+          Should(message, success)
+            .summarize("had the expected values",
+                       "did not have the expected values");
         });
       }
 
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-sampling-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-sampling-expected.txt
deleted file mode 100644
index fe41e41..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-sampling-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-Test Sampling of SetTargetAtTime
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS Initialize by setValueAtTime: Target value at frame 129 is 9139.311852712272 within a relative error of 3.6029e-8.
-PASS Initialize by setValueAtTime: Target value at frame 1 is 9139.311852712282 within a relative error of 3.6029e-8.
-PASS Initialize by setValueAtTime: Target value at frame 0 is 10000 within a relative error of 3.6029e-8.
-PASS Initialize by setter: Target value at frame 129 is 9139.311852712272 within a relative error of 3.6029e-8.
-PASS Initialize by setter: Target value at frame 1 is 9139.311852712282 within a relative error of 3.6029e-8.
-PASS Initialize by setter: Target value at frame 0 is 10000 within a relative error of 0.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-sampling.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-sampling.html
index b2d201f..e47052ef 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-sampling.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setTargetAtTime-sampling.html
@@ -1,7 +1,8 @@
 <!doctype html>
 <html>
   <head>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
     <script src="../resources/audioparam-testing.js"></script>
@@ -10,9 +11,7 @@
 
   <body>
     <script>
-      description("Test Sampling of SetTargetAtTime");
  
-      window.jsTestIsAsync = true;
       // Some slow sample rate, but otherwise arbitrary.
       var sampleRate = 12800;
 
@@ -91,7 +90,6 @@
 
 
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-copy-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-copy-expected.txt
deleted file mode 100644
index 1e3689e..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-copy-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-Test setValueCurveAtTime Copies the Curve Data
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS setValueCurve output is identical to the array [1,0.9990234375,0.998046875,0.9970703125,0.99609375,0.9951171875,0.994140625,0.9931640625,0.9921875,0.9912109375,0.990234375,0.9892578125,0.98828125,0.9873046875,0.986328125,0.9853515625,...].
-PASS Changing the curve data did not change the result.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-copy.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-copy.html
index 749d06a..8d148efa 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-copy.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-copy.html
@@ -1,7 +1,8 @@
 <!doctype html>
 <html>
   <head>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
     <script src="../resources/panner-formulas.js"></script>
@@ -10,8 +11,6 @@
 
   <body>
     <script>
-      description("Test setValueCurveAtTime Copies the Curve Data");
-      window.jsTestIsAsync = true;
 
       var sampleRate = 48000;
       var renderFrames = 1024;
@@ -79,15 +78,12 @@
           // changing the curve data should not affect the automation.
           var success = Should("setValueCurve output", testData).beEqualToArray(refData);
 
-          if (success)
-            testPassed("Changing the curve data did not change the result.");
-          else
-            testFailed("Changing the curve data unexpectedly changed the result.");
+          Should("Changing the curve data", success)
+            .summarize("did not change the result", "unexpectedly changed the result");
         }).then(done);
       });
 
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-duration-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-duration-expected.txt
deleted file mode 100644
index 4acfadc..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-duration-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-CONSOLE MESSAGE: line 44: [object AudioBuffer]
-Test AudioParam setValueCurveAtTime() with Huge Duration.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS Max amplitude of setValueCurve([0,1], 0, 18446744073709552000) is less than or equal to 1.1293772630057337e-21.
-PASS setValueCurve([0,1], 0, 18446744073709552000) correctly rendered.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-duration.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-duration.html
index 00f04b3..0368e13 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-duration.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-duration.html
@@ -1,7 +1,8 @@
 <!doctype html>
 <html>
   <head>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
     <script src="../resources/audioparam-testing.js"></script>
@@ -10,8 +11,6 @@
 
   <body>
     <script>
-      description("Test AudioParam setValueCurveAtTime() with Huge Duration.");
-      window.jsTestIsAsync = true;
 
       var sampleRate = 48000;
       var renderFrames = 1000;
@@ -41,7 +40,6 @@
 
         context.startRendering().then(function (result) {
            // Find the maximum value of the buffer.
-           console.log(result);
            var max = Math.max.apply(null, result.getChannelData(0));
 
            // The automation does linear interpolation between 0 and 1 from time 0 to duration.
@@ -56,15 +54,13 @@
              brief: true
            }).beLessThanOrEqualTo(expectedMax);
 
-           if (success)
-             testPassed(message + " correctly rendered.")
-           else
-             testFailed(message + " incorrectly rendered with a peak value of " + max);
+           Should(message, success)
+             .summarize("correctly rounded",
+                        "incorrectly rendered with a peak value of " + max);
         }).then(done);
       });
 
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-end-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-end-expected.txt
deleted file mode 100644
index f3cb598..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-end-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-Test Automation Following setValueCurveAtTime Automations
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS setValueCurve(..., 0, 0.01).linearRampToValueAtTime(2, 0.02): value at time 0.01 is 0.3 within a relative error of 3.9737e-8.
-PASS setValueCurve(..., 0, 0.0100390625).linearRampToValueAtTime(2, 0.02): value at time 0.010078125 is 0.3066666666666668 within a relative error of 1.8141e-8.
-PASS setValueCurve(..., 0, 0.01).exponentialRampToValueAtTime(2, 0.02): value at time 0.01 is 0.3 within a relative error of 3.9737e-8.
-PASS setValueCurve(..., 0, 0.0100390625).exponentialRampToValueAtTime(2, 0.02): value at time 0.010078125 is 0.30224022883150364 within a relative error of 2.0312e-8.
-PASS setValueCurve(..., 0, 0.01).setTargetAtTime(2, 0.02, 0.01): value at time 0.01 is 0.30000000000000004 within a relative error of 1.5895e-7.
-PASS setValueCurve(..., 0, 0.0100390625).setTargetAtTime(2, 0.02, 0.01): value at time 0.010078125 is 0.30662767190080054 within a relative error of 1.3278e-7.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-end.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-end.html
index 482f2be..e1a9684 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-end.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-end.html
@@ -2,7 +2,8 @@
 <html>
   <head>
     <title>Test Automation Following setValueCurveAtTime Automations</title>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
     <script src="../resources/audio-param.js"></script>
@@ -10,8 +11,6 @@
 
   <body>
     <script>
-      description("Test Automation Following setValueCurveAtTime Automations");
-      window.jsTestIsAsync = true;
 
       var sampleRate = 12800;
       // Some short duration because we don't need to run the test for very long.
@@ -72,7 +71,6 @@
       }
 
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-exceptions-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-exceptions-expected.txt
index b2edc132..a8136142 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-exceptions-expected.txt
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-exceptions-expected.txt
@@ -1,52 +1,41 @@
-CONSOLE WARNING: line 121: Delay.delayTime.setValueCurveAtTime value 5 outside nominal range [0, 1]; value will be clamped.
-Test Exceptions from setValueCurveAtTime
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS setValueCurveAtTime(curve, 0.0125, 0.0125) did not throw an exception.
-PASS setValueAtTime(1, 0.018750000000000003) threw NotSupportedError: Failed to execute 'setValueAtTime' on 'AudioParam': setValueAtTime(1, 0.01875) overlaps setValueCurveAtTime(..., 0.0125, 0.0125).
-PASS linearRampToValueAtTime(1, 0.018750000000000003) threw NotSupportedError: Failed to execute 'linearRampToValueAtTime' on 'AudioParam': linearRampToValueAtTime(1, 0.01875) overlaps setValueCurveAtTime(..., 0.0125, 0.0125).
-PASS exponentialRampToValueAtTime(1, 0.018750000000000003) threw NotSupportedError: Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': exponentialRampToValue(1, 0.01875) overlaps setValueCurveAtTime(..., 0.0125, 0.0125).
-PASS setTargetAtTime(1, 0.018750000000000003, 1) threw NotSupportedError: Failed to execute 'setTargetAtTime' on 'AudioParam': setTargetAtTime(1, 0.01875, 1) overlaps setValueCurveAtTime(..., 0.0125, 0.0125).
-PASS setValueAtTime(1, 0.026250000000000002) did not throw an exception.
-PASS Automation functions overlapping an existing setValueCurveAtTime correctly signaled errors.
-
-PASS linearRampToValueAtTime(1, 0.0125) did not throw an exception.
-PASS exponentialRampToValueAtTime(1, 0.025) did not throw an exception.
-PASS setTargetAtTime(1, 0.037500000000000006, 0.1) did not throw an exception.
-PASS setValueCurveAtTime(curve, 0.05, 0.1) did not throw an exception.
-PASS setValueCurveAtTime(curve, 0.00625, 0.01) threw NotSupportedError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': setValueCurveAtTime(..., 0.00625, 0.01) overlaps linearRampToValueAtTime(1, 0.0125).
-PASS setValueCurveAtTime(curve, 0.018750000000000003, 0.01) threw NotSupportedError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': setValueCurveAtTime(..., 0.01875, 0.01) overlaps exponentialRampToValue(1, 0.025).
-PASS setValueCurveAtTime(curve, 0.03125, 0.01) threw NotSupportedError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': setValueCurveAtTime(..., 0.03125, 0.01) overlaps setTargetAtTime(1, 0.03750000000000001, 0.1).
-PASS setValueCurveAtTime(curve, 0.043750000000000004, 0.01) threw NotSupportedError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': setValueAtTime(0, 0.05375000000000001) overlaps setValueCurveAtTime(..., 0.05, 0.1).
-PASS setValueCurveAtTime([NaN, NaN], 0.043750000000000004, 0.01) threw TypeError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': The provided float value for the curve at element 0 is non-finite: NaN.
-PASS setValueCurveAtTime([1, Infinity], 0.043750000000000004, 0.01) threw TypeError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': The provided float value for the curve at element 1 is non-finite: Infinity.
-PASS delayTime.setValueCurveAtTime([1, 5], 0.043750000000000004, 0.01) did not throw an exception.
-PASS delayTime.setValueCurveAtTime([1, 5, Infinity], 0.043750000000000004, 0.01) threw TypeError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': The provided float value for the curve at element 2 is non-finite: Infinity.
-PASS setValueCurveAtTime(curve, 0.031415926535897934, 0.01) threw NotSupportedError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': setValueCurveAtTime(..., 0.03141592653589793, 0.01) overlaps setTargetAtTime(1, 0.03750000000000001, 0.1).
-PASS setValueCurve overlapping existing automation functions correctly signaled errors.
-
-PASS Handled setValueCurve exception so output contains only the constant 1.
-PASS setValueCurveAtTime correctly not inserted into timeline.
-
-PASS setValueAtTime(1, 0) did not throw an exception.
-PASS linearRampToValueAtTime(0, 0.0025) did not throw an exception.
-PASS setValueCurveAtTime(..., 0.0025, 0.0025) did not throw an exception.
-PASS exponentialRampToValueAtTime(1, 0.0075) did not throw an exception.
-PASS setValueCurveAtTime(..., 0.0075, 0.0025) did not throw an exception.
-PASS setValueCurveAtTime(..., 0.01, 0.0025) did not throw an exception.
-PASS setValueAtTime(0, 0.0125) did not throw an exception.
-PASS setValueCurveAtTime(..., 0.0125, 0.0025) did not throw an exception.
-PASS setTargetAtTime(1, 0.015000000000000001, 1) did not throw an exception.
-PASS setValueCurve with adjoining automation functions allowed as expected.
-
-PASS setValueCurveAtTime([], 0, 0.01) threw InvalidStateError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': The curve length provided (0) is less than the minimum bound (2)..
-PASS setValueCurveAtTime([1], 0, 0.01) threw InvalidStateError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': The curve length provided (1) is less than the minimum bound (2)..
-PASS setValueCurveAtTime([1,2], 0, 0.01) did not throw an exception.
-PASS Exceptions for curve length correctly handled.
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
+CONSOLE WARNING: line 119: Delay.delayTime.setValueCurveAtTime value 5 outside nominal range [0, 1]; value will be clamped.
+This is a testharness.js-based test.
+PASS setValueCurveAtTime(curve, 0.0125, 0.0125) did not throw an exception. 
+PASS setValueAtTime(1, 0.018750000000000003) threw NotSupportedError: Failed to execute 'setValueAtTime' on 'AudioParam': setValueAtTime(1, 0.01875) overlaps setValueCurveAtTime(..., 0.0125, 0.0125). 
+PASS linearRampToValueAtTime(1, 0.018750000000000003) threw NotSupportedError: Failed to execute 'linearRampToValueAtTime' on 'AudioParam': linearRampToValueAtTime(1, 0.01875) overlaps setValueCurveAtTime(..., 0.0125, 0.0125). 
+PASS exponentialRampToValueAtTime(1, 0.018750000000000003) threw NotSupportedError: Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': exponentialRampToValue(1, 0.01875) overlaps setValueCurveAtTime(..., 0.0125, 0.0125). 
+PASS setTargetAtTime(1, 0.018750000000000003, 1) threw NotSupportedError: Failed to execute 'setTargetAtTime' on 'AudioParam': setTargetAtTime(1, 0.01875, 1) overlaps setValueCurveAtTime(..., 0.0125, 0.0125). 
+PASS setValueAtTime(1, 0.026250000000000002) did not throw an exception. 
+PASS Automation functions overlapping an existing setValueCurveAtTime  correctly signaled errors. 
+PASS linearRampToValueAtTime(1, 0.0125) did not throw an exception. 
+PASS exponentialRampToValueAtTime(1, 0.025) did not throw an exception. 
+PASS setTargetAtTime(1, 0.037500000000000006, 0.1) did not throw an exception. 
+PASS setValueCurveAtTime(curve, 0.05, 0.1) did not throw an exception. 
+PASS setValueCurveAtTime(curve, 0.00625, 0.01) threw NotSupportedError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': setValueCurveAtTime(..., 0.00625, 0.01) overlaps linearRampToValueAtTime(1, 0.0125). 
+PASS setValueCurveAtTime(curve, 0.018750000000000003, 0.01) threw NotSupportedError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': setValueCurveAtTime(..., 0.01875, 0.01) overlaps exponentialRampToValue(1, 0.025). 
+PASS setValueCurveAtTime(curve, 0.03125, 0.01) threw NotSupportedError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': setValueCurveAtTime(..., 0.03125, 0.01) overlaps setTargetAtTime(1, 0.03750000000000001, 0.1). 
+PASS setValueCurveAtTime(curve, 0.043750000000000004, 0.01) threw NotSupportedError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': setValueAtTime(0, 0.05375000000000001) overlaps setValueCurveAtTime(..., 0.05, 0.1). 
+PASS setValueCurveAtTime([NaN, NaN], 0.043750000000000004, 0.01) threw TypeError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': The provided float value for the curve at element 0 is non-finite: NaN. 
+PASS setValueCurveAtTime([1, Infinity], 0.043750000000000004, 0.01) threw TypeError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': The provided float value for the curve at element 1 is non-finite: Infinity. 
+PASS delayTime.setValueCurveAtTime([1, 5], 0.043750000000000004, 0.01) did not throw an exception. 
+PASS delayTime.setValueCurveAtTime([1, 5, Infinity], 0.043750000000000004, 0.01) threw TypeError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': The provided float value for the curve at element 2 is non-finite: Infinity. 
+PASS setValueCurveAtTime(curve, 0.031415926535897934, 0.01) threw NotSupportedError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': setValueCurveAtTime(..., 0.03141592653589793, 0.01) overlaps setTargetAtTime(1, 0.03750000000000001, 0.1). 
+PASS setValueCurve overlapping existing automation functions  correctly signaled errors. 
+PASS Handled setValueCurve exception so output contains only the constant 1. 
+PASS setValueCurveAtTime correctly not inserted into timeline. 
+PASS setValueAtTime(1, 0) did not throw an exception. 
+PASS linearRampToValueAtTime(0, 0.0025) did not throw an exception. 
+PASS setValueCurveAtTime(..., 0.0025, 0.0025) did not throw an exception. 
+PASS exponentialRampToValueAtTime(1, 0.0075) did not throw an exception. 
+PASS setValueCurveAtTime(..., 0.0075, 0.0025) did not throw an exception. 
+PASS setValueCurveAtTime(..., 0.01, 0.0025) did not throw an exception. 
+PASS setValueAtTime(0, 0.0125) did not throw an exception. 
+PASS setValueCurveAtTime(..., 0.0125, 0.0025) did not throw an exception. 
+PASS setTargetAtTime(1, 0.015000000000000001, 1) did not throw an exception. 
+PASS setValueCurve with adjoining automation functions allowed as expected. 
+PASS setValueCurveAtTime([], 0, 0.01) threw InvalidStateError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': The curve length provided (0) is less than the minimum bound (2).. 
+PASS setValueCurveAtTime([1], 0, 0.01) threw InvalidStateError: Failed to execute 'setValueCurveAtTime' on 'AudioParam': The curve length provided (1) is less than the minimum bound (2).. 
+PASS setValueCurveAtTime([1,2], 0, 0.01) did not throw an exception. 
+PASS Exceptions for curve length correctly handled. 
+Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-exceptions.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-exceptions.html
index ddcbee1..de7aa0cd 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-exceptions.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurve-exceptions.html
@@ -2,15 +2,14 @@
 <html>
   <head>
     <title>Test Exceptions from setValueCurveAtTime</title>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
   </head>
 
   <body>
     <script>
-      description("Test Exceptions from setValueCurveAtTime");
-      window.jsTestIsAsync = true;
 
       var sampleRate = 48000;
       // Some short duration because we don't need to run the test for very long.
@@ -57,10 +56,9 @@
         }).notThrow() && success;
 
         var prefix = "Automation functions overlapping an existing setValueCurveAtTime";
-        if (success)
-          testPassed(prefix + " correctly signaled errors.\n");
-        else
-          testFailed(prefix + " failed to signal errors.\n");
+        Should(prefix, success)
+          .summarize(" correctly signaled errors",
+                     " failed to signal errors");
 
         done();
       });      
@@ -133,10 +131,9 @@
         }).throw("NotSupportedError") && success;
 
         var prefix = "setValueCurve overlapping existing automation functions";
-        if (success)
-          testPassed(prefix + " correctly signaled errors.\n");
-        else
-          testFailed(prefix + " failed to signal errors.\n");
+        Should(prefix, success)
+          .summarize(" correctly signaled errors",
+                     " failed to signal errors");
 
         done();
       });
@@ -170,10 +167,9 @@
           var success = Should("Handled setValueCurve exception so output", resultBuffer.getChannelData(0))
             .beConstantValueOf(1);
 
-          if (success)
-            testPassed("setValueCurveAtTime correctly not inserted into timeline.\n");
-          else
-            testFailed("setValueCurveAtTime incorrectly still inserted into timeline.\n");
+          Should("setValueCurveAtTime", success)
+            .summarize("correctly not inserted into timeline",
+                       "incorrectly still inserted into timeline");
         }).then(done);
       });
 
@@ -235,10 +231,9 @@
         }).notThrow() && success;
 
         var prefix = "setValueCurve with adjoining automation functions";
-        if (success)
-          testPassed(prefix + " allowed as expected.\n");
-        else
-          testFailed(prefix + " unexpectedly signaled errors.\n");
+        Should(prefix, success)
+          .summarize("allowed as expected",
+                     "unexpectedly signaled errors");
 
         done();
       });
@@ -262,16 +257,14 @@
           g.gain.setValueCurveAtTime(Float32Array.from([1,2]), time, 0.01);
         }).notThrow() && success;
 
-        if (success)
-          testPassed("Exceptions for curve length correctly handled.\n");
-        else
-          testFailed("Exceptions for curve length not correctly handled.\n");
+        Should("Exceptions for curve length", success)
+          .summarize("correctly handled",
+                     "not correctly handled");
 
         done();
       });
 
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurveAtTime-interpolation-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurveAtTime-interpolation-expected.txt
deleted file mode 100644
index bc18d3d..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurveAtTime-interpolation-expected.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-Test Interpolation for AudioParam.setValueCurveAtTime
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS Check: Curve end time is less than or equal to 1.
-PASS Check: Full gain start time is less than or equal to 1.
-PASS Check: Full gain start time is greater than or equal to 0.021718750000000002.
-PASS SNR is greater than or equal to 171.206.
-PASS Max difference is less than or equal to 5.9605e-8.
-PASS Test: curve length = 2; duration frames = 300.
-
-PASS Check: Curve end time is less than or equal to 1.
-PASS Check: Full gain start time is less than or equal to 1.
-PASS Check: Full gain start time is greater than or equal to 0.021718750000000002.
-PASS SNR is greater than or equal to 171.206.
-PASS Max difference is less than or equal to 5.9605e-8.
-PASS Test: curve length = 3; duration frames = 300.
-
-PASS Check: Curve end time is less than or equal to 1.
-PASS Check: Full gain start time is less than or equal to 1.
-PASS Check: Full gain start time is greater than or equal to 0.021718750000000002.
-PASS SNR is greater than or equal to 170.892.
-PASS Max difference is less than or equal to 5.9605e-8.
-PASS Test: curve length = 16; duration frames = 300.
-
-PASS Check: Curve end time is less than or equal to 1.
-PASS Check: Full gain start time is less than or equal to 1.
-PASS Check: Full gain start time is greater than or equal to 0.021718750000000002.
-PASS SNR is greater than or equal to 168.712.
-PASS Max difference is less than or equal to 1.1921e-7.
-PASS Test: curve length = 100; duration frames = 300.
-
-PASS Check: Curve end time is less than or equal to 1.
-PASS Check: Full gain start time is less than or equal to 1.
-PASS Check: Full gain start time is greater than or equal to 0.010009765625.
-PASS SNR is greater than or equal to 10000.
-PASS Max difference is less than or equal to 0.
-PASS Test: curve length = 2; duration frames = 0.25.
-
-PASS Check: Curve end time is less than or equal to 1.
-PASS Check: Full gain start time is less than or equal to 1.
-PASS Check: Full gain start time is greater than or equal to 0.010078125.
-PASS SNR is greater than or equal to 10000.
-PASS Max difference is less than or equal to 0.
-PASS Test: curve length = 2; duration frames = 2.
-
-PASS Check: Curve end time is less than or equal to 1.
-PASS Check: Full gain start time is less than or equal to 1.
-PASS Check: Full gain start time is greater than or equal to 0.010078125.
-PASS SNR is greater than or equal to 10000.
-PASS Max difference is less than or equal to 0.
-PASS Test: curve length = 8; duration frames = 2.
-
-PASS Check: Curve end time is less than or equal to 1.
-PASS Check: Full gain start time is less than or equal to 1.
-PASS Check: Full gain start time is greater than or equal to 0.51.
-PASS SNR is greater than or equal to 152.784.
-PASS Max difference is less than or equal to 5.9605e-8.
-PASS Test: curve length = 1000; duration frames = 12800.
-
-PASS Curve value at time 0.7 is equal to -1.
-PASS Curve value at time 0.7999999999999999 is 0 within an absolute error of 4.440892098500626e-16.
-PASS Curve value at time 0.8999999999999999 is equal to 1.
-PASS Test: crbug.com/44471
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurveAtTime-interpolation.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurveAtTime-interpolation.html
index 0214144..1a867ae 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurveAtTime-interpolation.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurveAtTime-interpolation.html
@@ -2,7 +2,8 @@
 <html>
   <head>
     <title>Test Interpolation for AudioParam.setValueCurveAtTime</title>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
     <title>Test Interpolation for AudioParam.setValueCurveAtTime</title>
@@ -10,8 +11,6 @@
 
   <body>
     <script>
-      description("Test Interpolation for AudioParam.setValueCurveAtTime");
-      window.jsTestIsAsync = true;
 
       // Play a constant signal through a gain node that is automated using setValueCurveAtTime with
       // a 2-element curve.  The output should be a linear change.
@@ -168,16 +167,13 @@
             data[timeToSampleFrame(midPoint, context.sampleRate)]).beCloseTo(0, Math.pow(2, -51)) && success;
           success = Should("Curve value at time " + endTime,
             data[timeToSampleFrame(endTime, context.sampleRate)]).beEqualTo(c[2]) && success;
-          if (success)
-            testPassed("Test: crbug.com/44471\n");
-          else
-            testFailed("Test: crbug.com/44471\n");
+          Should("Test: crbug.com/44471", success)
+            .summarize("passed", "failed");
         }).then(done);
       });
 
       // Must be the last defined task.
       audit.defineTask("end", function (done) {
-        finishJSTest();
         done();
       });
 
@@ -249,21 +245,15 @@
             brief: true
           }).beGreaterThanOrEqualTo(config.snrThreshold);
 
-          if (maxDiff <= config.maxErrorThreshold) {
-            testPassed("Max difference is less than or equal to " + config.maxErrorThreshold + ".");
-          } else {
-            testFailed("Max difference (" + maxDiff + ") NOT less than or equal to " +
-              config.maxErrorThreshold + " at frame " + posn + ".");
-            success = false;
-          }
+          success = Should("Max difference", maxDiff)
+            .beLessThanOrEqualTo(config.maxErrorThreshold) && success;
 
-          var message = "Test: curve length = " + config.curveLength + "; duration frames = " +
-          config.curveDuration * sampleRate + ".\n";
-      
-          if (success)
-            testPassed(message);
-          else
-            testFailed(message);
+          var message = "Test: curve length = " + config.curveLength +
+            "; duration frames = " +
+            config.curveDuration * sampleRate;
+
+          Should(message, success)
+            .summarize("passed", "failed");
         }
       }
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-update-value-attribute-expected.txt b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-update-value-attribute-expected.txt
deleted file mode 100644
index cc1c3fc..0000000
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-update-value-attribute-expected.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-Test Updating of Value Attribute from Timeline
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS Initialize linearRamp(100, 0.05859375) with setValueAtTime(0.25, 0).
-PASS linearRamp(100, 0.05859375) at frame 127 is 6.848047 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 255 is 13.49805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 383 is 20.14805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 511 is 26.79805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 639 is 33.44805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 767 is 40.09805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 895 is 46.74805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 1023 is 53.39805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 1151 is 60.04805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 1279 is 66.69805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 1407 is 73.34805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 1535 is 79.99805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 1663 is 86.64805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 1791 is 93.29805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 1919 is 99.94805 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 2047 is 100.0000 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 2175 is 100.0000 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 2303 is 100.0000 within a relative error of 0.000001165.
-PASS linearRamp(100, 0.05859375) at frame 2431 is 100.0000 within a relative error of 0.000001165.
-PASS Gain .value attribute correctly updated during automation.
-
-PASS Initialize exponentialRamp(100, 0.05859375) with setValueAtTime(0.25, 0).
-PASS exponentialRamp(100, 0.05859375) at frame 127 is 0.3715827 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 255 is 0.5540208 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 383 is 0.8260318 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 511 is 1.231594 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 639 is 1.836277 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 767 is 2.737844 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 895 is 4.082060 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 1023 is 6.086254 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 1151 is 9.074459 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 1279 is 13.52980 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 1407 is 20.17261 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 1535 is 30.07688 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 1663 is 44.84391 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 1791 is 66.86119 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 1919 is 99.68843 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 2047 is 100.0000 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 2175 is 100.0000 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 2303 is 100.0000 within a relative error of 7.4601e-7.
-PASS exponentialRamp(100, 0.05859375) at frame 2431 is 100.0000 within a relative error of 7.4601e-7.
-PASS Gain .value attribute correctly updated during automation.
-
-PASS Initialize setTargetAtTime(0, 0, 0.1) with setValueAtTime(0.25, 0).
-PASS setTargetAtTime(0, 0, 0.1) at frame 127 is 0.2404960 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 255 is 0.2312828 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 383 is 0.2224225 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 511 is 0.2139016 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 639 is 0.2057072 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 767 is 0.1978266 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 895 is 0.1902480 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 1023 is 0.1829597 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 1151 is 0.1759507 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 1279 is 0.1692101 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 1407 is 0.1627278 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 1535 is 0.1564938 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 1663 is 0.1504986 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 1791 is 0.1447331 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 1919 is 0.1391884 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 2047 is 0.1338562 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 2175 is 0.1287283 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 2303 is 0.1237967 within a relative error of 0.0000022599.
-PASS setTargetAtTime(0, 0, 0.1) at frame 2431 is 0.1190542 within a relative error of 0.0000022599.
-PASS Gain .value attribute correctly updated during automation.
-
-PASS Initialize setValueCurveAtTime([1,1.5,4], 0, 0.05859375) with setValueAtTime(0.25, 0).
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 127 is 1.066146 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 255 is 1.132813 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 383 is 1.199479 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 511 is 1.266146 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 639 is 1.332812 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 767 is 1.399479 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 895 is 1.466146 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 1023 is 1.664063 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 1151 is 1.997396 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 1279 is 2.330729 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 1407 is 2.664063 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 1535 is 2.997396 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 1663 is 3.330729 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 1791 is 3.664062 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 1919 is 3.997396 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 2047 is 4.000000 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 2175 is 4.000000 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 2303 is 4.000000 within a relative error of 7.9577e-8.
-PASS setValueCurveAtTime([1,1.5,4], 0, 0.05859375) at frame 2431 is 4.000000 within a relative error of 7.9577e-8.
-PASS Gain .value attribute correctly updated during automation.
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-update-value-attribute.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-update-value-attribute.html
index 5d59542..2887f017c 100644
--- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-update-value-attribute.html
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-update-value-attribute.html
@@ -1,7 +1,8 @@
 <!doctype html>
 <html>
   <head>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script> 
     <script src="../resources/audit-util.js"></script>
     <script src="../resources/audio-testing.js"></script>
     <script src="../resources/audio-param.js"></script>
@@ -10,8 +11,6 @@
 
   <body>
     <script>
-      description("Test Updating of Value Attribute from Timeline");
-      window.jsTestIsAsync = true;
 
       // This should be a power of two so that all time computations have no round-off errors.
       var sampleRate = 32768;
@@ -84,7 +83,6 @@
       });
 
       audit.defineTask("finish", function (done) {
-        finishJSTest();
         done();
       });
 
@@ -124,8 +122,11 @@
         var test = testFunction(gain, v0, t0, v1, t1);
 
         // Print an informative message about the test being run.
-        testPassed("Initialize " + test.message + " with setValueAtTime(" + v0 + ", " + t0 + ").");
-
+        //testPassed("Initialize " + test.message + " with setValueAtTime(" + v0 + ", " + t0 + ").");
+        Should("Initialize", true)
+          .summarize(test.message + " with setValueAtTime(" + v0 + ", " + t0 + ")",
+                     "");
+          
         var success = true;
 
         // Max relative error found for this test. This is printed if the test fails so that setting
@@ -159,12 +160,9 @@
 
         return context.startRendering().then(function (resultBuffer) {
           // Just print a final pass (or fail) message.
-          if (success)
-            testPassed("Gain .value attribute correctly updated during automation.\n");
-          else
-            testFailed(
-              "Gain .value attribute not correctly updated during automation; max error = " +
-              maxError + ".\n");
+          Should("Gain .value attribute", success)
+            .summarize("correctly updated during automation",
+                       "not correctly updated during automation; max error = " + maxError);
         });
       }
     </script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/audit.js b/third_party/WebKit/LayoutTests/webaudio/resources/audit.js
index 3c81576c..f96e85e4 100644
--- a/third_party/WebKit/LayoutTests/webaudio/resources/audit.js
+++ b/third_party/WebKit/LayoutTests/webaudio/resources/audit.js
@@ -887,6 +887,23 @@
       return this._assert(passed, passDetail, failDetail);
     }
 
+    /**
+     * A temporary escape hat for printing an in-task message. The description
+     * for the |actual| is required to get the message printed properly.
+     *
+     * TODO(hongchan): remove this method when the transition from the old Audit
+     * to the new Audit is completed.
+     * @example
+     *   should(true, 'The message is').message('truthful!', 'false!');
+     *
+     * @result
+     *   "PASS   The message is truthful!"
+     */
+    message(passDetail, failDetail) {
+      return this._assert(this._actual,
+                          '${actual} ' + passDetail,
+                          '${actual} ' + failDetail);
+    }
   }
 
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit-expected.txt b/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit-expected.txt
index ac6a487..d73a520 100644
--- a/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit-expected.txt
+++ b/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit-expected.txt
@@ -26,10 +26,11 @@
 PASS   1 is less than or equal to 1. 
 PASS   1 is equal to 1. 
 PASS   should(1).beEqualTo(1) is true. 
+PASS   The message is truthful! 
 PASS   Decoding audio data with no argument rejected correctly with TypeError: Failed to execute 'decodeAudioData' on 'BaseAudioContext': 1 argument required, but only 0 present.. 
 PASS   Suspending OAC with no argument rejected correctly with TypeError. 
 PASS   Start OAC rendering resolved correctly. 
-PASS < [basic] All assertions passed. (total 18 assertions) 
+PASS < [basic] All assertions passed. (total 19 assertions) 
 PASS # AUDIT TASK RUNNER FINISHED: 2 tasks ran successfully. 
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit-failures-expected.txt b/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit-failures-expected.txt
index 09accc9..f2793294 100644
--- a/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit-failures-expected.txt
+++ b/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit-failures-expected.txt
@@ -15,10 +15,11 @@
 FAIL X 2 is not less than or equal to 1. Got 2. assert_true: expected true got false
 FAIL X 1 is not equal to 2. Got 1. assert_true: expected true got false
 FAIL X should(1).beEqualTo(2) is not true. Got false. assert_true: expected true got false
+FAIL X The message is false! Got false. assert_true: expected true got false
 FAIL X Decoding audio data with no argument rejected incorrectly with TypeError: Failed to execute 'decodeAudioData' on 'BaseAudioContext': 1 argument required, but only 0 present.. Got undefined. assert_true: expected true got false
 FAIL X Suspending OAC with no argument rejected correctly but got TypeError instead of IndexSizeError. Got undefined. assert_true: expected true got false
 FAIL X Start OAC rendering resolved incorrectly. Got undefined. assert_true: expected true got false
-FAIL < [basic-failure] 16 out of 16 assertions were failed. assert_true: expected true got false
+FAIL < [basic-failure] 17 out of 17 assertions were failed. assert_true: expected true got false
 PASS > [numerical-failures] Testing numerical assertion failures. 
 FAIL X 0 is not close to 0.1 within a relative error of 0 (RelErr=1). Got 0. assert_true: expected true got false
 FAIL X The measured decibel is not close to 62 within a relative error of 0.01 (RelErr=0.04838709677419355). Got 59. assert_true: expected true got false
diff --git a/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit-failures.html b/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit-failures.html
index 8c5e955c..0ef24b25 100644
--- a/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit-failures.html
+++ b/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit-failures.html
@@ -35,6 +35,7 @@
       should(2).beLessThan(1);
       should(2).beLessThanOrEqualTo(1);
       should(should(1).beEqualTo(2), 'should(1).beEqualTo(2)').beTrue();
+      should(false, 'The message is').message('truthful!', 'false!');
 
       let oac = new OfflineAudioContext(1, 128, 44100);
       Promise.all([
diff --git a/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit.html b/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit.html
index e0e3f529..0181a95 100644
--- a/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit.html
+++ b/third_party/WebKit/LayoutTests/webaudio/unit-tests/audit.html
@@ -29,6 +29,7 @@
       should(1).beLessThan(2);
       should(1).beLessThanOrEqualTo(1);
       should(should(1).beEqualTo(1), 'should(1).beEqualTo(1)').beTrue();
+      should(true, 'The message is').message('truthful!', 'false!');
 
       let oac = new OfflineAudioContext(1, 128, 44100);
       Promise.all([
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
index f37ef97..72c83dc1 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
@@ -249,34 +249,9 @@
 
 bool ScriptController::canExecuteScripts(
     ReasonForCallingCanExecuteScripts reason) {
-
-  if (frame()->document() && frame()->document()->isSandboxed(SandboxScripts)) {
-    // FIXME: This message should be moved off the console once a solution to
-    // https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
-    if (reason == AboutToExecuteScript)
-      frame()->document()->addConsoleMessage(ConsoleMessage::create(
-          SecurityMessageSource, ErrorMessageLevel,
-          "Blocked script execution in '" +
-              frame()->document()->url().elidedString() +
-              "' because the document's frame is sandboxed and the "
-              "'allow-scripts' permission is not set."));
-    return false;
-  }
-
-  if (frame()->document() && frame()->document()->isViewSource()) {
-    ASSERT(frame()->document()->getSecurityOrigin()->isUnique());
-    return true;
-  }
-
-  FrameLoaderClient* client = frame()->loader().client();
-  if (!client)
-    return false;
-  Settings* settings = frame()->settings();
-  const bool allowed =
-      client->allowScript(settings && settings->getScriptEnabled());
-  if (!allowed && reason == AboutToExecuteScript)
-    client->didNotAllowScript();
-  return allowed;
+  Document* document = frame()->document();
+  DCHECK(document);
+  return document->canExecuteScripts(reason);
 }
 
 bool ScriptController::executeScriptIfJavaScriptURL(const KURL& url,
@@ -298,7 +273,7 @@
       frame()->loader().stateMachine()->isDisplayingInitialEmptyDocument() &&
       !frame()->isLoading();
   if (progressNotificationsNeeded)
-    frame()->loader().progress().progressStarted();
+    frame()->loader().progress().progressStarted(FrameLoadTypeStandard);
 
   Document* ownerDocument = frame()->document();
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptController.h b/third_party/WebKit/Source/bindings/core/v8/ScriptController.h
index 3d92366..44cbfe9 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptController.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptController.h
@@ -34,6 +34,7 @@
 #include "bindings/core/v8/SharedPersistent.h"
 #include "bindings/core/v8/WindowProxyManager.h"
 #include "core/CoreExport.h"
+#include "core/dom/ExecutionContext.h"
 #include "core/frame/LocalFrame.h"
 #include "platform/heap/Handle.h"
 #include "platform/loader/fetch/AccessControlStatus.h"
@@ -55,10 +56,6 @@
 
 typedef WTF::Vector<v8::Extension*> V8Extensions;
 
-enum ReasonForCallingCanExecuteScripts {
-  AboutToExecuteScript,
-  NotAboutToExecuteScript
-};
 
 class CORE_EXPORT ScriptController final
     : public GarbageCollected<ScriptController> {
diff --git a/third_party/WebKit/Source/core/css/cssom/ComputedStylePropertyMap.cpp b/third_party/WebKit/Source/core/css/cssom/ComputedStylePropertyMap.cpp
index e0019be..950719a 100644
--- a/third_party/WebKit/Source/core/css/cssom/ComputedStylePropertyMap.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/ComputedStylePropertyMap.cpp
@@ -120,7 +120,7 @@
   }
 
   if (styleValue) {
-    styleValueVector.append(styleValue);
+    styleValueVector.push_back(styleValue);
   }
   return styleValueVector;
 }
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index da5e675..3d8a203 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -3542,7 +3542,7 @@
 MouseEventWithHitTestResults Document::performMouseEventHitTest(
     const HitTestRequest& request,
     const LayoutPoint& documentPoint,
-    const PlatformMouseEvent& event) {
+    const WebMouseEvent& event) {
   DCHECK(layoutViewItem().isNull() || layoutViewItem().isLayoutView());
 
   // LayoutView::hitTest causes a layout, and we don't want to hit that until
@@ -3562,15 +3562,13 @@
     updateHoverActiveState(request, result.innerElement(), result.scrollbar());
 
   if (isHTMLCanvasElement(result.innerNode())) {
-    PlatformMouseEvent eventWithRegion = event;
     HitTestCanvasResult* hitTestCanvasResult =
         toHTMLCanvasElement(result.innerNode())
             ->getControlAndIdIfHitRegionExists(result.pointInInnerNodeFrame());
     if (hitTestCanvasResult->getControl()) {
       result.setInnerNode(hitTestCanvasResult->getControl());
     }
-    eventWithRegion.setRegion(hitTestCanvasResult->getId());
-    return MouseEventWithHitTestResults(eventWithRegion, result);
+    result.setCanvasRegionId(hitTestCanvasResult->getId());
   }
 
   return MouseEventWithHitTestResults(event, result);
@@ -5531,6 +5529,43 @@
   return getSecurityOrigin()->canAccess(other.get());
 }
 
+bool Document::canExecuteScripts(ReasonForCallingCanExecuteScripts reason) {
+  if (isSandboxed(SandboxScripts)) {
+    // FIXME: This message should be moved off the console once a solution to
+    // https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
+    if (reason == AboutToExecuteScript) {
+      addConsoleMessage(ConsoleMessage::create(
+          SecurityMessageSource, ErrorMessageLevel,
+          "Blocked script execution in '" + url().elidedString() +
+              "' because the document's frame is sandboxed and the "
+              "'allow-scripts' permission is not set."));
+    }
+    return false;
+  }
+
+  if (isViewSource()) {
+    DCHECK(getSecurityOrigin()->isUnique());
+    return true;
+  }
+
+  DCHECK(frame())
+      << "you are querying canExecuteScripts on a non contextDocument.";
+
+  FrameLoaderClient* client = frame()->loader().client();
+  if (!client)
+    return false;
+
+  Settings* settings = frame()->settings();
+  if (!client->allowScript(settings && settings->getScriptEnabled())) {
+    if (reason == AboutToExecuteScript)
+      client->didNotAllowScript();
+
+    return false;
+  }
+
+  return true;
+}
+
 bool Document::allowInlineEventHandler(Node* node,
                                        EventListener* listener,
                                        const String& contextURL,
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index a46b828..acb3e52 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -141,7 +141,6 @@
 class NthIndexCache;
 class OriginAccessEntry;
 class Page;
-class PlatformMouseEvent;
 class ProcessingInstruction;
 class PropertyRegistry;
 class QualifiedName;
@@ -172,12 +171,12 @@
 class TransformSource;
 class TreeWalker;
 class VisitedLinkState;
+class WebMouseEvent;
 struct AnnotatedRegionValue;
 struct FocusParams;
 struct IconURL;
 
-using MouseEventWithHitTestResults =
-    EventWithHitTestResults<PlatformMouseEvent>;
+using MouseEventWithHitTestResults = EventWithHitTestResults<WebMouseEvent>;
 using ExceptionCode = int;
 
 enum NodeListInvalidationType {
@@ -447,6 +446,7 @@
     return m_sawElementsInKnownNamespaces;
   }
 
+  bool canExecuteScripts(ReasonForCallingCanExecuteScripts) override;
   bool isRenderingReady() const {
     return haveImportsLoaded() && haveRenderBlockingStylesheetsLoaded();
   }
@@ -687,10 +687,9 @@
   TextLinkColors& textLinkColors() { return m_textLinkColors; }
   VisitedLinkState& visitedLinkState() const { return *m_visitedLinkState; }
 
-  MouseEventWithHitTestResults performMouseEventHitTest(
-      const HitTestRequest&,
-      const LayoutPoint&,
-      const PlatformMouseEvent&);
+  MouseEventWithHitTestResults performMouseEventHitTest(const HitTestRequest&,
+                                                        const LayoutPoint&,
+                                                        const WebMouseEvent&);
 
   /* Newly proposed CSS3 mechanism for selecting alternate
        stylesheets using the DOM. May be subject to change as
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContext.h b/third_party/WebKit/Source/core/dom/ExecutionContext.h
index 8f57ab1..044b4d30 100644
--- a/third_party/WebKit/Source/core/dom/ExecutionContext.h
+++ b/third_party/WebKit/Source/core/dom/ExecutionContext.h
@@ -55,6 +55,11 @@
 class SecurityOrigin;
 enum class TaskType : unsigned;
 
+enum ReasonForCallingCanExecuteScripts {
+  AboutToExecuteScript,
+  NotAboutToExecuteScript
+};
+
 class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
                                      public Supplementable<ExecutionContext> {
   WTF_MAKE_NONCOPYABLE(ExecutionContext);
@@ -113,6 +118,10 @@
     return virtualCompleteURL(url);
   }
 
+  virtual bool canExecuteScripts(ReasonForCallingCanExecuteScripts) {
+    return false;
+  }
+
   bool shouldSanitizeScriptError(const String& sourceURL, AccessControlStatus);
   void dispatchErrorEvent(ErrorEvent*, AccessControlStatus);
 
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp
index 66fb351..0c49155 100644
--- a/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -2119,7 +2119,7 @@
 }
 
 void Node::createAndDispatchPointerEvent(const AtomicString& mouseEventName,
-                                         const PlatformMouseEvent& mouseEvent,
+                                         const WebMouseEvent& mouseEvent,
                                          LocalDOMWindow* view) {
   AtomicString pointerEventName;
   if (mouseEventName == EventTypeNames::mousemove)
@@ -2137,22 +2137,22 @@
   pointerEventInit.setPointerType("mouse");
   pointerEventInit.setIsPrimary(true);
   pointerEventInit.setButtons(
-      MouseEvent::platformModifiersToButtons(mouseEvent.getModifiers()));
+      MouseEvent::platformModifiersToButtons(mouseEvent.modifiers()));
 
   pointerEventInit.setBubbles(true);
   pointerEventInit.setCancelable(true);
   pointerEventInit.setComposed(true);
   pointerEventInit.setDetail(0);
 
-  pointerEventInit.setScreenX(mouseEvent.globalPosition().x());
-  pointerEventInit.setScreenY(mouseEvent.globalPosition().y());
+  pointerEventInit.setScreenX(mouseEvent.globalX);
+  pointerEventInit.setScreenY(mouseEvent.globalY);
 
   IntPoint locationInFrameZoomed;
   if (view && view->frame() && view->frame()->view()) {
     LocalFrame* frame = view->frame();
     FrameView* frameView = frame->view();
-    IntPoint locationInContents =
-        frameView->rootFrameToContents(mouseEvent.position());
+    IntPoint locationInContents = frameView->rootFrameToContents(
+        flooredIntPoint(mouseEvent.positionInRootFrame()));
     locationInFrameZoomed = frameView->contentsToFrame(locationInContents);
     float scaleFactor = 1 / frame->pageZoomFactor();
     locationInFrameZoomed.scale(scaleFactor, scaleFactor);
@@ -2164,28 +2164,30 @@
 
   if (pointerEventName == EventTypeNames::pointerdown ||
       pointerEventName == EventTypeNames::pointerup) {
-    pointerEventInit.setButton(
-        static_cast<int>(mouseEvent.pointerProperties().button));
+    pointerEventInit.setButton(static_cast<int>(mouseEvent.button));
   } else {
     pointerEventInit.setButton(
         static_cast<int>(WebPointerProperties::Button::NoButton));
   }
 
-  UIEventWithKeyState::setFromPlatformModifiers(pointerEventInit,
-                                                mouseEvent.getModifiers());
+  UIEventWithKeyState::setFromWebInputEventModifiers(
+      pointerEventInit,
+      static_cast<WebInputEvent::Modifiers>(mouseEvent.modifiers()));
   pointerEventInit.setView(view);
 
   dispatchEvent(PointerEvent::create(pointerEventName, pointerEventInit));
 }
 
-void Node::dispatchMouseEvent(const PlatformMouseEvent& nativeEvent,
+void Node::dispatchMouseEvent(const WebMouseEvent& nativeEvent,
                               const AtomicString& mouseEventType,
                               int detail,
+                              const String& canvasRegionId,
                               Node* relatedTarget) {
   createAndDispatchPointerEvent(mouseEventType, nativeEvent,
                                 document().domWindow());
   dispatchEvent(MouseEvent::create(mouseEventType, document().domWindow(),
-                                   nativeEvent, detail, relatedTarget));
+                                   nativeEvent, detail, canvasRegionId,
+                                   relatedTarget));
 }
 
 void Node::dispatchSimulatedClick(Event* underlyingEvent,
diff --git a/third_party/WebKit/Source/core/dom/Node.h b/third_party/WebKit/Source/core/dom/Node.h
index c02e8527..48f16d9 100644
--- a/third_party/WebKit/Source/core/dom/Node.h
+++ b/third_party/WebKit/Source/core/dom/Node.h
@@ -60,7 +60,6 @@
 class NodeList;
 class NodeListsNodeData;
 class NodeRareData;
-class PlatformMouseEvent;
 class QualifiedName;
 class RegisteredEventListener;
 class LayoutBox;
@@ -74,6 +73,7 @@
 using StaticNodeList = StaticNodeTypeList<Node>;
 class StyleChangeReasonForTracing;
 class Text;
+class WebMouseEvent;
 
 const int nodeStyleChangeShift = 18;
 const int nodeCustomElementShift = 20;
@@ -717,9 +717,10 @@
   DispatchEventResult dispatchDOMActivateEvent(int detail,
                                                Event& underlyingEvent);
 
-  void dispatchMouseEvent(const PlatformMouseEvent&,
+  void dispatchMouseEvent(const WebMouseEvent&,
                           const AtomicString& eventType,
                           int clickCount = 0,
+                          const String& canvasNodeId = String(),
                           Node* relatedTarget = nullptr);
 
   void dispatchSimulatedClick(
@@ -842,10 +843,10 @@
   void clearFlag(NodeFlags mask) { m_nodeFlags &= ~mask; }
 
   // TODO(mustaq): This is a hack to fix sites with flash objects. We should
-  // instead route all PlatformMouseEvents through EventHandler. See
+  // instead route all WebMouseEvents through EventHandler. See
   // crbug.com/665924.
   void createAndDispatchPointerEvent(const AtomicString& mouseEventName,
-                                     const PlatformMouseEvent&,
+                                     const WebMouseEvent&,
                                      LocalDOMWindow* view);
 
  protected:
diff --git a/third_party/WebKit/Source/core/editing/PositionIterator.cpp b/third_party/WebKit/Source/core/editing/PositionIterator.cpp
index c483c24..21cdcc6d3 100644
--- a/third_party/WebKit/Source/core/editing/PositionIterator.cpp
+++ b/third_party/WebKit/Source/core/editing/PositionIterator.cpp
@@ -44,11 +44,11 @@
     // Each m_offsetsInAnchorNode[offset] should be an index of node in
     // parent, but delay to calculate the index until it is needed for
     // performance.
-    m_offsetsInAnchorNode.append(kInvalidOffset);
+    m_offsetsInAnchorNode.push_back(kInvalidOffset);
     ++m_depthToAnchorNode;
   }
   if (m_nodeAfterPositionInAnchor)
-    m_offsetsInAnchorNode.append(offsetInAnchor);
+    m_offsetsInAnchorNode.push_back(offsetInAnchor);
 }
 template <typename Strategy>
 PositionIteratorAlgorithm<Strategy>::PositionIteratorAlgorithm(
@@ -152,7 +152,7 @@
     // Increment depth intializing with 0.
     ++m_depthToAnchorNode;
     if (m_depthToAnchorNode == m_offsetsInAnchorNode.size())
-      m_offsetsInAnchorNode.append(0);
+      m_offsetsInAnchorNode.push_back(0);
     else
       m_offsetsInAnchorNode[m_depthToAnchorNode] = 0;
     return;
@@ -233,7 +233,7 @@
       // Increment depth intializing with last offset.
       ++m_depthToAnchorNode;
       if (m_depthToAnchorNode >= m_offsetsInAnchorNode.size())
-        m_offsetsInAnchorNode.append(m_offsetInAnchor);
+        m_offsetsInAnchorNode.push_back(m_offsetInAnchor);
       else
         m_offsetsInAnchorNode[m_depthToAnchorNode] = m_offsetInAnchor;
       return;
@@ -268,7 +268,7 @@
     // Decrement depth initializing with -1 because
     // |m_nodeAfterPositionInAnchor| is null so still unneeded.
     if (m_depthToAnchorNode >= m_offsetsInAnchorNode.size())
-      m_offsetsInAnchorNode.append(kInvalidOffset);
+      m_offsetsInAnchorNode.push_back(kInvalidOffset);
     else
       m_offsetsInAnchorNode[m_depthToAnchorNode] = kInvalidOffset;
     ++m_depthToAnchorNode;
diff --git a/third_party/WebKit/Source/core/editing/SelectionController.cpp b/third_party/WebKit/Source/core/editing/SelectionController.cpp
index 390e6def..b798e64 100644
--- a/third_party/WebKit/Source/core/editing/SelectionController.cpp
+++ b/third_party/WebKit/Source/core/editing/SelectionController.cpp
@@ -180,8 +180,8 @@
   // Don't restart the selection when the mouse is pressed on an
   // existing selection so we can allow for text dragging.
   if (FrameView* view = m_frame->view()) {
-    const LayoutPoint vPoint =
-        view->rootFrameToContents(event.event().position());
+    const LayoutPoint vPoint = view->rootFrameToContents(
+        flooredIntPoint(event.event().positionInRootFrame()));
     if (!extendSelection && this->selection().contains(vPoint)) {
       m_mouseDownWasSingleClickInSelection = true;
       if (!event.event().fromTouch())
@@ -245,8 +245,8 @@
                                    .selectAllChildren(*innerNode)
                                    .build())
             .isCaret();
-    const bool notLeftClick = event.event().pointerProperties().button !=
-                              WebPointerProperties::Button::Left;
+    const bool notLeftClick =
+        event.event().button != WebPointerProperties::Button::Left;
     if (!isTextBoxEmpty || notLeftClick)
       isHandleVisible = event.event().fromTouch();
   }
@@ -538,7 +538,7 @@
     return;
 
   AppendTrailingWhitespace appendTrailingWhitespace =
-      (result.event().clickCount() == 2 &&
+      (result.event().clickCount == 2 &&
        m_frame->editor().isSelectTrailingWhitespaceEnabled())
           ? AppendTrailingWhitespace::ShouldAppend
           : AppendTrailingWhitespace::DontAppend;
@@ -558,7 +558,7 @@
 
   selectClosestMisspellingFromHitTestResult(
       result.hitTestResult(),
-      (result.event().clickCount() == 2 &&
+      (result.event().clickCount == 2 &&
        m_frame->editor().isSelectTrailingWhitespaceEnabled())
           ? AppendTrailingWhitespace::ShouldAppend
           : AppendTrailingWhitespace::DontAppend);
@@ -733,8 +733,7 @@
   if (!m_mouseDownAllowsMultiClick)
     return handleMousePressEventSingleClick(event);
 
-  if (event.event().pointerProperties().button !=
-      WebPointerProperties::Button::Left)
+  if (event.event().button != WebPointerProperties::Button::Left)
     return false;
 
   if (selection().isRange()) {
@@ -763,8 +762,7 @@
   if (!m_mouseDownAllowsMultiClick)
     return handleMousePressEventSingleClick(event);
 
-  if (event.event().pointerProperties().button !=
-      WebPointerProperties::Button::Left)
+  if (event.event().button != WebPointerProperties::Button::Left)
     return false;
 
   Node* innerNode = event.innerNode();
@@ -865,9 +863,9 @@
   // editing, place the caret.
   if (m_mouseDownWasSingleClickInSelection &&
       m_selectionState != SelectionState::ExtendedSelection &&
-      dragStartPos == event.event().position() && selection().isRange() &&
-      event.event().pointerProperties().button !=
-          WebPointerProperties::Button::Right) {
+      dragStartPos == flooredIntPoint(event.event().positionInRootFrame()) &&
+      selection().isRange() &&
+      event.event().button != WebPointerProperties::Button::Right) {
     // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
     // needs to be audited.  See http://crbug.com/590369 for more details.
     m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets();
@@ -893,8 +891,7 @@
 
   selection().selectFrameElementInParentIfFullySelected();
 
-  if (event.event().pointerProperties().button ==
-          WebPointerProperties::Button::Middle &&
+  if (event.event().button == WebPointerProperties::Button::Middle &&
       !event.isOverLink()) {
     // Ignore handled, since we want to paste to where the caret was placed
     // anyway.
@@ -905,7 +902,7 @@
 }
 
 bool SelectionController::handlePasteGlobalSelection(
-    const PlatformMouseEvent& mouseEvent) {
+    const WebMouseEvent& mouseEvent) {
   // If the event was a middle click, attempt to copy global selection in after
   // the newly set caret position.
   //
@@ -922,7 +919,7 @@
   // down then the text is pasted just before the onclick handler runs and
   // clears the text box. So it's important this happens after the event
   // handlers have been fired.
-  if (mouseEvent.type() != PlatformEvent::MouseReleased)
+  if (mouseEvent.type() != WebInputEvent::MouseUp)
     return false;
 
   if (!m_frame->page())
@@ -1022,7 +1019,8 @@
   // greyed out even though we're clicking on the selection.  This looks
   // really strange (having the whole frame be greyed out), so we deselect the
   // selection.
-  IntPoint p = m_frame->view()->rootFrameToContents(mev.event().position());
+  IntPoint p = m_frame->view()->rootFrameToContents(
+      flooredIntPoint(mev.event().positionInRootFrame()));
   if (!selection().contains(p))
     return;
 
@@ -1071,13 +1069,16 @@
 }
 
 bool isLinkSelection(const MouseEventWithHitTestResults& event) {
-  return event.event().altKey() && event.isOverLink();
+  return (event.event().modifiers() & WebInputEvent::Modifiers::AltKey) != 0 &&
+         event.isOverLink();
 }
 
 bool isExtendingSelection(const MouseEventWithHitTestResults& event) {
   bool isMouseDownOnLinkOrImage =
       event.isOverLink() || event.hitTestResult().image();
-  return event.event().shiftKey() && !isMouseDownOnLinkOrImage;
+  return (event.event().modifiers() & WebInputEvent::Modifiers::ShiftKey) !=
+             0 &&
+         !isMouseDownOnLinkOrImage;
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/SelectionController.h b/third_party/WebKit/Source/core/editing/SelectionController.h
index 8d847cc..69abbddc 100644
--- a/third_party/WebKit/Source/core/editing/SelectionController.h
+++ b/third_party/WebKit/Source/core/editing/SelectionController.h
@@ -62,7 +62,7 @@
                                const IntPoint&);
   bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&,
                                const LayoutPoint&);
-  bool handlePasteGlobalSelection(const PlatformMouseEvent&);
+  bool handlePasteGlobalSelection(const WebMouseEvent&);
   bool handleGestureLongPress(const WebGestureEvent&, const HitTestResult&);
   void handleGestureTwoFingerTap(const GestureEventWithHitTestResults&);
   void handleGestureLongTap(const GestureEventWithHitTestResults&);
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp
index f20a8ad..5fca9b6 100644
--- a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp
+++ b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp
@@ -634,7 +634,7 @@
     m_sortedTextBoxes.clear();
     for (InlineTextBox* textBox = layoutObject->firstTextBox(); textBox;
          textBox = textBox->nextTextBox()) {
-      m_sortedTextBoxes.append(textBox);
+      m_sortedTextBoxes.push_back(textBox);
     }
     std::sort(m_sortedTextBoxes.begin(), m_sortedTextBoxes.end(),
               InlineTextBox::compareByStart);
diff --git a/third_party/WebKit/Source/core/events/DragEvent.cpp b/third_party/WebKit/Source/core/events/DragEvent.cpp
index 61e44d4..9512e6cd 100644
--- a/third_party/WebKit/Source/core/events/DragEvent.cpp
+++ b/third_party/WebKit/Source/core/events/DragEvent.cpp
@@ -10,25 +10,24 @@
 
 namespace blink {
 
-DragEvent* DragEvent::create(
-    const AtomicString& type,
-    bool canBubble,
-    bool cancelable,
-    AbstractView* view,
-    int detail,
-    int screenX,
-    int screenY,
-    int windowX,
-    int windowY,
-    int movementX,
-    int movementY,
-    PlatformEvent::Modifiers modifiers,
-    short button,
-    unsigned short buttons,
-    EventTarget* relatedTarget,
-    TimeTicks platformTimeStamp,
-    DataTransfer* dataTransfer,
-    PlatformMouseEvent::SyntheticEventType syntheticEventType) {
+DragEvent* DragEvent::create(const AtomicString& type,
+                             bool canBubble,
+                             bool cancelable,
+                             AbstractView* view,
+                             int detail,
+                             int screenX,
+                             int screenY,
+                             int windowX,
+                             int windowY,
+                             int movementX,
+                             int movementY,
+                             PlatformEvent::Modifiers modifiers,
+                             short button,
+                             unsigned short buttons,
+                             EventTarget* relatedTarget,
+                             TimeTicks platformTimeStamp,
+                             DataTransfer* dataTransfer,
+                             SyntheticEventType syntheticEventType) {
   return new DragEvent(type, canBubble, cancelable, view, detail, screenX,
                        screenY, windowX, windowY, movementX, movementY,
                        modifiers, button, buttons, relatedTarget,
@@ -57,7 +56,7 @@
                      EventTarget* relatedTarget,
                      TimeTicks platformTimeStamp,
                      DataTransfer* dataTransfer,
-                     PlatformMouseEvent::SyntheticEventType syntheticEventType)
+                     SyntheticEventType syntheticEventType)
     : MouseEvent(
           eventType,
           canBubble,
@@ -78,8 +77,7 @@
           syntheticEventType,
           // TODO(zino): Should support canvas hit region because the drag event
           // is a kind of mouse event. Please see http://crbug.com/594073
-          String(),
-          nullptr),
+          String()),
       m_dataTransfer(dataTransfer)
 
 {}
diff --git a/third_party/WebKit/Source/core/events/DragEvent.h b/third_party/WebKit/Source/core/events/DragEvent.h
index e1d6fcb..2bdef6e 100644
--- a/third_party/WebKit/Source/core/events/DragEvent.h
+++ b/third_party/WebKit/Source/core/events/DragEvent.h
@@ -40,8 +40,7 @@
                            EventTarget* relatedTarget,
                            TimeTicks platformTimeStamp,
                            DataTransfer*,
-                           PlatformMouseEvent::SyntheticEventType =
-                               PlatformMouseEvent::RealOrIndistinguishable);
+                           SyntheticEventType = RealOrIndistinguishable);
 
   static DragEvent* create(const AtomicString& type,
                            const DragEventInit& initializer) {
@@ -79,7 +78,7 @@
             EventTarget* relatedTarget,
             TimeTicks platformTimeStamp,
             DataTransfer*,
-            PlatformMouseEvent::SyntheticEventType);
+            SyntheticEventType);
 
   DragEvent(const AtomicString& type, const DragEventInit&);
 
diff --git a/third_party/WebKit/Source/core/events/MouseEvent.cpp b/third_party/WebKit/Source/core/events/MouseEvent.cpp
index da7a869..5e68f976 100644
--- a/third_party/WebKit/Source/core/events/MouseEvent.cpp
+++ b/third_party/WebKit/Source/core/events/MouseEvent.cpp
@@ -32,7 +32,6 @@
 #include "core/layout/LayoutObject.h"
 #include "core/paint/PaintLayer.h"
 #include "core/svg/SVGElement.h"
-#include "platform/PlatformMouseEvent.h"
 #include "public/platform/WebPointerProperties.h"
 
 namespace blink {
@@ -91,48 +90,16 @@
 
 MouseEvent* MouseEvent::create(const AtomicString& eventType,
                                AbstractView* view,
-                               const PlatformMouseEvent& event,
+                               const WebMouseEvent& event,
                                int detail,
+                               const String& canvasRegionId,
                                Node* relatedTarget) {
   bool isMouseEnterOrLeave = eventType == EventTypeNames::mouseenter ||
                              eventType == EventTypeNames::mouseleave;
   bool isCancelable = !isMouseEnterOrLeave;
   bool isBubbling = !isMouseEnterOrLeave;
-
-  return MouseEvent::create(
-      eventType, isBubbling, isCancelable, view, detail,
-      event.globalPosition().x(), event.globalPosition().y(),
-      event.position().x(), event.position().y(), event.movementDelta().x(),
-      event.movementDelta().y(), event.getModifiers(),
-      static_cast<short>(event.pointerProperties().button),
-      platformModifiersToButtons(event.getModifiers()), relatedTarget,
-      event.timestamp(), event.getSyntheticEventType(), event.region(), &event);
-}
-
-MouseEvent* MouseEvent::create(
-    const AtomicString& type,
-    bool canBubble,
-    bool cancelable,
-    AbstractView* view,
-    int detail,
-    int screenX,
-    int screenY,
-    int windowX,
-    int windowY,
-    int movementX,
-    int movementY,
-    PlatformEvent::Modifiers modifiers,
-    short button,
-    unsigned short buttons,
-    EventTarget* relatedTarget,
-    TimeTicks platformTimeStamp,
-    PlatformMouseEvent::SyntheticEventType syntheticEventType,
-    const String& region,
-    const PlatformMouseEvent* mouseEvent) {
-  return new MouseEvent(
-      type, canBubble, cancelable, view, detail, screenX, screenY, windowX,
-      windowY, movementX, movementY, modifiers, button, buttons, relatedTarget,
-      platformTimeStamp, syntheticEventType, region, mouseEvent);
+  return new MouseEvent(eventType, isBubbling, isCancelable, view, event,
+                        detail, canvasRegionId, relatedTarget);
 }
 
 MouseEvent* MouseEvent::create(const AtomicString& eventType,
@@ -145,12 +112,11 @@
     modifiers = keyStateEvent->modifiers();
   }
 
-  PlatformMouseEvent::SyntheticEventType syntheticType =
-      PlatformMouseEvent::Positionless;
+  SyntheticEventType syntheticType = Positionless;
   int screenX = 0;
   int screenY = 0;
   if (underlyingEvent && underlyingEvent->isMouseEvent()) {
-    syntheticType = PlatformMouseEvent::RealOrIndistinguishable;
+    syntheticType = RealOrIndistinguishable;
     MouseEvent* mouseEvent = toMouseEvent(underlyingEvent);
     screenX = mouseEvent->screenX();
     screenY = mouseEvent->screenY();
@@ -158,14 +124,14 @@
 
   TimeTicks timestamp =
       underlyingEvent ? underlyingEvent->platformTimeStamp() : TimeTicks::Now();
-  MouseEvent* createdEvent = MouseEvent::create(
+  MouseEvent* createdEvent = new MouseEvent(
       eventType, true, true, view, 0, screenX, screenY, 0, 0, 0, 0, modifiers,
-      0, 0, nullptr, timestamp, syntheticType, String(), nullptr);
+      0, 0, nullptr, timestamp, syntheticType, String());
 
   createdEvent->setTrusted(creationScope ==
                            SimulatedClickCreationScope::FromUserAgent);
   createdEvent->setUnderlyingEvent(underlyingEvent);
-  if (syntheticType == PlatformMouseEvent::RealOrIndistinguishable) {
+  if (syntheticType == RealOrIndistinguishable) {
     MouseEvent* mouseEvent = toMouseEvent(createdEvent->underlyingEvent());
     createdEvent->initCoordinates(mouseEvent->clientX(), mouseEvent->clientY());
   }
@@ -179,62 +145,60 @@
       m_button(0),
       m_buttons(0),
       m_relatedTarget(nullptr),
-      m_syntheticEventType(PlatformMouseEvent::RealOrIndistinguishable) {}
+      m_syntheticEventType(RealOrIndistinguishable) {}
 
-MouseEvent::MouseEvent(
-    const AtomicString& eventType,
-    bool canBubble,
-    bool cancelable,
-    AbstractView* abstractView,
-    PlatformMouseEvent::SyntheticEventType syntheticEventType,
-    const String& region,
-    const WebMouseEvent& event)
+MouseEvent::MouseEvent(const AtomicString& eventType,
+                       bool canBubble,
+                       bool cancelable,
+                       AbstractView* abstractView,
+                       const WebMouseEvent& event,
+                       int detail,
+                       const String& region,
+                       EventTarget* relatedTarget)
     : UIEventWithKeyState(
           eventType,
           canBubble,
           cancelable,
           abstractView,
-          0,
+          detail,
           static_cast<PlatformEvent::Modifiers>(event.modifiers()),
           TimeTicks::FromSeconds(event.timeStampSeconds()),
-          syntheticEventType == PlatformMouseEvent::FromTouch
+          event.fromTouch()
               ? InputDeviceCapabilities::firesTouchEventsSourceCapabilities()
               : InputDeviceCapabilities::
                     doesntFireTouchEventsSourceCapabilities()),
       m_screenLocation(event.globalX, event.globalY),
       m_movementDelta(flooredIntPoint(event.movementInRootFrame())),
-      m_positionType(syntheticEventType == PlatformMouseEvent::Positionless
-                         ? PositionType::Positionless
-                         : PositionType::Position),
-      m_button(0),
+      m_positionType(PositionType::Position),
+      m_button(static_cast<short>(event.button)),
       m_buttons(platformModifiersToButtons(event.modifiers())),
-      m_syntheticEventType(syntheticEventType),
+      m_relatedTarget(relatedTarget),
+      m_syntheticEventType(event.fromTouch() ? FromTouch
+                                             : RealOrIndistinguishable),
       m_region(region) {
   IntPoint rootFrameCoordinates = flooredIntPoint(event.positionInRootFrame());
   initCoordinatesFromRootFrame(rootFrameCoordinates.x(),
                                rootFrameCoordinates.y());
 }
 
-MouseEvent::MouseEvent(
-    const AtomicString& eventType,
-    bool canBubble,
-    bool cancelable,
-    AbstractView* abstractView,
-    int detail,
-    int screenX,
-    int screenY,
-    int windowX,
-    int windowY,
-    int movementX,
-    int movementY,
-    PlatformEvent::Modifiers modifiers,
-    short button,
-    unsigned short buttons,
-    EventTarget* relatedTarget,
-    TimeTicks platformTimeStamp,
-    PlatformMouseEvent::SyntheticEventType syntheticEventType,
-    const String& region,
-    const PlatformMouseEvent* mouseEvent)
+MouseEvent::MouseEvent(const AtomicString& eventType,
+                       bool canBubble,
+                       bool cancelable,
+                       AbstractView* abstractView,
+                       int detail,
+                       int screenX,
+                       int screenY,
+                       int windowX,
+                       int windowY,
+                       int movementX,
+                       int movementY,
+                       PlatformEvent::Modifiers modifiers,
+                       short button,
+                       unsigned short buttons,
+                       EventTarget* relatedTarget,
+                       TimeTicks platformTimeStamp,
+                       SyntheticEventType syntheticEventType,
+                       const String& region)
     : UIEventWithKeyState(
           eventType,
           canBubble,
@@ -243,13 +207,13 @@
           detail,
           modifiers,
           platformTimeStamp,
-          syntheticEventType == PlatformMouseEvent::FromTouch
+          syntheticEventType == FromTouch
               ? InputDeviceCapabilities::firesTouchEventsSourceCapabilities()
               : InputDeviceCapabilities::
                     doesntFireTouchEventsSourceCapabilities()),
       m_screenLocation(screenX, screenY),
       m_movementDelta(movementX, movementY),
-      m_positionType(syntheticEventType == PlatformMouseEvent::Positionless
+      m_positionType(syntheticEventType == Positionless
                          ? PositionType::Positionless
                          : PositionType::Position),
       m_button(button),
@@ -257,8 +221,6 @@
       m_relatedTarget(relatedTarget),
       m_syntheticEventType(syntheticEventType),
       m_region(region) {
-  if (mouseEvent)
-    m_mouseEvent.reset(new PlatformMouseEvent(*mouseEvent));
   initCoordinatesFromRootFrame(windowX, windowY);
 }
 
@@ -273,7 +235,7 @@
       m_button(initializer.button()),
       m_buttons(initializer.buttons()),
       m_relatedTarget(initializer.relatedTarget()),
-      m_syntheticEventType(PlatformMouseEvent::RealOrIndistinguishable),
+      m_syntheticEventType(RealOrIndistinguishable),
       m_region(initializer.region()) {
   initCoordinates(initializer.clientX(), initializer.clientY());
 }
diff --git a/third_party/WebKit/Source/core/events/MouseEvent.h b/third_party/WebKit/Source/core/events/MouseEvent.h
index 767a340..831be6c 100644
--- a/third_party/WebKit/Source/core/events/MouseEvent.h
+++ b/third_party/WebKit/Source/core/events/MouseEvent.h
@@ -28,7 +28,6 @@
 #include "core/events/EventDispatchMediator.h"
 #include "core/events/MouseEventInit.h"
 #include "core/events/UIEventWithKeyState.h"
-#include "platform/PlatformMouseEvent.h"
 #include "public/platform/WebMouseEvent.h"
 
 namespace blink {
@@ -39,34 +38,24 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static MouseEvent* create() { return new MouseEvent; }
+  enum SyntheticEventType {
+    // Real mouse input events or synthetic events that behave just like real
+    // events
+    RealOrIndistinguishable,
+    // Synthetic mouse events derived from touch input
+    FromTouch,
+    // Synthetic mouse events generated without a position, for example those
+    // generated from keyboard input.
+    Positionless,
+  };
 
-  // TODO(mustaq): Should replace most/all of these params with a
-  // MouseEventInit.
-  static MouseEvent* create(const AtomicString& type,
-                            bool canBubble,
-                            bool cancelable,
-                            AbstractView*,
-                            int detail,
-                            int screenX,
-                            int screenY,
-                            int windowX,
-                            int windowY,
-                            int movementX,
-                            int movementY,
-                            PlatformEvent::Modifiers,
-                            short button,
-                            unsigned short buttons,
-                            EventTarget* relatedTarget,
-                            TimeTicks platformTimeStamp,
-                            PlatformMouseEvent::SyntheticEventType,
-                            const String& region,
-                            const PlatformMouseEvent*);
+  static MouseEvent* create() { return new MouseEvent; }
 
   static MouseEvent* create(const AtomicString& eventType,
                             AbstractView*,
-                            const PlatformMouseEvent&,
+                            const WebMouseEvent&,
                             int detail,
+                            const String& canvasRegionId,
                             Node* relatedTarget);
 
   static MouseEvent* create(ScriptState*,
@@ -109,20 +98,17 @@
   void setRelatedTarget(EventTarget* relatedTarget) {
     m_relatedTarget = relatedTarget;
   }
-  PlatformMouseEvent::SyntheticEventType getSyntheticEventType() const {
+  SyntheticEventType getSyntheticEventType() const {
     return m_syntheticEventType;
   }
   const String& region() const { return m_region; }
-  void setRegion(const String& region) { m_region = region; }
 
   Node* toElement() const;
   Node* fromElement() const;
 
   virtual DataTransfer* getDataTransfer() const { return nullptr; }
 
-  bool fromTouch() const {
-    return m_syntheticEventType == PlatformMouseEvent::FromTouch;
-  }
+  bool fromTouch() const { return m_syntheticEventType == FromTouch; }
 
   const AtomicString& interfaceName() const override;
 
@@ -133,7 +119,7 @@
 
   int clickCount() { return detail(); }
 
-  const PlatformMouseEvent* mouseEvent() const { return m_mouseEvent.get(); }
+  const WebMouseEvent* nativeEvent() const { return m_nativeEvent.get(); }
 
   enum class PositionType {
     Position,
@@ -200,9 +186,10 @@
              bool canBubble,
              bool cancelable,
              AbstractView*,
-             PlatformMouseEvent::SyntheticEventType,
+             const WebMouseEvent&,
+             int detail,
              const String& region,
-             const WebMouseEvent&);
+             EventTarget* relatedTarget);
 
   MouseEvent(const AtomicString& type,
              bool canBubble,
@@ -220,9 +207,8 @@
              unsigned short buttons,
              EventTarget* relatedTarget,
              TimeTicks platformTimeStamp,
-             PlatformMouseEvent::SyntheticEventType,
-             const String& region,
-             const PlatformMouseEvent*);
+             SyntheticEventType,
+             const String& region);
 
   MouseEvent(const AtomicString& type, const MouseEventInit&);
 
@@ -267,9 +253,9 @@
   short m_button;
   unsigned short m_buttons;
   Member<EventTarget> m_relatedTarget;
-  PlatformMouseEvent::SyntheticEventType m_syntheticEventType;
+  SyntheticEventType m_syntheticEventType;
   String m_region;
-  std::unique_ptr<PlatformMouseEvent> m_mouseEvent;
+  std::unique_ptr<WebMouseEvent> m_nativeEvent;
 };
 
 class MouseEventDispatchMediator final : public EventDispatchMediator {
diff --git a/third_party/WebKit/Source/core/events/PointerEventFactory.cpp b/third_party/WebKit/Source/core/events/PointerEventFactory.cpp
index 13eed8b..75586e7 100644
--- a/third_party/WebKit/Source/core/events/PointerEventFactory.cpp
+++ b/third_party/WebKit/Source/core/events/PointerEventFactory.cpp
@@ -134,22 +134,22 @@
   pointerEventInit->setTwist(touchPoint.twist);
 }
 
-void updateMousePointerEventInit(const PlatformMouseEvent& mouseEvent,
+void updateMousePointerEventInit(const WebMouseEvent& mouseEvent,
                                  LocalDOMWindow* view,
                                  PointerEventInit* pointerEventInit) {
   // This function should not update attributes like pointerId, isPrimary,
   // and pointerType which is the same among the coalesced events and the
   // dispatched event.
 
-  pointerEventInit->setScreenX(mouseEvent.globalPosition().x());
-  pointerEventInit->setScreenY(mouseEvent.globalPosition().y());
+  pointerEventInit->setScreenX(mouseEvent.globalX);
+  pointerEventInit->setScreenY(mouseEvent.globalY);
 
   IntPoint locationInFrameZoomed;
   if (view && view->frame() && view->frame()->view()) {
     LocalFrame* frame = view->frame();
     FrameView* frameView = frame->view();
-    IntPoint locationInContents =
-        frameView->rootFrameToContents(mouseEvent.position());
+    IntPoint locationInContents = frameView->rootFrameToContents(
+        flooredIntPoint(mouseEvent.positionInRootFrame()));
     locationInFrameZoomed = frameView->contentsToFrame(locationInContents);
     float scaleFactor = 1 / frame->pageZoomFactor();
     locationInFrameZoomed.scale(scaleFactor, scaleFactor);
@@ -158,13 +158,12 @@
   pointerEventInit->setClientX(locationInFrameZoomed.x());
   pointerEventInit->setClientY(locationInFrameZoomed.y());
 
-  pointerEventInit->setPressure(getPointerEventPressure(
-      mouseEvent.pointerProperties().force, pointerEventInit->buttons()));
-  pointerEventInit->setTiltX(mouseEvent.pointerProperties().tiltX);
-  pointerEventInit->setTiltY(mouseEvent.pointerProperties().tiltY);
-  pointerEventInit->setTangentialPressure(
-      mouseEvent.pointerProperties().tangentialPressure);
-  pointerEventInit->setTwist(mouseEvent.pointerProperties().twist);
+  pointerEventInit->setPressure(
+      getPointerEventPressure(mouseEvent.force, pointerEventInit->buttons()));
+  pointerEventInit->setTiltX(mouseEvent.tiltX);
+  pointerEventInit->setTiltY(mouseEvent.tiltY);
+  pointerEventInit->setTangentialPressure(mouseEvent.tangentialPressure);
+  pointerEventInit->setTwist(mouseEvent.twist);
 }
 
 }  // namespace
@@ -216,8 +215,8 @@
 
 PointerEvent* PointerEventFactory::create(
     const AtomicString& mouseEventName,
-    const PlatformMouseEvent& mouseEvent,
-    const Vector<PlatformMouseEvent>& coalescedMouseEvents,
+    const WebMouseEvent& mouseEvent,
+    const Vector<WebMouseEvent>& coalescedMouseEvents,
     LocalDOMWindow* view) {
   DCHECK(mouseEventName == EventTypeNames::mousemove ||
          mouseEventName == EventTypeNames::mousedown ||
@@ -226,19 +225,18 @@
   AtomicString pointerEventName =
       pointerEventNameForMouseEventName(mouseEventName);
 
-  unsigned buttons =
-      MouseEvent::platformModifiersToButtons(mouseEvent.getModifiers());
+  unsigned buttons = MouseEvent::platformModifiersToButtons(
+      static_cast<PlatformEvent::Modifiers>(mouseEvent.modifiers()));
   PointerEventInit pointerEventInit;
 
-  setIdTypeButtons(pointerEventInit, mouseEvent.pointerProperties(), buttons);
+  setIdTypeButtons(pointerEventInit, mouseEvent, buttons);
   setEventSpecificFields(pointerEventInit, pointerEventName);
 
   if (pointerEventName == EventTypeNames::pointerdown ||
       pointerEventName == EventTypeNames::pointerup) {
-    WebPointerProperties::Button button = mouseEvent.pointerProperties().button;
+    WebPointerProperties::Button button = mouseEvent.button;
     // TODO(mustaq): Fix when the spec starts supporting hovering erasers.
-    if (mouseEvent.pointerProperties().pointerType ==
-            WebPointerProperties::PointerType::Eraser &&
+    if (mouseEvent.pointerType == WebPointerProperties::PointerType::Eraser &&
         button == WebPointerProperties::Button::Left)
       button = WebPointerProperties::Button::Eraser;
     pointerEventInit.setButton(static_cast<int>(button));
@@ -248,14 +246,13 @@
         static_cast<int>(WebPointerProperties::Button::NoButton));
   }
 
-  UIEventWithKeyState::setFromPlatformModifiers(pointerEventInit,
-                                                mouseEvent.getModifiers());
+  UIEventWithKeyState::setFromWebInputEventModifiers(
+      pointerEventInit,
+      static_cast<WebInputEvent::Modifiers>(mouseEvent.modifiers()));
 
   // Make sure chorded buttons fire pointermove instead of pointerup/down.
   if ((pointerEventName == EventTypeNames::pointerdown &&
-       (buttons &
-        ~buttonToButtonsBitfield(mouseEvent.pointerProperties().button)) !=
-           0) ||
+       (buttons & ~buttonToButtonsBitfield(mouseEvent.button)) != 0) ||
       (pointerEventName == EventTypeNames::pointerup && buttons != 0))
     pointerEventName = EventTypeNames::pointermove;
 
@@ -267,12 +264,10 @@
   if (pointerEventName == EventTypeNames::pointermove) {
     HeapVector<Member<PointerEvent>> coalescedPointerEvents;
     for (const auto& coalescedMouseEvent : coalescedMouseEvents) {
-      DCHECK_EQ(mouseEvent.pointerProperties().id,
-                coalescedMouseEvent.pointerProperties().id);
+      DCHECK_EQ(mouseEvent.id, coalescedMouseEvent.id);
       // TODO(crbug.com/684292): We need further investigation of why the
       // following DCHECK fails.
-      // DCHECK_EQ(mouseEvent.pointerProperties().pointerType,
-      //          coalescedMouseEvent.pointerProperties().pointerType);
+      // DCHECK_EQ(mouseEvent.pointerType, coalescedMouseEvent.pointerType);
       PointerEventInit coalescedEventInit = pointerEventInit;
       updateMousePointerEventInit(coalescedMouseEvent, view,
                                   &coalescedEventInit);
diff --git a/third_party/WebKit/Source/core/events/PointerEventFactory.h b/third_party/WebKit/Source/core/events/PointerEventFactory.h
index 2f1275e..7c9d0d72 100644
--- a/third_party/WebKit/Source/core/events/PointerEventFactory.h
+++ b/third_party/WebKit/Source/core/events/PointerEventFactory.h
@@ -30,8 +30,8 @@
   ~PointerEventFactory();
 
   PointerEvent* create(const AtomicString& mouseEventName,
-                       const PlatformMouseEvent&,
-                       const Vector<PlatformMouseEvent>&,
+                       const WebMouseEvent&,
+                       const Vector<WebMouseEvent>&,
                        LocalDOMWindow*);
 
   PointerEvent* create(const WebTouchPoint&,
diff --git a/third_party/WebKit/Source/core/events/PointerEventFactoryTest.cpp b/third_party/WebKit/Source/core/events/PointerEventFactoryTest.cpp
index 9050098f..9ff8362 100644
--- a/third_party/WebKit/Source/core/events/PointerEventFactoryTest.cpp
+++ b/third_party/WebKit/Source/core/events/PointerEventFactoryTest.cpp
@@ -66,11 +66,11 @@
                          WebTouchPoint::State);
   };
 
-  class PlatformMouseEventBuilder : public PlatformMouseEvent {
+  class WebMouseEventBuilder : public WebMouseEvent {
    public:
-    PlatformMouseEventBuilder(WebPointerProperties::PointerType,
-                              int,
-                              PlatformEvent::Modifiers);
+    WebMouseEventBuilder(WebPointerProperties::PointerType,
+                         int,
+                         PlatformEvent::Modifiers);
   };
 };
 
@@ -89,13 +89,13 @@
   state = stateParam;
 }
 
-PointerEventFactoryTest::PlatformMouseEventBuilder::PlatformMouseEventBuilder(
-    WebPointerProperties::PointerType pointerType,
-    int id,
-    PlatformEvent::Modifiers modifiers) {
-  m_pointerProperties.pointerType = pointerType;
-  m_pointerProperties.id = id;
-  m_modifiers = modifiers;
+PointerEventFactoryTest::WebMouseEventBuilder::WebMouseEventBuilder(
+    WebPointerProperties::PointerType pointerTypeParam,
+    int idParam,
+    PlatformEvent::Modifiers modifiersParam) {
+  pointerType = pointerTypeParam;
+  id = idParam;
+  m_modifiers = modifiersParam;
 }
 
 PointerEvent* PointerEventFactoryTest::createAndCheckTouchCancel(
@@ -160,17 +160,16 @@
     bool isPrimary,
     PlatformEvent::Modifiers modifiers,
     size_t coalescedEventCount) {
-  Vector<PlatformMouseEvent> coalescedEvents;
+  Vector<WebMouseEvent> coalescedEvents;
   for (size_t i = 0; i < coalescedEventCount; i++) {
-    coalescedEvents.push_back(
-        PointerEventFactoryTest::PlatformMouseEventBuilder(pointerType, rawId,
-                                                           modifiers));
+    coalescedEvents.push_back(PointerEventFactoryTest::WebMouseEventBuilder(
+        pointerType, rawId, modifiers));
   }
   PointerEvent* pointerEvent = m_pointerEventFactory.create(
       coalescedEventCount ? EventTypeNames::mousemove
                           : EventTypeNames::mousedown,
-      PointerEventFactoryTest::PlatformMouseEventBuilder(pointerType, rawId,
-                                                         modifiers),
+      PointerEventFactoryTest::WebMouseEventBuilder(pointerType, rawId,
+                                                    modifiers),
       coalescedEvents, nullptr);
   EXPECT_EQ(uniqueId, pointerEvent->pointerId());
   EXPECT_EQ(isPrimary, pointerEvent->isPrimary());
diff --git a/third_party/WebKit/Source/core/events/WheelEvent.cpp b/third_party/WebKit/Source/core/events/WheelEvent.cpp
index 5f39f8b..3597836 100644
--- a/third_party/WebKit/Source/core/events/WheelEvent.cpp
+++ b/third_party/WebKit/Source/core/events/WheelEvent.cpp
@@ -24,7 +24,6 @@
 #include "core/events/WheelEvent.h"
 
 #include "core/clipboard/DataTransfer.h"
-#include "platform/PlatformMouseEvent.h"
 
 namespace blink {
 
@@ -73,12 +72,13 @@
                  true,
                  event.isCancelable(),
                  view,
-                 PlatformMouseEvent::RealOrIndistinguishable,
+                 event,
+                 event.clickCount,
                  // TODO(zino): Should support canvas hit region because the
                  // wheel event is a kind of mouse event. Please see
                  // http://crbug.com/594075
                  String(),
-                 event),
+                 nullptr),
       m_wheelDelta(event.wheelTicksX * TickMultiplier,
                    event.wheelTicksY * TickMultiplier),
       m_deltaX(-event.deltaXInRootFrame()),
diff --git a/third_party/WebKit/Source/core/html/HTMLInputElement.cpp b/third_party/WebKit/Source/core/html/HTMLInputElement.cpp
index 07ee1a29..af78e1d 100644
--- a/third_party/WebKit/Source/core/html/HTMLInputElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLInputElement.cpp
@@ -72,7 +72,6 @@
 #include "core/layout/LayoutTheme.h"
 #include "core/page/ChromeClient.h"
 #include "platform/Language.h"
-#include "platform/PlatformMouseEvent.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/text/PlatformLocale.h"
 #include "wtf/MathExtras.h"
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
index db8af67..64894942 100644
--- a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
@@ -70,7 +70,6 @@
 #include "core/page/ChromeClient.h"
 #include "core/page/Page.h"
 #include "core/page/SpatialNavigation.h"
-#include "platform/PlatformMouseEvent.h"
 #include "platform/PopupMenu.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "platform/text/PlatformLocale.h"
@@ -1288,7 +1287,7 @@
       return;
 
     int ignoreModifiers = PlatformEvent::ShiftKey | PlatformEvent::CtrlKey |
-                          PlatformEvent::AltKey | PlatformMouseEvent::MetaKey;
+                          PlatformEvent::AltKey | PlatformEvent::MetaKey;
     if (keyEvent->modifiers() & ignoreModifiers)
       return;
 
diff --git a/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp b/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp
index 0ca1bd5..e2a50b29 100644
--- a/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp
+++ b/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp
@@ -50,7 +50,6 @@
 #include "core/html/shadow/ShadowElementNames.h"
 #include "core/html/shadow/SliderThumbElement.h"
 #include "core/layout/LayoutSlider.h"
-#include "platform/PlatformMouseEvent.h"
 #include "wtf/MathExtras.h"
 #include "wtf/NonCopyingSort.h"
 #include <limits>
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index 35cea31..1d31008 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -568,14 +568,13 @@
 }
 
 WebInputEventResult EventHandler::handleMousePressEvent(
-    const PlatformMouseEvent& mouseEvent) {
+    const WebMouseEvent& mouseEvent) {
   TRACE_EVENT0("blink", "EventHandler::handleMousePressEvent");
 
   // For 4th/5th button in the mouse since Chrome does not yet send
   // button value to Blink but in some cases it does send the event.
   // This check is needed to suppress such an event (crbug.com/574959)
-  if (mouseEvent.pointerProperties().button ==
-      WebPointerProperties::Button::NoButton)
+  if (mouseEvent.button == WebPointerProperties::Button::NoButton)
     return WebInputEventResult::HandledSuppressed;
 
   if (m_eventHandlerWillResetCapturingMouseEventsNode)
@@ -588,8 +587,8 @@
   HitTestRequest request(HitTestRequest::Active);
   // Save the document point we generate in case the window coordinate is
   // invalidated by what happens when we dispatch the event.
-  LayoutPoint documentPoint =
-      m_frame->view()->rootFrameToContents(mouseEvent.position());
+  LayoutPoint documentPoint = m_frame->view()->rootFrameToContents(
+      flooredIntPoint(mouseEvent.positionInRootFrame()));
   MouseEventWithHitTestResults mev =
       m_frame->document()->performMouseEventHitTest(request, documentPoint,
                                                     mouseEvent);
@@ -642,7 +641,7 @@
     }
   }
 
-  m_mouseEventManager->setClickCount(mouseEvent.clickCount());
+  m_mouseEventManager->setClickCount(mouseEvent.clickCount);
   m_mouseEventManager->setClickNode(
       mev.innerNode()->isTextNode()
           ? FlatTreeTraversal::parent(*mev.innerNode())
@@ -652,15 +651,16 @@
     m_frame->selection().setCaretBlinkingSuspended(true);
 
   WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents(
-      EventTypeNames::mousedown, mev.innerNode(), mev.event(),
-      Vector<PlatformMouseEvent>());
+      EventTypeNames::mousedown, mev.innerNode(), mev.canvasRegionId(),
+      mev.event(), Vector<WebMouseEvent>());
 
   if (eventResult == WebInputEventResult::NotHandled && m_frame->view()) {
     FrameView* view = m_frame->view();
     PaintLayer* layer = mev.innerNode()->layoutObject()
                             ? mev.innerNode()->layoutObject()->enclosingLayer()
                             : nullptr;
-    IntPoint p = view->rootFrameToContents(mouseEvent.position());
+    IntPoint p = view->rootFrameToContents(
+        flooredIntPoint(mouseEvent.positionInRootFrame()));
     if (layer && layer->getScrollableArea() &&
         layer->getScrollableArea()->isPointInResizeControl(p,
                                                            ResizerForPointer)) {
@@ -678,7 +678,7 @@
   HitTestResult hitTestResult = EventHandlingUtil::hitTestResultInFrame(
       m_frame, documentPoint, HitTestRequest::ReadOnly);
   InputDeviceCapabilities* sourceCapabilities =
-      mouseEvent.getSyntheticEventType() == PlatformMouseEvent::FromTouch
+      mouseEvent.fromTouch()
           ? InputDeviceCapabilities::firesTouchEventsSourceCapabilities()
           : InputDeviceCapabilities::doesntFireTouchEventsSourceCapabilities();
   if (eventResult == WebInputEventResult::NotHandled) {
@@ -719,9 +719,8 @@
   }
 
   if (mev.hitTestResult().innerNode() &&
-      mouseEvent.pointerProperties().button ==
-          WebPointerProperties::Button::Left) {
-    ASSERT(mouseEvent.type() == PlatformEvent::MousePressed);
+      mouseEvent.button == WebPointerProperties::Button::Left) {
+    DCHECK_EQ(WebInputEvent::MouseDown, mouseEvent.type());
     HitTestResult result = mev.hitTestResult();
     result.setToShadowHostIfInUserAgentShadowRoot();
     m_frame->chromeClient().onMouseDown(result.innerNode());
@@ -731,8 +730,8 @@
 }
 
 WebInputEventResult EventHandler::handleMouseMoveEvent(
-    const PlatformMouseEvent& event,
-    const Vector<PlatformMouseEvent>& coalescedEvents) {
+    const WebMouseEvent& event,
+    const Vector<WebMouseEvent>& coalescedEvents) {
   TRACE_EVENT0("blink", "EventHandler::handleMouseMoveEvent");
 
   HitTestResult hoveredNode = HitTestResult();
@@ -759,16 +758,15 @@
   return result;
 }
 
-void EventHandler::handleMouseLeaveEvent(const PlatformMouseEvent& event) {
+void EventHandler::handleMouseLeaveEvent(const WebMouseEvent& event) {
   TRACE_EVENT0("blink", "EventHandler::handleMouseLeaveEvent");
 
-  handleMouseMoveOrLeaveEvent(event, Vector<PlatformMouseEvent>(), 0, false,
-                              true);
+  handleMouseMoveOrLeaveEvent(event, Vector<WebMouseEvent>(), 0, false, true);
 }
 
 WebInputEventResult EventHandler::handleMouseMoveOrLeaveEvent(
-    const PlatformMouseEvent& mouseEvent,
-    const Vector<PlatformMouseEvent>& coalescedEvents,
+    const WebMouseEvent& mouseEvent,
+    const Vector<WebMouseEvent>& coalescedEvents,
     HitTestResult* hoveredNode,
     bool onlyUpdateScrollbars,
     bool forceLeave) {
@@ -784,9 +782,9 @@
   m_mouseEventManager->handleSvgPanIfNeeded(false);
 
   if (m_frameSetBeingResized) {
-    return updatePointerTargetAndDispatchEvents(EventTypeNames::mousemove,
-                                                m_frameSetBeingResized.get(),
-                                                mouseEvent, coalescedEvents);
+    return updatePointerTargetAndDispatchEvents(
+        EventTypeNames::mousemove, m_frameSetBeingResized.get(), String(),
+        mouseEvent, coalescedEvents);
   }
 
   // Send events right to a scrollbar if the mouse is pressed.
@@ -862,7 +860,8 @@
   if (newSubframe) {
     // Update over/out state before passing the event to the subframe.
     m_pointerEventManager->sendMouseAndPointerBoundaryEvents(
-        updateMouseEventTargetNode(mev.innerNode()), mev.event());
+        updateMouseEventTargetNode(mev.innerNode()), mev.canvasRegionId(),
+        mev.event());
 
     // Event dispatch in sendMouseAndPointerBoundaryEvents may have caused the
     // subframe of the target node to be detached from its FrameView, in which
@@ -891,7 +890,8 @@
     return eventResult;
 
   eventResult = updatePointerTargetAndDispatchEvents(
-      EventTypeNames::mousemove, mev.innerNode(), mev.event(), coalescedEvents);
+      EventTypeNames::mousemove, mev.innerNode(), mev.canvasRegionId(),
+      mev.event(), coalescedEvents);
   if (eventResult != WebInputEventResult::NotHandled)
     return eventResult;
 
@@ -899,14 +899,13 @@
 }
 
 WebInputEventResult EventHandler::handleMouseReleaseEvent(
-    const PlatformMouseEvent& mouseEvent) {
+    const WebMouseEvent& mouseEvent) {
   TRACE_EVENT0("blink", "EventHandler::handleMouseReleaseEvent");
 
   // For 4th/5th button in the mouse since Chrome does not yet send
   // button value to Blink but in some cases it does send the event.
   // This check is needed to suppress such an event (crbug.com/574959)
-  if (mouseEvent.pointerProperties().button ==
-      WebPointerProperties::Button::NoButton)
+  if (mouseEvent.button == WebPointerProperties::Button::NoButton)
     return WebInputEventResult::HandledSuppressed;
 
   if (!mouseEvent.fromTouch())
@@ -924,7 +923,7 @@
 
   if (m_frameSetBeingResized) {
     return m_mouseEventManager->setMousePositionAndDispatchMouseEvent(
-        updateMouseEventTargetNode(m_frameSetBeingResized.get()),
+        updateMouseEventTargetNode(m_frameSetBeingResized.get()), String(),
         EventTypeNames::mouseup, mouseEvent);
   }
 
@@ -933,7 +932,7 @@
     m_lastScrollbarUnderMouse->mouseUp(mouseEvent);
     return updatePointerTargetAndDispatchEvents(
         EventTypeNames::mouseup, m_mouseEventManager->getNodeUnderMouse(),
-        mouseEvent, Vector<PlatformMouseEvent>());
+        String(), mouseEvent, Vector<WebMouseEvent>());
   }
 
   // Mouse events simulated from touch should not hit-test again.
@@ -971,8 +970,8 @@
   }
 
   WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents(
-      EventTypeNames::mouseup, mev.innerNode(), mev.event(),
-      Vector<PlatformMouseEvent>());
+      EventTypeNames::mouseup, mev.innerNode(), mev.canvasRegionId(),
+      mev.event(), Vector<WebMouseEvent>());
 
   WebInputEventResult clickEventResult =
       m_mouseEventManager->dispatchMouseClickIfNeeded(mev);
@@ -1044,7 +1043,7 @@
 }
 
 WebInputEventResult EventHandler::updateDragAndDrop(
-    const PlatformMouseEvent& event,
+    const WebMouseEvent& event,
     DataTransfer* dataTransfer) {
   WebInputEventResult eventResult = WebInputEventResult::NotHandled;
 
@@ -1062,9 +1061,11 @@
     newTarget = FlatTreeTraversal::parent(*newTarget);
 
   if (AutoscrollController* controller =
-          m_scrollManager->autoscrollController())
-    controller->updateDragAndDrop(newTarget, event.position(),
-                                  event.timestamp());
+          m_scrollManager->autoscrollController()) {
+    controller->updateDragAndDrop(
+        newTarget, flooredIntPoint(event.positionInRootFrame()),
+        TimeTicks::FromSeconds(event.timeStampSeconds()));
+  }
 
   if (m_dragTarget != newTarget) {
     // FIXME: this ordering was explicitly chosen to match WinIE. However,
@@ -1137,7 +1138,7 @@
   return eventResult;
 }
 
-void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event,
+void EventHandler::cancelDragAndDrop(const WebMouseEvent& event,
                                      DataTransfer* dataTransfer) {
   LocalFrame* targetFrame;
   if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
@@ -1153,7 +1154,7 @@
 }
 
 WebInputEventResult EventHandler::performDragAndDrop(
-    const PlatformMouseEvent& event,
+    const WebMouseEvent& event,
     DataTransfer* dataTransfer) {
   LocalFrame* targetFrame;
   WebInputEventResult result = WebInputEventResult::NotHandled;
@@ -1256,15 +1257,16 @@
 WebInputEventResult EventHandler::updatePointerTargetAndDispatchEvents(
     const AtomicString& mouseEventType,
     Node* targetNode,
-    const PlatformMouseEvent& mouseEvent,
-    const Vector<PlatformMouseEvent>& coalescedEvents) {
+    const String& canvasRegionId,
+    const WebMouseEvent& mouseEvent,
+    const Vector<WebMouseEvent>& coalescedEvents) {
   ASSERT(mouseEventType == EventTypeNames::mousedown ||
          mouseEventType == EventTypeNames::mousemove ||
          mouseEventType == EventTypeNames::mouseup);
 
   const auto& eventResult = m_pointerEventManager->sendMousePointerEvent(
-      updateMouseEventTargetNode(targetNode), mouseEventType, mouseEvent,
-      coalescedEvents);
+      updateMouseEventTargetNode(targetNode), canvasRegionId, mouseEventType,
+      mouseEvent, coalescedEvents);
   return eventResult;
 }
 
@@ -1617,33 +1619,33 @@
 
   const WebGestureEvent& gestureEvent = targetedEvent.event();
   unsigned modifiers = gestureEvent.modifiers();
-  PlatformMouseEvent fakeMouseMove(
-      gestureEvent, WebPointerProperties::Button::NoButton,
-      PlatformEvent::MouseMoved,
-      /* clickCount */ 0, static_cast<PlatformEvent::Modifiers>(modifiers),
-      PlatformMouseEvent::FromTouch,
-      TimeTicks::FromSeconds(gestureEvent.timeStampSeconds()),
-      WebPointerProperties::PointerType::Mouse);
+  WebMouseEvent fakeMouseMove(
+      WebInputEvent::MouseMove, gestureEvent,
+      WebPointerProperties::Button::NoButton,
+      /* clickCount */ 0,
+      modifiers | WebInputEvent::Modifiers::IsCompatibilityEventForTouch,
+      gestureEvent.timeStampSeconds());
 
   // Update the mouseout/mouseleave event
   size_t indexExitedFrameChain = exitedFrameChain.size();
   while (indexExitedFrameChain) {
     LocalFrame* leaveFrame = exitedFrameChain[--indexExitedFrameChain];
     leaveFrame->eventHandler().m_mouseEventManager->setNodeUnderMouse(
-        updateMouseEventTargetNode(nullptr), fakeMouseMove);
+        updateMouseEventTargetNode(nullptr), String(), fakeMouseMove);
   }
 
   // update the mouseover/mouseenter event
   while (indexEnteredFrameChain) {
     Frame* parentFrame =
         enteredFrameChain[--indexEnteredFrameChain]->tree().parent();
-    if (parentFrame && parentFrame->isLocalFrame())
+    if (parentFrame && parentFrame->isLocalFrame()) {
       toLocalFrame(parentFrame)
           ->eventHandler()
           .m_mouseEventManager->setNodeUnderMouse(
               updateMouseEventTargetNode(toHTMLFrameOwnerElement(
                   enteredFrameChain[indexEnteredFrameChain]->owner())),
-              fakeMouseMove);
+              String(), fakeMouseMove);
+    }
   }
 }
 
@@ -1782,7 +1784,7 @@
 }
 
 WebInputEventResult EventHandler::sendContextMenuEvent(
-    const PlatformMouseEvent& event,
+    const WebMouseEvent& event,
     Node* overrideTargetNode) {
   FrameView* v = m_frame->view();
   if (!v)
@@ -1791,7 +1793,8 @@
   // Clear mouse press state to avoid initiating a drag while context menu is
   // up.
   m_mouseEventManager->setMousePressed(false);
-  LayoutPoint positionInContents = v->rootFrameToContents(event.position());
+  LayoutPoint positionInContents =
+      v->rootFrameToContents(flooredIntPoint(event.positionInRootFrame()));
   HitTestRequest request(HitTestRequest::Active);
   MouseEventWithHitTestResults mev =
       m_frame->document()->performMouseEventHitTest(request, positionInContents,
@@ -1806,7 +1809,7 @@
   Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode();
   return m_mouseEventManager->dispatchMouseEvent(
       updateMouseEventTargetNode(targetNode), EventTypeNames::contextmenu,
-      event, 0);
+      event, mev.hitTestResult().canvasRegionId(), 0);
 }
 
 WebInputEventResult EventHandler::sendContextMenuEventForKey(
@@ -1883,15 +1886,20 @@
 
   // The contextmenu event is a mouse event even when invoked using the
   // keyboard.  This is required for web compatibility.
-  PlatformEvent::EventType eventType = PlatformEvent::MousePressed;
+  WebInputEvent::Type eventType = WebInputEvent::MouseDown;
   if (m_frame->settings() && m_frame->settings()->getShowContextMenuOnMouseUp())
-    eventType = PlatformEvent::MouseReleased;
+    eventType = WebInputEvent::MouseUp;
 
-  PlatformMouseEvent mouseEvent(
-      locationInRootFrame, globalPosition,
-      WebPointerProperties::Button::NoButton, eventType, /* clickCount */ 0,
-      PlatformEvent::NoModifiers, PlatformMouseEvent::RealOrIndistinguishable,
-      TimeTicks::Now(), WebPointerProperties::PointerType::Mouse);
+  WebMouseEvent mouseEvent(
+      eventType,
+      WebFloatPoint(locationInRootFrame.x(), locationInRootFrame.y()),
+      WebFloatPoint(globalPosition.x(), globalPosition.y()),
+      WebPointerProperties::Button::NoButton, /* clickCount */ 0,
+      PlatformEvent::NoModifiers, TimeTicks::Now().InSeconds());
+
+  // TODO(dtapuska): Transition the mouseEvent to be created really in viewport
+  // coordinates instead of root frame coordinates.
+  mouseEvent.setFrameScale(1);
 
   return sendContextMenuEvent(mouseEvent, overrideTargetElement);
 }
@@ -1987,7 +1995,7 @@
       event, m_mouseEventManager->mousePressNode());
 }
 
-void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event,
+void EventHandler::dragSourceEndedAt(const WebMouseEvent& event,
                                      DragOperation operation) {
   // Asides from routing the event to the correct frame, the hit test is also an
   // opportunity for Layer to update the :hover and :active pseudoclasses.
@@ -2100,7 +2108,7 @@
 
 WebInputEventResult EventHandler::passMouseMoveEventToSubframe(
     MouseEventWithHitTestResults& mev,
-    const Vector<PlatformMouseEvent>& coalescedEvents,
+    const Vector<WebMouseEvent>& coalescedEvents,
     LocalFrame* subframe,
     HitTestResult* hoveredNode) {
   if (m_mouseEventManager->mouseDownMayStartDrag())
diff --git a/third_party/WebKit/Source/core/input/EventHandler.h b/third_party/WebKit/Source/core/input/EventHandler.h
index 152219d..6b52de4 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.h
+++ b/third_party/WebKit/Source/core/input/EventHandler.h
@@ -38,7 +38,6 @@
 #include "core/page/EventWithHitTestResults.h"
 #include "core/style/ComputedStyleConstants.h"
 #include "platform/Cursor.h"
-#include "platform/PlatformMouseEvent.h"
 #include "platform/UserGestureIndicator.h"
 #include "platform/geometry/LayoutPoint.h"
 #include "platform/heap/Handle.h"
@@ -73,6 +72,7 @@
 class SelectionController;
 class TextEvent;
 class WebGestureEvent;
+class WebMouseEvent;
 class WebMouseWheelEvent;
 class WebTouchEvent;
 
@@ -113,11 +113,9 @@
   void setCapturingMouseEventsNode(
       Node*);  // A caller is responsible for resetting capturing node to 0.
 
-  WebInputEventResult updateDragAndDrop(const PlatformMouseEvent&,
-                                        DataTransfer*);
-  void cancelDragAndDrop(const PlatformMouseEvent&, DataTransfer*);
-  WebInputEventResult performDragAndDrop(const PlatformMouseEvent&,
-                                         DataTransfer*);
+  WebInputEventResult updateDragAndDrop(const WebMouseEvent&, DataTransfer*);
+  void cancelDragAndDrop(const WebMouseEvent&, DataTransfer*);
+  WebInputEventResult performDragAndDrop(const WebMouseEvent&, DataTransfer*);
   void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement);
 
   void scheduleHoverStateUpdate();
@@ -142,12 +140,12 @@
                       Node* startingNode = nullptr);
 
   WebInputEventResult handleMouseMoveEvent(
-      const PlatformMouseEvent&,
-      const Vector<PlatformMouseEvent>& coalescedEvents);
-  void handleMouseLeaveEvent(const PlatformMouseEvent&);
+      const WebMouseEvent&,
+      const Vector<WebMouseEvent>& coalescedEvents);
+  void handleMouseLeaveEvent(const WebMouseEvent&);
 
-  WebInputEventResult handleMousePressEvent(const PlatformMouseEvent&);
-  WebInputEventResult handleMouseReleaseEvent(const PlatformMouseEvent&);
+  WebInputEventResult handleMousePressEvent(const WebMouseEvent&);
+  WebInputEventResult handleMouseReleaseEvent(const WebMouseEvent&);
   WebInputEventResult handleWheelEvent(const WebMouseWheelEvent&);
 
   // Called on the local root frame exactly once per gesture event.
@@ -193,7 +191,7 @@
                                      IntRect& targetArea,
                                      Node*& targetNode);
 
-  WebInputEventResult sendContextMenuEvent(const PlatformMouseEvent&,
+  WebInputEventResult sendContextMenuEvent(const WebMouseEvent&,
                                            Node* overrideTargetNode = nullptr);
   WebInputEventResult sendContextMenuEventForKey(
       Element* overrideTargetElement = nullptr);
@@ -219,7 +217,7 @@
                             TextEventInputType = TextEventInputKeyboard);
   void defaultTextInputEventHandler(TextEvent*);
 
-  void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
+  void dragSourceEndedAt(const WebMouseEvent&, DragOperation);
 
   void capsLockStateMayHaveChanged();  // Only called by FrameSelection
 
@@ -260,8 +258,8 @@
 
  private:
   WebInputEventResult handleMouseMoveOrLeaveEvent(
-      const PlatformMouseEvent&,
-      const Vector<PlatformMouseEvent>&,
+      const WebMouseEvent&,
+      const Vector<WebMouseEvent>&,
       HitTestResult* hoveredNode = nullptr,
       bool onlyUpdateScrollbars = false,
       bool forceLeave = false);
@@ -302,13 +300,14 @@
   // preventDefaulted pointerdown (i.e., one of
   // {mousedown, mousemove, mouseup}).
   // TODO(mustaq): Can we avoid the clickCount param, instead use
-  // PlatformMouseEvent's count?
+  // WebmMouseEvent's count?
   //     Same applied to dispatchMouseEvent() above.
   WebInputEventResult updatePointerTargetAndDispatchEvents(
       const AtomicString& mouseEventType,
       Node* target,
-      const PlatformMouseEvent&,
-      const Vector<PlatformMouseEvent>& coalescedEvents);
+      const String& canvasRegionId,
+      const WebMouseEvent&,
+      const Vector<WebMouseEvent>& coalescedEvents);
 
   // Clears drag target and related states. It is called when drag is done or
   // canceled.
@@ -319,7 +318,7 @@
       LocalFrame* subframe);
   WebInputEventResult passMouseMoveEventToSubframe(
       MouseEventWithHitTestResults&,
-      const Vector<PlatformMouseEvent>&,
+      const Vector<WebMouseEvent>&,
       LocalFrame* subframe,
       HitTestResult* hoveredNode = nullptr);
   WebInputEventResult passMouseReleaseEventToSubframe(
diff --git a/third_party/WebKit/Source/core/input/EventHandlerTest.cpp b/third_party/WebKit/Source/core/input/EventHandlerTest.cpp
index 8ff61f1..e92bcffb 100644
--- a/third_party/WebKit/Source/core/input/EventHandlerTest.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandlerTest.cpp
@@ -14,7 +14,6 @@
 #include "core/page/AutoscrollController.h"
 #include "core/page/Page.h"
 #include "core/testing/DummyPageHolder.h"
-#include "platform/PlatformMouseEvent.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include <memory>
 
@@ -63,18 +62,20 @@
   }
 };
 
-class MousePressEventBuilder : public PlatformMouseEvent {
+class MousePressEventBuilder : public WebMouseEvent {
  public:
   MousePressEventBuilder(IntPoint position,
-                         int clickCount,
-                         WebMouseEvent::Button button)
-      : PlatformMouseEvent(position,
-                           position,
-                           button,
-                           PlatformEvent::MousePressed,
-                           clickCount,
-                           static_cast<PlatformEvent::Modifiers>(0),
-                           TimeTicks::Now()) {}
+                         int clickCountParam,
+                         WebMouseEvent::Button buttonParam)
+      : WebMouseEvent(WebInputEvent::MouseDown,
+                      WebInputEvent::NoModifiers,
+                      TimeTicks::Now().InSeconds()) {
+    clickCount = clickCountParam;
+    button = buttonParam;
+    x = globalX = position.x();
+    y = globalY = position.y();
+    m_frameScale = 1;
+  }
 };
 
 void EventHandlerTest::SetUp() {
@@ -105,27 +106,32 @@
   frameView->layoutViewportScrollableArea()->setScrollOffset(
       ScrollOffset(0, 400), ProgrammaticScroll);
 
-  PlatformMouseEvent mouseDownEvent(
-      IntPoint(0, 0), IntPoint(100, 200), WebPointerProperties::Button::Left,
-      PlatformEvent::MousePressed, 1, PlatformEvent::Modifiers::LeftButtonDown,
-      TimeTicks::Now());
+  WebMouseEvent mouseDownEvent(WebInputEvent::MouseDown, WebFloatPoint(0, 0),
+                               WebFloatPoint(100, 200),
+                               WebPointerProperties::Button::Left, 1,
+                               WebInputEvent::Modifiers::LeftButtonDown,
+                               WebInputEvent::TimeStampForTesting);
+  mouseDownEvent.setFrameScale(1);
   document().frame()->eventHandler().handleMousePressEvent(mouseDownEvent);
 
-  PlatformMouseEvent mouseMoveEvent(
-      IntPoint(100, 50), IntPoint(200, 250), WebPointerProperties::Button::Left,
-      PlatformEvent::MouseMoved, 1, PlatformEvent::Modifiers::LeftButtonDown,
-      TimeTicks::Now());
+  WebMouseEvent mouseMoveEvent(WebInputEvent::MouseMove, WebFloatPoint(100, 50),
+                               WebFloatPoint(200, 250),
+                               WebPointerProperties::Button::Left, 1,
+                               WebInputEvent::Modifiers::LeftButtonDown,
+                               WebInputEvent::TimeStampForTesting);
+  mouseMoveEvent.setFrameScale(1);
   document().frame()->eventHandler().handleMouseMoveEvent(
-      mouseMoveEvent, Vector<PlatformMouseEvent>());
+      mouseMoveEvent, Vector<WebMouseEvent>());
 
   page().autoscrollController().animate(WTF::monotonicallyIncreasingTime());
   page().animator().serviceScriptedAnimations(
       WTF::monotonicallyIncreasingTime());
 
-  PlatformMouseEvent mouseUpEvent(
-      IntPoint(100, 50), IntPoint(200, 250), WebPointerProperties::Button::Left,
-      PlatformEvent::MouseReleased, 1, static_cast<PlatformEvent::Modifiers>(0),
-      TimeTicks::Now());
+  WebMouseEvent mouseUpEvent(
+      WebMouseEvent::MouseUp, WebFloatPoint(100, 50), WebFloatPoint(200, 250),
+      WebPointerProperties::Button::Left, 1, WebInputEvent::NoModifiers,
+      WebInputEvent::TimeStampForTesting);
+  mouseUpEvent.setFrameScale(1);
   document().frame()->eventHandler().handleMouseReleaseEvent(mouseUpEvent);
 
   ASSERT_TRUE(selection().isRange());
@@ -206,18 +212,22 @@
       "<div style='width: 300px; height: 100px;'>"
       "<span class='line' draggable='true'>abcd</span>"
       "</div>");
-  PlatformMouseEvent mouseDownEvent(
-      IntPoint(262, 29), IntPoint(329, 67), WebPointerProperties::Button::Left,
-      PlatformEvent::MousePressed, 1, PlatformEvent::Modifiers::LeftButtonDown,
-      TimeTicks::Now());
+  WebMouseEvent mouseDownEvent(WebMouseEvent::MouseDown, WebFloatPoint(262, 29),
+                               WebFloatPoint(329, 67),
+                               WebPointerProperties::Button::Left, 1,
+                               WebInputEvent::Modifiers::LeftButtonDown,
+                               WebInputEvent::TimeStampForTesting);
+  mouseDownEvent.setFrameScale(1);
   document().frame()->eventHandler().handleMousePressEvent(mouseDownEvent);
 
-  PlatformMouseEvent mouseMoveEvent(
-      IntPoint(618, 298), IntPoint(685, 436),
-      WebPointerProperties::Button::Left, PlatformEvent::MouseMoved, 1,
-      PlatformEvent::Modifiers::LeftButtonDown, TimeTicks::Now());
+  WebMouseEvent mouseMoveEvent(WebMouseEvent::MouseMove,
+                               WebFloatPoint(618, 298), WebFloatPoint(685, 436),
+                               WebPointerProperties::Button::Left, 1,
+                               WebInputEvent::Modifiers::LeftButtonDown,
+                               WebInputEvent::TimeStampForTesting);
+  mouseMoveEvent.setFrameScale(1);
   document().frame()->eventHandler().handleMouseMoveEvent(
-      mouseMoveEvent, Vector<PlatformMouseEvent>());
+      mouseMoveEvent, Vector<WebMouseEvent>());
 
   EXPECT_EQ(
       IntPoint(12, 29),
@@ -238,18 +248,22 @@
       "draggable='true'/>"
       "</svg>"
       "</div>");
-  PlatformMouseEvent mouseDownEvent(
-      IntPoint(145, 144), IntPoint(212, 282),
-      WebPointerProperties::Button::Left, PlatformEvent::MousePressed, 1,
-      PlatformEvent::Modifiers::LeftButtonDown, TimeTicks::Now());
+  WebMouseEvent mouseDownEvent(WebMouseEvent::MouseDown,
+                               WebFloatPoint(145, 144), WebFloatPoint(212, 282),
+                               WebPointerProperties::Button::Left, 1,
+                               WebInputEvent::Modifiers::LeftButtonDown,
+                               WebInputEvent::TimeStampForTesting);
+  mouseDownEvent.setFrameScale(1);
   document().frame()->eventHandler().handleMousePressEvent(mouseDownEvent);
 
-  PlatformMouseEvent mouseMoveEvent(
-      IntPoint(618, 298), IntPoint(685, 436),
-      WebPointerProperties::Button::Left, PlatformEvent::MouseMoved, 1,
-      PlatformEvent::Modifiers::LeftButtonDown, TimeTicks::Now());
+  WebMouseEvent mouseMoveEvent(WebMouseEvent::MouseMove,
+                               WebFloatPoint(618, 298), WebFloatPoint(685, 436),
+                               WebPointerProperties::Button::Left, 1,
+                               WebInputEvent::Modifiers::LeftButtonDown,
+                               WebInputEvent::TimeStampForTesting);
+  mouseMoveEvent.setFrameScale(1);
   document().frame()->eventHandler().handleMouseMoveEvent(
-      mouseMoveEvent, Vector<PlatformMouseEvent>());
+      mouseMoveEvent, Vector<WebMouseEvent>());
 
   EXPECT_EQ(
       IntPoint(45, 44),
@@ -273,10 +287,11 @@
       SelectionInDOMTree::Builder()
           .collapse(Position(document().body(), 0))
           .build());
-  PlatformMouseEvent mouseDownEvent(
-      IntPoint(0, 0), IntPoint(100, 200), WebPointerProperties::Button::Right,
-      PlatformEvent::MousePressed, 1, PlatformEvent::Modifiers::RightButtonDown,
-      TimeTicks::Now());
+  WebMouseEvent mouseDownEvent(
+      WebMouseEvent::MouseDown, WebFloatPoint(0, 0), WebFloatPoint(100, 200),
+      WebPointerProperties::Button::Right, 1,
+      PlatformEvent::Modifiers::RightButtonDown, TimeTicks::Now().InSeconds());
+  mouseDownEvent.setFrameScale(1);
   EXPECT_EQ(
       WebInputEventResult::HandledApplication,
       document().frame()->eventHandler().sendContextMenuEvent(mouseDownEvent));
@@ -387,18 +402,20 @@
       "<style>.box { width: 100px; height: 100px; display: block; }</style>"
       "<a class='box' href=''>Drag me</a>");
 
-  PlatformMouseEvent mouseDownEvent(
-      IntPoint(50, 50), IntPoint(50, 50), WebPointerProperties::Button::Left,
-      PlatformEvent::MousePressed, 1, PlatformEvent::Modifiers::LeftButtonDown,
-      TimeTicks::Now());
+  WebMouseEvent mouseDownEvent(
+      WebInputEvent::MouseDown, WebFloatPoint(50, 50), WebFloatPoint(50, 50),
+      WebPointerProperties::Button::Left, 1,
+      PlatformEvent::Modifiers::LeftButtonDown, TimeTicks::Now().InSeconds());
+  mouseDownEvent.setFrameScale(1);
   document().frame()->eventHandler().handleMousePressEvent(mouseDownEvent);
 
-  PlatformMouseEvent mouseMoveEvent(
-      IntPoint(51, 50), IntPoint(51, 50), WebPointerProperties::Button::Left,
-      PlatformEvent::MouseMoved, 1, PlatformEvent::Modifiers::LeftButtonDown,
-      TimeTicks::Now());
+  WebMouseEvent mouseMoveEvent(
+      WebInputEvent::MouseMove, WebFloatPoint(51, 50), WebFloatPoint(51, 50),
+      WebPointerProperties::Button::Left, 1,
+      PlatformEvent::Modifiers::LeftButtonDown, TimeTicks::Now().InSeconds());
+  mouseMoveEvent.setFrameScale(1);
   document().frame()->eventHandler().handleMouseMoveEvent(
-      mouseMoveEvent, Vector<PlatformMouseEvent>());
+      mouseMoveEvent, Vector<WebMouseEvent>());
 
   // This reproduces what might be the conditions of http://crbug.com/677916
   //
@@ -406,10 +423,11 @@
   // this contrived test. Given the current code, it is unclear how the
   // dragSourceEndedAt() call could occur before a drag operation is started.
 
-  PlatformMouseEvent mouseUpEvent(
-      IntPoint(100, 50), IntPoint(200, 250), WebPointerProperties::Button::Left,
-      PlatformEvent::MouseReleased, 1, static_cast<PlatformEvent::Modifiers>(0),
-      TimeTicks::Now());
+  WebMouseEvent mouseUpEvent(
+      WebInputEvent::MouseUp, WebFloatPoint(100, 50), WebFloatPoint(200, 250),
+      WebPointerProperties::Button::Left, 1,
+      static_cast<PlatformEvent::Modifiers>(0), TimeTicks::Now().InSeconds());
+  mouseUpEvent.setFrameScale(1);
   document().frame()->eventHandler().dragSourceEndedAt(mouseUpEvent,
                                                        DragOperationNone);
 
diff --git a/third_party/WebKit/Source/core/input/EventHandlingUtil.cpp b/third_party/WebKit/Source/core/input/EventHandlingUtil.cpp
index 908de11..4c8e0fb 100644
--- a/third_party/WebKit/Source/core/input/EventHandlingUtil.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandlingUtil.cpp
@@ -9,6 +9,7 @@
 #include "core/layout/api/LayoutViewItem.h"
 #include "core/paint/PaintLayer.h"
 #include "platform/scroll/ScrollableArea.h"
+#include "public/platform/WebMouseEvent.h"
 
 namespace blink {
 namespace EventHandlingUtil {
@@ -110,12 +111,14 @@
 MouseEventWithHitTestResults performMouseEventHitTest(
     LocalFrame* frame,
     const HitTestRequest& request,
-    const PlatformMouseEvent& mev) {
+    const WebMouseEvent& mev) {
   DCHECK(frame);
   DCHECK(frame->document());
 
   return frame->document()->performMouseEventHitTest(
-      request, contentPointFromRootFrame(frame, mev.position()), mev);
+      request, contentPointFromRootFrame(
+                   frame, flooredIntPoint(mev.positionInRootFrame())),
+      mev);
 }
 
 }  // namespace EventHandlingUtil
diff --git a/third_party/WebKit/Source/core/input/EventHandlingUtil.h b/third_party/WebKit/Source/core/input/EventHandlingUtil.h
index 558ae12..8e45b6b 100644
--- a/third_party/WebKit/Source/core/input/EventHandlingUtil.h
+++ b/third_party/WebKit/Source/core/input/EventHandlingUtil.h
@@ -36,10 +36,9 @@
 LayoutPoint contentPointFromRootFrame(LocalFrame*,
                                       const IntPoint& pointInRootFrame);
 
-MouseEventWithHitTestResults performMouseEventHitTest(
-    LocalFrame*,
-    const HitTestRequest&,
-    const PlatformMouseEvent&);
+MouseEventWithHitTestResults performMouseEventHitTest(LocalFrame*,
+                                                      const HitTestRequest&,
+                                                      const WebMouseEvent&);
 
 }  // namespace EventHandlingUtil
 
diff --git a/third_party/WebKit/Source/core/input/GestureManager.cpp b/third_party/WebKit/Source/core/input/GestureManager.cpp
index 780be371..5646057 100644
--- a/third_party/WebKit/Source/core/input/GestureManager.cpp
+++ b/third_party/WebKit/Source/core/input/GestureManager.cpp
@@ -150,15 +150,16 @@
   const unsigned modifiers = gestureEvent.modifiers();
 
   if (!m_suppressMouseEventsFromGestures) {
-    PlatformMouseEvent fakeMouseMove(
-        gestureEvent, WebPointerProperties::Button::NoButton,
-        PlatformEvent::MouseMoved,
-        /* clickCount */ 0, static_cast<PlatformEvent::Modifiers>(modifiers),
-        PlatformMouseEvent::FromTouch,
-        TimeTicks::FromSeconds(gestureEvent.timeStampSeconds()),
-        WebPointerProperties::PointerType::Mouse);
+    WebMouseEvent fakeMouseMove(
+        WebInputEvent::MouseMove, gestureEvent,
+        WebPointerProperties::Button::NoButton,
+        /* clickCount */ 0,
+        static_cast<PlatformEvent::Modifiers>(
+            modifiers | WebInputEvent::Modifiers::IsCompatibilityEventForTouch),
+        gestureEvent.timeStampSeconds());
     m_mouseEventManager->setMousePositionAndDispatchMouseEvent(
-        currentHitTest.innerNode(), EventTypeNames::mousemove, fakeMouseMove);
+        currentHitTest.innerNode(), currentHitTest.canvasRegionId(),
+        EventTypeNames::mousemove, fakeMouseMove);
   }
 
   // Do a new hit-test in case the mousemove event changed the DOM.
@@ -192,14 +193,13 @@
 
   m_mouseEventManager->setClickNode(tappedNonTextNode);
 
-  PlatformMouseEvent fakeMouseDown(
-      gestureEvent, WebPointerProperties::Button::Left,
-      PlatformEvent::MousePressed, gestureEvent.tapCount(),
-      static_cast<PlatformEvent::Modifiers>(modifiers |
-                                            PlatformEvent::LeftButtonDown),
-      PlatformMouseEvent::FromTouch,
-      TimeTicks::FromSeconds(gestureEvent.timeStampSeconds()),
-      WebPointerProperties::PointerType::Mouse);
+  WebMouseEvent fakeMouseDown(
+      WebInputEvent::MouseDown, gestureEvent,
+      WebPointerProperties::Button::Left, gestureEvent.tapCount(),
+      static_cast<PlatformEvent::Modifiers>(
+          modifiers | WebInputEvent::Modifiers::LeftButtonDown |
+          WebInputEvent::Modifiers::IsCompatibilityEventForTouch),
+      gestureEvent.timeStampSeconds());
 
   // TODO(mustaq): We suppress MEs plus all it's side effects. What would that
   // mean for for TEs?  What's the right balance here? crbug.com/617255
@@ -210,8 +210,8 @@
 
     mouseDownEventResult =
         m_mouseEventManager->setMousePositionAndDispatchMouseEvent(
-            currentHitTest.innerNode(), EventTypeNames::mousedown,
-            fakeMouseDown);
+            currentHitTest.innerNode(), currentHitTest.canvasRegionId(),
+            EventTypeNames::mousedown, fakeMouseDown);
     m_selectionController->initializeSelectionState();
     if (mouseDownEventResult == WebInputEventResult::NotHandled)
       mouseDownEventResult = m_mouseEventManager->handleMouseFocus(
@@ -240,19 +240,18 @@
         m_frame, adjustedPoint, hitType);
   }
 
-  PlatformMouseEvent fakeMouseUp(
-      gestureEvent, WebPointerProperties::Button::Left,
-      PlatformEvent::MouseReleased, gestureEvent.tapCount(),
-      static_cast<PlatformEvent::Modifiers>(modifiers),
-      PlatformMouseEvent::FromTouch,
-      TimeTicks::FromSeconds(gestureEvent.timeStampSeconds()),
-      WebPointerProperties::PointerType::Mouse);
+  WebMouseEvent fakeMouseUp(
+      WebInputEvent::MouseUp, gestureEvent, WebPointerProperties::Button::Left,
+      gestureEvent.tapCount(),
+      static_cast<PlatformEvent::Modifiers>(
+          modifiers | WebInputEvent::Modifiers::IsCompatibilityEventForTouch),
+      gestureEvent.timeStampSeconds());
   WebInputEventResult mouseUpEventResult =
       m_suppressMouseEventsFromGestures
           ? WebInputEventResult::HandledSuppressed
           : m_mouseEventManager->setMousePositionAndDispatchMouseEvent(
-                currentHitTest.innerNode(), EventTypeNames::mouseup,
-                fakeMouseUp);
+                currentHitTest.innerNode(), currentHitTest.canvasRegionId(),
+                EventTypeNames::mouseup, fakeMouseUp);
 
   WebInputEventResult clickEventResult = WebInputEventResult::NotHandled;
   if (tappedNonTextNode) {
@@ -268,7 +267,7 @@
           *tappedNonTextNode, EventHandlingUtil::parentForClickEvent);
       clickEventResult =
           m_mouseEventManager->setMousePositionAndDispatchMouseEvent(
-              clickTargetNode, EventTypeNames::click, fakeMouseUp);
+              clickTargetNode, String(), EventTypeNames::click, fakeMouseUp);
     }
     m_mouseEventManager->setClickNode(nullptr);
   }
@@ -361,30 +360,31 @@
   unsigned modifiers = gestureEvent.modifiers();
 
   if (!m_suppressMouseEventsFromGestures) {
-    // Send MouseMoved event prior to handling (https://crbug.com/485290).
-    PlatformMouseEvent fakeMouseMove(
-        gestureEvent, WebPointerProperties::Button::NoButton,
-        PlatformEvent::MouseMoved,
-        /* clickCount */ 0, static_cast<PlatformEvent::Modifiers>(modifiers),
-        PlatformMouseEvent::FromTouch,
-        TimeTicks::FromSeconds(gestureEvent.timeStampSeconds()),
-        WebPointerProperties::PointerType::Mouse);
+    // Send MouseMove event prior to handling (https://crbug.com/485290).
+    WebMouseEvent fakeMouseMove(
+        WebInputEvent::MouseMove, gestureEvent,
+        WebPointerProperties::Button::NoButton,
+        /* clickCount */ 0,
+        static_cast<PlatformEvent::Modifiers>(
+            modifiers | WebInputEvent::IsCompatibilityEventForTouch),
+        gestureEvent.timeStampSeconds());
     m_mouseEventManager->setMousePositionAndDispatchMouseEvent(
-        targetedEvent.hitTestResult().innerNode(), EventTypeNames::mousemove,
+        targetedEvent.hitTestResult().innerNode(),
+        targetedEvent.canvasRegionId(), EventTypeNames::mousemove,
         fakeMouseMove);
   }
 
-  PlatformEvent::EventType eventType = PlatformEvent::MousePressed;
+  WebInputEvent::Type eventType = WebInputEvent::MouseDown;
   if (m_frame->settings() && m_frame->settings()->getShowContextMenuOnMouseUp())
-    eventType = PlatformEvent::MouseReleased;
+    eventType = WebInputEvent::MouseUp;
 
-  PlatformMouseEvent mouseEvent(
-      gestureEvent, WebPointerProperties::Button::Right, eventType,
+  WebMouseEvent mouseEvent(
+      eventType, gestureEvent, WebPointerProperties::Button::Right,
       /* clickCount */ 1,
       static_cast<PlatformEvent::Modifiers>(
-          modifiers | PlatformEvent::Modifiers::RightButtonDown),
-      PlatformMouseEvent::FromTouch, TimeTicks::Now(),
-      WebPointerProperties::PointerType::Mouse);
+          modifiers | PlatformEvent::Modifiers::RightButtonDown |
+          WebInputEvent::IsCompatibilityEventForTouch),
+      gestureEvent.timeStampSeconds());
 
   if (!m_suppressMouseEventsFromGestures && m_frame->view()) {
     HitTestRequest request(HitTestRequest::Active);
diff --git a/third_party/WebKit/Source/core/input/MouseEventManager.cpp b/third_party/WebKit/Source/core/input/MouseEventManager.cpp
index bb29431..aaca3de 100644
--- a/third_party/WebKit/Source/core/input/MouseEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/MouseEventManager.cpp
@@ -35,25 +35,21 @@
 
 namespace {
 
-PlatformMouseEvent mouseEventWithRegion(Node* node,
-                                        const PlatformMouseEvent& mouseEvent) {
+String canvasRegionId(Node* node, const WebMouseEvent& mouseEvent) {
   if (!node->isElementNode())
-    return mouseEvent;
+    return String();
 
   Element* element = toElement(node);
   if (!element->isInCanvasSubtree())
-    return mouseEvent;
+    return String();
 
   HTMLCanvasElement* canvas =
       Traversal<HTMLCanvasElement>::firstAncestorOrSelf(*element);
   // In this case, the event target is canvas and mouse rerouting doesn't
   // happen.
   if (canvas == element)
-    return mouseEvent;
-  String region = canvas->getIdFromControl(element);
-  PlatformMouseEvent newMouseEvent = mouseEvent;
-  newMouseEvent.setRegion(region);
-  return newMouseEvent;
+    return String();
+  return canvas->getIdFromControl(element);
 }
 
 // The amount of time to wait before sending a fake mouse event triggered
@@ -100,7 +96,7 @@
   m_clickNode = nullptr;
   m_mouseDownPos = IntPoint();
   m_mouseDownTimestamp = TimeTicks();
-  m_mouseDown = PlatformMouseEvent();
+  m_mouseDown = WebMouseEvent();
   m_svgPan = false;
   m_dragStartPos = LayoutPoint();
   m_fakeMouseMoveEventTimer.stop();
@@ -118,46 +114,45 @@
 }
 
 MouseEventManager::MouseEventBoundaryEventDispatcher::
-    MouseEventBoundaryEventDispatcher(
-        MouseEventManager* mouseEventManager,
-        const PlatformMouseEvent* platformMouseEvent,
-        EventTarget* exitedTarget)
+    MouseEventBoundaryEventDispatcher(MouseEventManager* mouseEventManager,
+                                      const WebMouseEvent* webMouseEvent,
+                                      EventTarget* exitedTarget,
+                                      const String& canvasRegionId)
     : m_mouseEventManager(mouseEventManager),
-      m_platformMouseEvent(platformMouseEvent),
-      m_exitedTarget(exitedTarget) {}
+      m_webMouseEvent(webMouseEvent),
+      m_exitedTarget(exitedTarget),
+      m_canvasRegionId(canvasRegionId) {}
 
 void MouseEventManager::MouseEventBoundaryEventDispatcher::dispatchOut(
     EventTarget* target,
     EventTarget* relatedTarget) {
-  dispatch(
-      target, relatedTarget, EventTypeNames::mouseout,
-      mouseEventWithRegion(m_exitedTarget->toNode(), *m_platformMouseEvent),
-      false);
+  dispatch(target, relatedTarget, EventTypeNames::mouseout,
+           canvasRegionId(m_exitedTarget->toNode(), *m_webMouseEvent),
+           *m_webMouseEvent, false);
 }
 
 void MouseEventManager::MouseEventBoundaryEventDispatcher::dispatchOver(
     EventTarget* target,
     EventTarget* relatedTarget) {
-  dispatch(target, relatedTarget, EventTypeNames::mouseover,
-           *m_platformMouseEvent, false);
+  dispatch(target, relatedTarget, EventTypeNames::mouseover, m_canvasRegionId,
+           *m_webMouseEvent, false);
 }
 
 void MouseEventManager::MouseEventBoundaryEventDispatcher::dispatchLeave(
     EventTarget* target,
     EventTarget* relatedTarget,
     bool checkForListener) {
-  dispatch(
-      target, relatedTarget, EventTypeNames::mouseleave,
-      mouseEventWithRegion(m_exitedTarget->toNode(), *m_platformMouseEvent),
-      checkForListener);
+  dispatch(target, relatedTarget, EventTypeNames::mouseleave,
+           canvasRegionId(m_exitedTarget->toNode(), *m_webMouseEvent),
+           *m_webMouseEvent, checkForListener);
 }
 
 void MouseEventManager::MouseEventBoundaryEventDispatcher::dispatchEnter(
     EventTarget* target,
     EventTarget* relatedTarget,
     bool checkForListener) {
-  dispatch(target, relatedTarget, EventTypeNames::mouseenter,
-           *m_platformMouseEvent, checkForListener);
+  dispatch(target, relatedTarget, EventTypeNames::mouseenter, m_canvasRegionId,
+           *m_webMouseEvent, checkForListener);
 }
 
 AtomicString
@@ -174,25 +169,28 @@
     EventTarget* target,
     EventTarget* relatedTarget,
     const AtomicString& type,
-    const PlatformMouseEvent& platformMouseEvent,
+    const String& canvasRegionId,
+    const WebMouseEvent& webMouseEvent,
     bool checkForListener) {
-  m_mouseEventManager->dispatchMouseEvent(target, type, platformMouseEvent,
-                                          relatedTarget, checkForListener);
+  m_mouseEventManager->dispatchMouseEvent(target, type, webMouseEvent,
+                                          canvasRegionId, relatedTarget,
+                                          checkForListener);
 }
 
-void MouseEventManager::sendBoundaryEvents(
-    EventTarget* exitedTarget,
-    EventTarget* enteredTarget,
-    const PlatformMouseEvent& mousePlatformEvent) {
+void MouseEventManager::sendBoundaryEvents(EventTarget* exitedTarget,
+                                           EventTarget* enteredTarget,
+                                           const String& canvasRegionId,
+                                           const WebMouseEvent& mouseEvent) {
   MouseEventBoundaryEventDispatcher boundaryEventDispatcher(
-      this, &mousePlatformEvent, exitedTarget);
+      this, &mouseEvent, exitedTarget, canvasRegionId);
   boundaryEventDispatcher.sendBoundaryEvents(exitedTarget, enteredTarget);
 }
 
 WebInputEventResult MouseEventManager::dispatchMouseEvent(
     EventTarget* target,
     const AtomicString& mouseEventType,
-    const PlatformMouseEvent& mouseEvent,
+    const WebMouseEvent& mouseEvent,
+    const String& canvasRegionId,
     EventTarget* relatedTarget,
     bool checkForListener) {
   if (target && target->toNode() &&
@@ -206,9 +204,10 @@
         mouseEventType == EventTypeNames::dblclick) {
       clickCount = m_clickCount;
     }
-    MouseEvent* event = MouseEvent::create(
-        mouseEventType, targetNode->document().domWindow(), mouseEvent,
-        clickCount, relatedTarget ? relatedTarget->toNode() : nullptr);
+    MouseEvent* event =
+        MouseEvent::create(mouseEventType, targetNode->document().domWindow(),
+                           mouseEvent, clickCount, canvasRegionId,
+                           relatedTarget ? relatedTarget->toNode() : nullptr);
     DispatchEventResult dispatchResult = target->dispatchEvent(event);
     return EventHandlingUtil::toWebInputEventResult(dispatchResult);
   }
@@ -217,32 +216,32 @@
 
 WebInputEventResult MouseEventManager::setMousePositionAndDispatchMouseEvent(
     Node* targetNode,
+    const String& canvasRegionId,
     const AtomicString& eventType,
-    const PlatformMouseEvent& platformMouseEvent) {
+    const WebMouseEvent& webMouseEvent) {
   // If the target node is a text node, dispatch on the parent node.
   if (targetNode && targetNode->isTextNode())
     targetNode = FlatTreeTraversal::parent(*targetNode);
 
-  setNodeUnderMouse(targetNode, platformMouseEvent);
+  setNodeUnderMouse(targetNode, canvasRegionId, webMouseEvent);
 
-  return dispatchMouseEvent(m_nodeUnderMouse, eventType, platformMouseEvent,
-                            nullptr);
+  return dispatchMouseEvent(m_nodeUnderMouse, eventType, webMouseEvent,
+                            canvasRegionId, nullptr);
 }
 
 WebInputEventResult MouseEventManager::dispatchMouseClickIfNeeded(
     const MouseEventWithHitTestResults& mev) {
   // We only prevent click event when the click may cause contextmenu to popup.
   // However, we always send auxclick.
-  bool contextMenuEvent = !RuntimeEnabledFeatures::auxclickEnabled() &&
-                          mev.event().pointerProperties().button ==
-                              WebPointerProperties::Button::Right;
+  bool contextMenuEvent =
+      !RuntimeEnabledFeatures::auxclickEnabled() &&
+      mev.event().button == WebPointerProperties::Button::Right;
 #if OS(MACOSX)
   // FIXME: The Mac port achieves the same behavior by checking whether the
   // context menu is currently open in WebPage::mouseEvent(). Consider merging
   // the implementations.
-  if (mev.event().pointerProperties().button ==
-          WebPointerProperties::Button::Left &&
-      mev.event().getModifiers() & PlatformEvent::CtrlKey)
+  if (mev.event().button == WebPointerProperties::Button::Left &&
+      mev.event().modifiers() & WebInputEvent::Modifiers::ControlKey)
     contextMenuEvent = true;
 #endif
 
@@ -269,12 +268,12 @@
     }
     if (clickTargetNode) {
       clickEventResult = dispatchMouseEvent(
-          clickTargetNode, !RuntimeEnabledFeatures::auxclickEnabled() ||
-                                   (mev.event().pointerProperties().button ==
-                                    WebPointerProperties::Button::Left)
-                               ? EventTypeNames::click
-                               : EventTypeNames::auxclick,
-          mev.event(), nullptr);
+          clickTargetNode,
+          !RuntimeEnabledFeatures::auxclickEnabled() ||
+                  (mev.event().button == WebPointerProperties::Button::Left)
+              ? EventTypeNames::click
+              : EventTypeNames::auxclick,
+          mev.event(), mev.canvasRegionId(), nullptr);
     }
   }
   return clickEventResult;
@@ -300,14 +299,17 @@
   if (!m_frame->page()->isCursorVisible())
     return;
 
-  PlatformMouseEvent fakeMouseMoveEvent(
-      m_lastKnownMousePosition, m_lastKnownMouseGlobalPosition,
-      WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, 0,
-      static_cast<PlatformEvent::Modifiers>(
-          KeyboardEventManager::getCurrentModifierState()),
-      PlatformMouseEvent::RealOrIndistinguishable, TimeTicks::Now(),
-      WebPointerProperties::PointerType::Mouse);
-  Vector<PlatformMouseEvent> coalescedEvents;
+  WebMouseEvent fakeMouseMoveEvent(
+      WebInputEvent::MouseMove,
+      WebFloatPoint(m_lastKnownMousePosition.x(), m_lastKnownMousePosition.y()),
+      WebFloatPoint(m_lastKnownMouseGlobalPosition.x(),
+                    m_lastKnownMouseGlobalPosition.y()),
+      WebPointerProperties::Button::NoButton, 0,
+      KeyboardEventManager::getCurrentModifierState(),
+      TimeTicks::Now().InSeconds());
+  // TODO(dtapuska): Update m_lastKnowMousePosition to be viewport coordinates.
+  fakeMouseMoveEvent.setFrameScale(1);
+  Vector<WebMouseEvent> coalescedEvents;
   m_frame->eventHandler().handleMouseMoveEvent(fakeMouseMoveEvent,
                                                coalescedEvents);
 }
@@ -316,9 +318,9 @@
   m_fakeMouseMoveEventTimer.stop();
 }
 
-void MouseEventManager::setNodeUnderMouse(
-    Node* target,
-    const PlatformMouseEvent& platformMouseEvent) {
+void MouseEventManager::setNodeUnderMouse(Node* target,
+                                          const String& canvasRegionId,
+                                          const WebMouseEvent& webMouseEvent) {
   Node* lastNodeUnderMouse = m_nodeUnderMouse;
   m_nodeUnderMouse = target;
 
@@ -367,7 +369,8 @@
     lastNodeUnderMouse = nullptr;
   }
 
-  sendBoundaryEvents(lastNodeUnderMouse, m_nodeUnderMouse, platformMouseEvent);
+  sendBoundaryEvents(lastNodeUnderMouse, m_nodeUnderMouse, canvasRegionId,
+                     webMouseEvent);
 }
 
 void MouseEventManager::nodeChildrenWillBeRemoved(ContainerNode& container) {
@@ -493,17 +496,18 @@
 }
 
 void MouseEventManager::handleMousePressEventUpdateStates(
-    const PlatformMouseEvent& mouseEvent) {
+    const WebMouseEvent& mouseEvent) {
   cancelFakeMouseMoveEvent();
   m_mousePressed = true;
   m_capturesDragging = true;
   setLastKnownMousePosition(mouseEvent);
   m_mouseDownMayStartDrag = false;
   m_mouseDownMayStartAutoscroll = false;
-  m_mouseDownTimestamp = mouseEvent.timestamp();
+  m_mouseDownTimestamp = TimeTicks::FromSeconds(mouseEvent.timeStampSeconds());
 
   if (FrameView* view = m_frame->view()) {
-    m_mouseDownPos = view->rootFrameToContents(mouseEvent.position());
+    m_mouseDownPos = view->rootFrameToContents(
+        flooredIntPoint(mouseEvent.positionInRootFrame()));
   } else {
     invalidateClick();
   }
@@ -517,11 +521,10 @@
   return m_lastKnownMousePosition;
 }
 
-void MouseEventManager::setLastKnownMousePosition(
-    const PlatformMouseEvent& event) {
+void MouseEventManager::setLastKnownMousePosition(const WebMouseEvent& event) {
   m_isMousePositionUnknown = false;
-  m_lastKnownMousePosition = event.position();
-  m_lastKnownMouseGlobalPosition = event.globalPosition();
+  m_lastKnownMousePosition = flooredIntPoint(event.positionInRootFrame());
+  m_lastKnownMouseGlobalPosition = IntPoint(event.globalX, event.globalY);
 }
 
 void MouseEventManager::dispatchFakeMouseMoveEventSoon() {
@@ -561,11 +564,12 @@
   m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets();
 
   if (FrameView* frameView = m_frame->view()) {
-    if (frameView->isPointInScrollbarCorner(event.event().position()))
+    if (frameView->isPointInScrollbarCorner(
+            flooredIntPoint(event.event().positionInRootFrame())))
       return WebInputEventResult::NotHandled;
   }
 
-  bool singleClick = event.event().clickCount() <= 1;
+  bool singleClick = event.event().clickCount <= 1;
 
   m_mouseDownMayStartDrag =
       singleClick && !isLinkSelection(event) && !isExtendingSelection(event);
@@ -576,10 +580,12 @@
 
   if (m_frame->document()->isSVGDocument() &&
       m_frame->document()->accessSVGExtensions().zoomAndPanEnabled()) {
-    if (event.event().shiftKey() && singleClick) {
+    if ((event.event().modifiers() & WebInputEvent::Modifiers::ShiftKey) &&
+        singleClick) {
       m_svgPan = true;
       m_frame->document()->accessSVGExtensions().startPan(
-          m_frame->view()->rootFrameToContents(event.event().position()));
+          m_frame->view()->rootFrameToContents(
+              flooredIntPoint(event.event().positionInRootFrame())));
       return WebInputEventResult::HandledSystem;
     }
   }
@@ -593,16 +599,16 @@
 
   m_mousePressNode = innerNode;
   m_frame->document()->setSequentialFocusNavigationStartingPoint(innerNode);
-  m_dragStartPos = event.event().position();
+  m_dragStartPos = flooredIntPoint(event.event().positionInRootFrame());
 
   bool swallowEvent = false;
   m_mousePressed = true;
 
-  if (event.event().clickCount() == 2) {
+  if (event.event().clickCount == 2) {
     swallowEvent = m_frame->eventHandler()
                        .selectionController()
                        .handleMousePressEventDoubleClick(event);
-  } else if (event.event().clickCount() >= 3) {
+  } else if (event.event().clickCount >= 3) {
     swallowEvent = m_frame->eventHandler()
                        .selectionController()
                        .handleMousePressEventTripleClick(event);
@@ -647,30 +653,28 @@
 
     // TODO(mustaq): Suppressing long-tap MouseEvents could break
     // drag-drop. Will do separately because of the risk. crbug.com/606938.
-    PlatformMouseEvent mouseDownEvent(
-        gestureEvent, WebPointerProperties::Button::Left,
-        PlatformEvent::MousePressed, 1,
-        static_cast<PlatformEvent::Modifiers>(modifiers |
-                                              PlatformEvent::LeftButtonDown),
-        PlatformMouseEvent::FromTouch, TimeTicks::Now(),
-        WebPointerProperties::PointerType::Mouse);
+    WebMouseEvent mouseDownEvent(
+        WebInputEvent::MouseDown, gestureEvent,
+        WebPointerProperties::Button::Left, 1,
+        modifiers | WebInputEvent::Modifiers::LeftButtonDown |
+            WebInputEvent::Modifiers::IsCompatibilityEventForTouch,
+        TimeTicks::Now().InSeconds());
     m_mouseDown = mouseDownEvent;
 
-    PlatformMouseEvent mouseDragEvent(
-        gestureEvent, WebPointerProperties::Button::Left,
-        PlatformEvent::MouseMoved, 1,
-        static_cast<PlatformEvent::Modifiers>(modifiers |
-                                              PlatformEvent::LeftButtonDown),
-        PlatformMouseEvent::FromTouch, TimeTicks::Now(),
-        WebPointerProperties::PointerType::Mouse);
+    WebMouseEvent mouseDragEvent(
+        WebInputEvent::MouseMove, gestureEvent,
+        WebPointerProperties::Button::Left, 1,
+        modifiers | WebInputEvent::Modifiers::LeftButtonDown |
+            WebInputEvent::Modifiers::IsCompatibilityEventForTouch,
+        TimeTicks::Now().InSeconds());
     HitTestRequest request(HitTestRequest::ReadOnly);
     MouseEventWithHitTestResults mev =
         EventHandlingUtil::performMouseEventHitTest(m_frame, request,
                                                     mouseDragEvent);
     m_mouseDownMayStartDrag = true;
     dragState().m_dragSrc = nullptr;
-    m_mouseDownPos =
-        m_frame->view()->rootFrameToContents(mouseDragEvent.position());
+    m_mouseDownPos = m_frame->view()->rootFrameToContents(
+        flooredIntPoint(mouseDragEvent.positionInRootFrame()));
     return handleDrag(mev, DragInitiator::Touch);
   }
   return false;
@@ -701,8 +705,7 @@
   //    that ends as a result of a mouse release does not send a mouse release
   //    event. As a result, m_mousePressed also ends up remaining true until
   //    the next mouse release event seen by the EventHandler.
-  if (event.event().pointerProperties().button !=
-      WebPointerProperties::Button::Left)
+  if (event.event().button != WebPointerProperties::Button::Left)
     m_mousePressed = false;
 
   if (!m_mousePressed)
@@ -751,7 +754,7 @@
 
 bool MouseEventManager::handleDrag(const MouseEventWithHitTestResults& event,
                                    DragInitiator initiator) {
-  DCHECK(event.event().type() == PlatformEvent::MouseMoved);
+  DCHECK(event.event().type() == WebInputEvent::MouseMove);
   // Callers must protect the reference to FrameView, since this function may
   // dispatch DOM events, causing page/FrameView to go away.
   DCHECK(m_frame);
@@ -766,7 +769,9 @@
     Node* node = result.innerNode();
     if (node) {
       DragController::SelectionDragPolicy selectionDragPolicy =
-          event.event().timestamp() - m_mouseDownTimestamp < kTextDragDelay
+          TimeTicks::FromSeconds(event.event().timeStampSeconds()) -
+                      m_mouseDownTimestamp <
+                  kTextDragDelay
               ? DragController::DelayedSelectionDragResolution
               : DragController::ImmediateSelectionDragResolution;
       dragState().m_dragSrc = m_frame->page()->dragController().draggableNode(
@@ -794,7 +799,8 @@
   m_frame->view()->setCursor(pointerCursor());
 
   if (initiator == DragInitiator::Mouse &&
-      !dragThresholdExceeded(event.event().position())) {
+      !dragThresholdExceeded(
+          flooredIntPoint(event.event().positionInRootFrame()))) {
     dragState().m_dragSrc = nullptr;
     return true;
   }
@@ -867,7 +873,7 @@
 // eventhandler canceled.
 WebInputEventResult MouseEventManager::dispatchDragSrcEvent(
     const AtomicString& eventType,
-    const PlatformMouseEvent& event) {
+    const WebMouseEvent& event) {
   return dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event,
                            dragState().m_dragDataTransfer.get());
 }
@@ -875,7 +881,7 @@
 WebInputEventResult MouseEventManager::dispatchDragEvent(
     const AtomicString& eventType,
     Node* dragTarget,
-    const PlatformMouseEvent& event,
+    const WebMouseEvent& event,
     DataTransfer* dataTransfer) {
   FrameView* view = m_frame->view();
 
@@ -886,13 +892,16 @@
   const bool cancelable = eventType != EventTypeNames::dragleave &&
                           eventType != EventTypeNames::dragend;
 
+  IntPoint position = flooredIntPoint(event.positionInRootFrame());
+  IntPoint movement = flooredIntPoint(event.movementInRootFrame());
   DragEvent* me = DragEvent::create(
       eventType, true, cancelable, m_frame->document()->domWindow(), 0,
-      event.globalPosition().x(), event.globalPosition().y(),
-      event.position().x(), event.position().y(), event.movementDelta().x(),
-      event.movementDelta().y(), event.getModifiers(), 0,
-      MouseEvent::platformModifiersToButtons(event.getModifiers()), nullptr,
-      event.timestamp(), dataTransfer, event.getSyntheticEventType());
+      event.globalX, event.globalY, position.x(), position.y(), movement.x(),
+      movement.y(), static_cast<PlatformEvent::Modifiers>(event.modifiers()), 0,
+      MouseEvent::platformModifiersToButtons(event.modifiers()), nullptr,
+      TimeTicks::FromSeconds(event.timeStampSeconds()), dataTransfer,
+      event.fromTouch() ? MouseEvent::FromTouch
+                        : MouseEvent::RealOrIndistinguishable);
 
   return EventHandlingUtil::toWebInputEventResult(
       dragTarget->dispatchEvent(me));
@@ -905,7 +914,7 @@
   }
 }
 
-void MouseEventManager::dragSourceEndedAt(const PlatformMouseEvent& event,
+void MouseEventManager::dragSourceEndedAt(const WebMouseEvent& event,
                                           DragOperation operation) {
   if (dragState().m_dragSrc) {
     dragState().m_dragDataTransfer->setDestinationOperation(operation);
diff --git a/third_party/WebKit/Source/core/input/MouseEventManager.h b/third_party/WebKit/Source/core/input/MouseEventManager.h
index aa8640a0..0628dfb 100644
--- a/third_party/WebKit/Source/core/input/MouseEventManager.h
+++ b/third_party/WebKit/Source/core/input/MouseEventManager.h
@@ -10,9 +10,9 @@
 #include "core/input/BoundaryEventDispatcher.h"
 #include "core/page/DragActions.h"
 #include "core/page/EventWithHitTestResults.h"
-#include "platform/PlatformMouseEvent.h"
 #include "platform/Timer.h"
 #include "public/platform/WebInputEventResult.h"
+#include "public/platform/WebMouseEvent.h"
 #include "wtf/Allocator.h"
 #include "wtf/Time.h"
 
@@ -45,23 +45,25 @@
 
   WebInputEventResult dispatchMouseEvent(EventTarget*,
                                          const AtomicString&,
-                                         const PlatformMouseEvent&,
+                                         const WebMouseEvent&,
+                                         const String& canvasRegionId,
                                          EventTarget* relatedTarget,
                                          bool checkForListener = false);
 
   WebInputEventResult setMousePositionAndDispatchMouseEvent(
       Node* targetNode,
+      const String& canvasRegionId,
       const AtomicString& eventType,
-      const PlatformMouseEvent&);
+      const WebMouseEvent&);
 
   WebInputEventResult dispatchMouseClickIfNeeded(
       const MouseEventWithHitTestResults&);
 
   WebInputEventResult dispatchDragSrcEvent(const AtomicString& eventType,
-                                           const PlatformMouseEvent&);
+                                           const WebMouseEvent&);
   WebInputEventResult dispatchDragEvent(const AtomicString& eventType,
                                         Node* target,
-                                        const PlatformMouseEvent&,
+                                        const WebMouseEvent&,
                                         DataTransfer*);
 
   // Resets the internal state of this object.
@@ -69,9 +71,12 @@
 
   void sendBoundaryEvents(EventTarget* exitedTarget,
                           EventTarget* enteredTarget,
-                          const PlatformMouseEvent& mousePlatformEvent);
+                          const String& canvasRegionId,
+                          const WebMouseEvent&);
 
-  void setNodeUnderMouse(Node*, const PlatformMouseEvent&);
+  void setNodeUnderMouse(Node*,
+                         const String& canvasRegionId,
+                         const WebMouseEvent&);
 
   WebInputEventResult handleMouseFocus(
       const HitTestResult&,
@@ -83,7 +88,7 @@
   void dispatchFakeMouseMoveEventSoon();
   void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
 
-  void setLastKnownMousePosition(const PlatformMouseEvent&);
+  void setLastKnownMousePosition(const WebMouseEvent&);
 
   bool handleDragDropIfPossible(const GestureEventWithHitTestResults&);
 
@@ -103,11 +108,11 @@
   // drag heuristics.
   void clearDragHeuristicState();
 
-  void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
+  void dragSourceEndedAt(const WebMouseEvent&, DragOperation);
 
   void updateSelectionForMouseDrag();
 
-  void handleMousePressEventUpdateStates(const PlatformMouseEvent&);
+  void handleMousePressEventUpdateStates(const WebMouseEvent&);
 
   // Returns whether pan is handled and resets the state on release.
   bool handleSvgPanIfNeeded(bool isReleaseEvent);
@@ -144,8 +149,9 @@
 
    public:
     MouseEventBoundaryEventDispatcher(MouseEventManager*,
-                                      const PlatformMouseEvent*,
-                                      EventTarget* exitedTarget);
+                                      const WebMouseEvent*,
+                                      EventTarget* exitedTarget,
+                                      const String& canvasRegionId);
 
    protected:
     void dispatchOut(EventTarget*, EventTarget* relatedTarget) override;
@@ -163,11 +169,13 @@
     void dispatch(EventTarget*,
                   EventTarget* relatedTarget,
                   const AtomicString&,
-                  const PlatformMouseEvent&,
+                  const String& canvasRegionId,
+                  const WebMouseEvent&,
                   bool checkForListener);
     Member<MouseEventManager> m_mouseEventManager;
-    const PlatformMouseEvent* m_platformMouseEvent;
+    const WebMouseEvent* m_webMouseEvent;
     Member<EventTarget> m_exitedTarget;
+    String m_canvasRegionId;
   };
 
   // If the given element is a shadow host and its root has delegatesFocus=false
@@ -218,7 +226,7 @@
 
   IntPoint m_mouseDownPos;  // In our view's coords.
   TimeTicks m_mouseDownTimestamp;
-  PlatformMouseEvent m_mouseDown;
+  WebMouseEvent m_mouseDown;
 
   LayoutPoint m_dragStartPos;
 
diff --git a/third_party/WebKit/Source/core/input/PointerEventManager.cpp b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
index 3d22ce286..ae2d1960 100644
--- a/third_party/WebKit/Source/core/input/PointerEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
@@ -180,12 +180,13 @@
 
 void PointerEventManager::sendMouseAndPointerBoundaryEvents(
     Node* enteredNode,
-    const PlatformMouseEvent& mouseEvent) {
+    const String& canvasRegionId,
+    const WebMouseEvent& mouseEvent) {
   // Mouse event type does not matter as this pointerevent will only be used
   // to create boundary pointer events and its type will be overridden in
   // |sendBoundaryEvents| function.
   PointerEvent* dummyPointerEvent = m_pointerEventFactory.create(
-      EventTypeNames::mousedown, mouseEvent, Vector<PlatformMouseEvent>(),
+      EventTypeNames::mousedown, mouseEvent, Vector<WebMouseEvent>(),
       m_frame->document()->domWindow());
 
   // TODO(crbug/545647): This state should reset with pointercancel too.
@@ -195,11 +196,11 @@
   // behavior regarding preventMouseEvent state in that case.
   if (dummyPointerEvent->buttons() == 0 && dummyPointerEvent->isPrimary()) {
     m_preventMouseEventForPointerType[toPointerTypeIndex(
-        mouseEvent.pointerProperties().pointerType)] = false;
+        mouseEvent.pointerType)] = false;
   }
 
   processCaptureAndPositionOfPointerEvent(dummyPointerEvent, enteredNode,
-                                          mouseEvent, true);
+                                          canvasRegionId, mouseEvent, true);
 }
 
 void PointerEventManager::sendBoundaryEvents(EventTarget* exitedTarget,
@@ -439,9 +440,10 @@
 
 WebInputEventResult PointerEventManager::sendMousePointerEvent(
     Node* target,
+    const String& canvasRegionId,
     const AtomicString& mouseEventType,
-    const PlatformMouseEvent& mouseEvent,
-    const Vector<PlatformMouseEvent>& coalescedEvents) {
+    const WebMouseEvent& mouseEvent,
+    const Vector<WebMouseEvent>& coalescedEvents) {
   PointerEvent* pointerEvent =
       m_pointerEventFactory.create(mouseEventType, mouseEvent, coalescedEvents,
                                    m_frame->document()->domWindow());
@@ -455,12 +457,12 @@
 
     if (pointerEvent->isPrimary()) {
       m_preventMouseEventForPointerType[toPointerTypeIndex(
-          mouseEvent.pointerProperties().pointerType)] = false;
+          mouseEvent.pointerType)] = false;
     }
   }
 
   EventTarget* pointerEventTarget = processCaptureAndPositionOfPointerEvent(
-      pointerEvent, target, mouseEvent, true);
+      pointerEvent, target, canvasRegionId, mouseEvent, true);
 
   EventTarget* effectiveTarget = getEffectiveTargetForPointerEvent(
       pointerEventTarget, pointerEvent->pointerId());
@@ -472,12 +474,12 @@
       pointerEvent->type() == EventTypeNames::pointerdown &&
       pointerEvent->isPrimary()) {
     m_preventMouseEventForPointerType[toPointerTypeIndex(
-        mouseEvent.pointerProperties().pointerType)] = true;
+        mouseEvent.pointerType)] = true;
   }
 
   if (pointerEvent->isPrimary() &&
       !m_preventMouseEventForPointerType[toPointerTypeIndex(
-          mouseEvent.pointerProperties().pointerType)]) {
+          mouseEvent.pointerType)]) {
     EventTarget* mouseTarget = effectiveTarget;
     // Event path could be null if pointer event is not dispatched and
     // that happens for example when pointer event feature is not enabled.
@@ -491,8 +493,9 @@
       }
     }
     result = EventHandlingUtil::mergeEventResult(
-        result, m_mouseEventManager->dispatchMouseEvent(
-                    mouseTarget, mouseEventType, mouseEvent, nullptr));
+        result,
+        m_mouseEventManager->dispatchMouseEvent(
+            mouseTarget, mouseEventType, mouseEvent, canvasRegionId, nullptr));
   }
 
   if (pointerEvent->type() == EventTypeNames::pointerup ||
@@ -503,7 +506,7 @@
 
     if (pointerEvent->isPrimary()) {
       m_preventMouseEventForPointerType[toPointerTypeIndex(
-          mouseEvent.pointerProperties().pointerType)] = false;
+          mouseEvent.pointerType)] = false;
     }
   }
 
@@ -534,7 +537,8 @@
 EventTarget* PointerEventManager::processCaptureAndPositionOfPointerEvent(
     PointerEvent* pointerEvent,
     EventTarget* hitTestTarget,
-    const PlatformMouseEvent& mouseEvent,
+    const String& canvasRegionId,
+    const WebMouseEvent& mouseEvent,
     bool sendMouseEvent) {
   processPendingPointerCapture(pointerEvent);
 
@@ -547,7 +551,8 @@
   setNodeUnderPointer(pointerEvent, hitTestTarget);
   if (sendMouseEvent) {
     m_mouseEventManager->setNodeUnderMouse(
-        hitTestTarget ? hitTestTarget->toNode() : nullptr, mouseEvent);
+        hitTestTarget ? hitTestTarget->toNode() : nullptr, canvasRegionId,
+        mouseEvent);
   }
   return hitTestTarget;
 }
diff --git a/third_party/WebKit/Source/core/input/PointerEventManager.h b/third_party/WebKit/Source/core/input/PointerEventManager.h
index 8504f5c..0ba65f6 100644
--- a/third_party/WebKit/Source/core/input/PointerEventManager.h
+++ b/third_party/WebKit/Source/core/input/PointerEventManager.h
@@ -36,9 +36,10 @@
   // in this function.
   WebInputEventResult sendMousePointerEvent(
       Node* target,
+      const String& canvasRegionId,
       const AtomicString& type,
-      const PlatformMouseEvent&,
-      const Vector<PlatformMouseEvent>& coalescedEvents);
+      const WebMouseEvent&,
+      const Vector<WebMouseEvent>& coalescedEvents);
 
   WebInputEventResult handleTouchEvents(
       const WebTouchEvent&,
@@ -51,7 +52,8 @@
   // and their corresponding boundary events will be handled altogether by
   // sendMousePointerEvent function.
   void sendMouseAndPointerBoundaryEvents(Node* enteredNode,
-                                         const PlatformMouseEvent&);
+                                         const String& canvasRegionId,
+                                         const WebMouseEvent&);
 
   // Resets the internal state of this object.
   void clear();
@@ -168,7 +170,8 @@
   EventTarget* processCaptureAndPositionOfPointerEvent(
       PointerEvent*,
       EventTarget* hitTestTarget,
-      const PlatformMouseEvent& = PlatformMouseEvent(),
+      const String& canvasRegionId = String(),
+      const WebMouseEvent& = WebMouseEvent(),
       bool sendMouseEvent = false);
 
   void removeTargetFromPointerCapturingMapping(PointerCapturingMap&,
diff --git a/third_party/WebKit/Source/core/input/ScrollManager.cpp b/third_party/WebKit/Source/core/input/ScrollManager.cpp
index 0a5c306..12de4c6bf 100644
--- a/third_party/WebKit/Source/core/input/ScrollManager.cpp
+++ b/third_party/WebKit/Source/core/input/ScrollManager.cpp
@@ -506,11 +506,12 @@
   return m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode();
 }
 
-void ScrollManager::resize(const PlatformMouseEvent& evt) {
-  if (evt.type() == PlatformEvent::MouseMoved) {
+void ScrollManager::resize(const WebMouseEvent& evt) {
+  if (evt.type() == WebInputEvent::MouseMove) {
     if (!m_frame->eventHandler().mousePressed())
       return;
-    m_resizeScrollableArea->resize(evt.position(), m_offsetFromResizeCorner);
+    m_resizeScrollableArea->resize(flooredIntPoint(evt.positionInRootFrame()),
+                                   m_offsetFromResizeCorner);
   }
 }
 
diff --git a/third_party/WebKit/Source/core/input/ScrollManager.h b/third_party/WebKit/Source/core/input/ScrollManager.h
index a5f69d7..b87e244 100644
--- a/third_party/WebKit/Source/core/input/ScrollManager.h
+++ b/third_party/WebKit/Source/core/input/ScrollManager.h
@@ -86,7 +86,7 @@
 
   // These functions are related to |m_resizeScrollableArea|.
   bool inResizeMode() const;
-  void resize(const PlatformMouseEvent&);
+  void resize(const WebMouseEvent&);
   // Clears |m_resizeScrollableArea|. if |shouldNotBeNull| is true this
   // function DCHECKs to make sure that variable is indeed not null.
   void clearResizeScrollableArea(bool shouldNotBeNull);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
index bbb87a7..8cfe3a1 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
@@ -75,7 +75,6 @@
 #include "core/page/Page.h"
 #include "core/xml/DocumentXPathEvaluator.h"
 #include "core/xml/XPathResult.h"
-#include "platform/PlatformMouseEvent.h"
 #include "wtf/ListHashSet.h"
 #include "wtf/PtrUtil.h"
 #include "wtf/text/CString.h"
diff --git a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl
index 2d725e6..b463a8b8 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl
+++ b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl
@@ -244,7 +244,7 @@
     void frameDocumentUpdated([Keep] LocalFrame*);
 
     [Page, Tracing]
-    void frameStartedLoading([Keep] LocalFrame*);
+    void frameStartedLoading([Keep] LocalFrame*, FrameLoadType);
 
     [Page, Tracing]
     void frameStoppedLoading([Keep] LocalFrame*);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorLogAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorLogAgent.cpp
index 2522296..cb1c23e 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorLogAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorLogAgent.cpp
@@ -212,7 +212,7 @@
       String::format("Forced reflow while executing JavaScript took %ldms",
                      lround(duration * 1000));
   ConsoleMessage* message = ConsoleMessage::create(
-      ViolationMessageSource, WarningMessageLevel, messageText);
+      ViolationMessageSource, VerboseMessageLevel, messageText);
   consoleMessageAdded(message);
 }
 
@@ -221,7 +221,7 @@
                                                double time,
                                                SourceLocation* location) {
   ConsoleMessage* message = ConsoleMessage::create(
-      ViolationMessageSource, WarningMessageLevel, text, location->clone());
+      ViolationMessageSource, VerboseMessageLevel, text, location->clone());
   consoleMessageAdded(message);
 };
 
diff --git a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
index 924771b..c628973 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
@@ -964,7 +964,7 @@
         (success ? "XHR finished loading: " : "XHR failed loading: ") + method +
         " \"" + url + "\".";
     ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest(
-        NetworkMessageSource, VerboseMessageLevel, message, url, it->value);
+        NetworkMessageSource, InfoMessageLevel, message, url, it->value);
     m_inspectedFrames->root()->console().addMessageToStorage(consoleMessage);
   }
   m_knownRequestIdMap.remove(client);
@@ -992,7 +992,7 @@
   if (m_state->booleanProperty(NetworkAgentState::monitoringXHR, false)) {
     String message = "Fetch complete: " + method + " \"" + url + "\".";
     ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest(
-        NetworkMessageSource, VerboseMessageLevel, message, url, it->value);
+        NetworkMessageSource, InfoMessageLevel, message, url, it->value);
     m_inspectedFrames->root()->console().addMessageToStorage(consoleMessage);
   }
   m_knownRequestIdMap.remove(client);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
index 10fc07b..6919dc6 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
@@ -678,7 +678,7 @@
          m_state->booleanProperty(PageAgentState::screencastEnabled, false);
 }
 
-void InspectorPageAgent::frameStartedLoading(LocalFrame* frame) {
+void InspectorPageAgent::frameStartedLoading(LocalFrame* frame, FrameLoadType) {
   frontend()->frameStartedLoading(frameId(frame));
 }
 
diff --git a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
index 65b8061..665331f 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
@@ -145,7 +145,7 @@
   void didCommitLoad(LocalFrame*, DocumentLoader*);
   void frameAttachedToParent(LocalFrame*);
   void frameDetachedFromParent(LocalFrame*);
-  void frameStartedLoading(LocalFrame*);
+  void frameStartedLoading(LocalFrame*, FrameLoadType);
   void frameStoppedLoading(LocalFrame*);
   void frameScheduledNavigation(LocalFrame*, double delay);
   void frameClearedScheduledNavigation(LocalFrame*);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp
index 28678dc..c71a2e5 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp
@@ -42,9 +42,9 @@
   emitMetadataEvents();
 }
 
-void InspectorTracingAgent::frameStartedLoading(LocalFrame* frame) {
-  if (frame != m_inspectedFrames->root() ||
-      frame->loader().loadType() != FrameLoadTypeReload)
+void InspectorTracingAgent::frameStartedLoading(LocalFrame* frame,
+                                                FrameLoadType type) {
+  if (frame != m_inspectedFrames->root() || type != FrameLoadTypeReload)
     return;
   m_client->showReloadingBlanket();
 }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h
index c7aa893..77a8b11d 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h
@@ -10,6 +10,7 @@
 #include "core/CoreExport.h"
 #include "core/inspector/InspectorBaseAgent.h"
 #include "core/inspector/protocol/Tracing.h"
+#include "core/loader/FrameLoaderTypes.h"
 #include "wtf/text/WTFString.h"
 
 namespace blink {
@@ -45,7 +46,7 @@
   Response disable() override;
 
   // InspectorInstrumentation methods
-  void frameStartedLoading(LocalFrame*);
+  void frameStartedLoading(LocalFrame*, FrameLoadType);
   void frameStoppedLoading(LocalFrame*);
 
   // Protocol method implementations.
diff --git a/third_party/WebKit/Source/core/layout/HitTestResult.cpp b/third_party/WebKit/Source/core/layout/HitTestResult.cpp
index 76f4cd95..b1b70ee9 100644
--- a/third_party/WebKit/Source/core/layout/HitTestResult.cpp
+++ b/third_party/WebKit/Source/core/layout/HitTestResult.cpp
@@ -92,7 +92,8 @@
       m_localPoint(other.localPoint()),
       m_innerURLElement(other.URLElement()),
       m_scrollbar(other.scrollbar()),
-      m_isOverWidget(other.isOverWidget()) {
+      m_isOverWidget(other.isOverWidget()),
+      m_canvasRegionId(other.canvasRegionId()) {
   // Only copy the NodeSet in case of list hit test.
   m_listBasedTestResult = other.m_listBasedTestResult
                               ? new NodeSet(*other.m_listBasedTestResult)
@@ -135,6 +136,7 @@
   m_scrollbar = other.scrollbar();
   m_isOverWidget = other.isOverWidget();
   m_cacheable = other.m_cacheable;
+  m_canvasRegionId = other.canvasRegionId();
 
   // Only copy the NodeSet in case of list hit test.
   m_listBasedTestResult = other.m_listBasedTestResult
@@ -438,6 +440,7 @@
     m_pointInInnerNodeFrame = other.m_pointInInnerNodeFrame;
     m_innerURLElement = other.URLElement();
     m_isOverWidget = other.isOverWidget();
+    m_canvasRegionId = other.canvasRegionId();
   }
 
   if (other.m_listBasedTestResult) {
diff --git a/third_party/WebKit/Source/core/layout/HitTestResult.h b/third_party/WebKit/Source/core/layout/HitTestResult.h
index 18225cff..ff5c464 100644
--- a/third_party/WebKit/Source/core/layout/HitTestResult.h
+++ b/third_party/WebKit/Source/core/layout/HitTestResult.h
@@ -154,6 +154,9 @@
   bool isLiveLink() const;
   bool isContentEditable() const;
 
+  const String& canvasRegionId() const { return m_canvasRegionId; }
+  void setCanvasRegionId(const String& id) { m_canvasRegionId = id; }
+
   bool isOverLink() const;
 
   bool isCacheable() const { return m_cacheable; }
@@ -208,6 +211,7 @@
                         // border/padding area of a LayoutPart for example).
 
   mutable Member<NodeSet> m_listBasedTestResult;
+  String m_canvasRegionId;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutScrollbarTheme.h b/third_party/WebKit/Source/core/layout/LayoutScrollbarTheme.h
index c9b96ebe..de89c064 100644
--- a/third_party/WebKit/Source/core/layout/LayoutScrollbarTheme.h
+++ b/third_party/WebKit/Source/core/layout/LayoutScrollbarTheme.h
@@ -30,7 +30,7 @@
 
 namespace blink {
 
-class PlatformMouseEvent;
+class WebMouseEvent;
 
 class LayoutScrollbarTheme final : public ScrollbarTheme {
  public:
@@ -49,11 +49,11 @@
                          const IntRect& cornerRect) override;
 
   bool shouldCenterOnThumb(const ScrollbarThemeClient& scrollbar,
-                           const PlatformMouseEvent& event) override {
+                           const WebMouseEvent& event) override {
     return ScrollbarTheme::theme().shouldCenterOnThumb(scrollbar, event);
   }
   bool shouldSnapBackToDragOrigin(const ScrollbarThemeClient& scrollbar,
-                                  const PlatformMouseEvent& event) override {
+                                  const WebMouseEvent& event) override {
     return ScrollbarTheme::theme().shouldSnapBackToDragOrigin(scrollbar, event);
   }
 
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index 8a87af32..7a0159a 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -481,6 +481,30 @@
       m_owningLayer.getSquashingDisallowedReasons());
 }
 
+bool CompositedLayerMapping::ancestorRoundedCornersWontClip(
+    const LayoutObject* child,
+    const LayoutObject* clippingAncestor) {
+  if (!clippingAncestor->isBoxModelObject())
+    return false;
+  const LayoutBoxModelObject* clippingObject =
+      toLayoutBoxModelObject(clippingAncestor);
+  LayoutRect localVisualRect = m_compositedBounds;
+  child->mapToVisualRectInAncestorSpace(clippingObject, localVisualRect);
+  FloatRoundedRect roundedClipRect =
+      clippingObject->style()->getRoundedInnerBorderFor(
+          clippingObject->localVisualRect());
+  FloatRect innerClipRect = roundedClipRect.radiusCenterRect();
+  // The first condition catches cases where the child is certainly inside
+  // the rounded corner portion of the border, and cannot be clipped by
+  // the rounded portion. The second catches cases where the child is
+  // entirely outside the rectangular border (ignoring rounded corners) so
+  // is also unaffected by the rounded corners. In both cases the existing
+  // rectangular clip is adequate and the mask is unnecessary.
+  return innerClipRect.contains(FloatRect(localVisualRect)) ||
+         !localVisualRect.intersects(
+             enclosingLayoutRect(roundedClipRect.rect()));
+}
+
 void CompositedLayerMapping::
     owningLayerClippedOrMaskedByLayerNotAboveCompositedAncestor(
         const PaintLayer* scrollParent,
@@ -521,8 +545,9 @@
   ClipRectsContext clipRectsContext(compositingAncestor, UncachedClipRects,
                                     IgnoreOverlayScrollbarSize);
   clipRectsContext.setIgnoreOverflowClip();
-  IntRect parentClipRect = pixelSnappedIntRect(
-      m_owningLayer.clipper().backgroundClipRect(clipRectsContext).rect());
+  LayoutRect unsnappedParentClipRect =
+      m_owningLayer.clipper().backgroundClipRect(clipRectsContext).rect();
+  IntRect parentClipRect = pixelSnappedIntRect(unsnappedParentClipRect);
   owningLayerIsClipped = parentClipRect != LayoutRect::infiniteIntRect();
 
   // TODO(schenney): CSS clips are not applied to composited children, and
@@ -530,7 +555,8 @@
   // https://bugs.chromium.org/p/chromium/issues/detail?id=615870
   DCHECK(clippingContainer->style());
   owningLayerIsMasked =
-      owningLayerIsClipped && clippingContainer->style()->hasBorderRadius();
+      owningLayerIsClipped && clippingContainer->style()->hasBorderRadius() &&
+      !ancestorRoundedCornersWontClip(layoutObject(), clippingContainer);
 }
 
 const PaintLayer* CompositedLayerMapping::scrollParent() {
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
index 312c9fa9..6b696ba7 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
@@ -480,6 +480,15 @@
       const GraphicsLayerPaintInfo&,
       const Vector<GraphicsLayerPaintInfo>& layers);
 
+  // Conservatively check that a border-radius clip does not clip a child.
+  // This is a fast approximate test. Depending on the shape of the child and
+  // the size of the border radius, this method may return false when in fact
+  // the child is not clipped. We accept the approximation because most border
+  // radii are small and the outcome is used to reduce the number of layers,
+  // not influence correctness.
+  bool ancestorRoundedCornersWontClip(const LayoutObject* child,
+                                      const LayoutObject* clippingAncestor);
+
   // Return true in |owningLayerIsClipped| iff |m_owningLayer|'s compositing
   // ancestor is not a descendant (inclusive) of the clipping container for
   // |m_owningLayer|. Return true in |owningLayerIsMasked| iff
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp
index 72ad343..7e308c20 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp
@@ -1169,10 +1169,12 @@
 TEST_P(CompositedLayerMappingTest, AncestorClippingMaskLayerUpdates) {
   setBodyInnerHTML(
       "<style>"
-      "#ancestor { width: 100px; height: 100px; overflow: hidden; }"
-      "#child { width: 120px; height: 120px; background-color: green; }"
+      "  #ancestor { width: 100px; height: 100px; overflow: hidden; }"
+      "  #child { width: 120px; height: 120px; background-color: green; }"
       "</style>"
-      "<div id='ancestor'><div id='child'></div></div>");
+      "<div id='ancestor'>"
+      "  <div id='child'></div>"
+      "</div>");
   document().view()->updateAllLifecyclePhases();
 
   Element* ancestor = document().getElementById("ancestor");
@@ -1194,7 +1196,6 @@
   // Making the child conposited causes creation of an AncestorClippingLayer.
   child->setAttribute(HTMLNames::styleAttr, "will-change: transform");
   document().view()->updateAllLifecyclePhases();
-
   childPaintLayer = toLayoutBoxModelObject(child->layoutObject())->layer();
   ASSERT_TRUE(childPaintLayer);
   CompositedLayerMapping* childMapping =
@@ -1208,7 +1209,6 @@
   // ancestorClippingMaskLayer for the child
   ancestor->setAttribute(HTMLNames::styleAttr, "border-radius: 40px;");
   document().view()->updateAllLifecyclePhases();
-
   childPaintLayer = toLayoutBoxModelObject(child->layoutObject())->layer();
   ASSERT_TRUE(childPaintLayer);
   childMapping = childPaintLayer->compositedLayerMapping();
@@ -1221,7 +1221,6 @@
   // for the child
   ancestor->setAttribute(HTMLNames::styleAttr, "border-radius: 0px;");
   document().view()->updateAllLifecyclePhases();
-
   childPaintLayer = toLayoutBoxModelObject(child->layoutObject())->layer();
   ASSERT_TRUE(childPaintLayer);
   childMapping = childPaintLayer->compositedLayerMapping();
@@ -1238,7 +1237,6 @@
   // on the child
   ancestor->setAttribute(HTMLNames::styleAttr, "overflow: visible");
   document().view()->updateAllLifecyclePhases();
-
   childPaintLayer = toLayoutBoxModelObject(child->layoutObject())->layer();
   ASSERT_TRUE(childPaintLayer);
   childMapping = childPaintLayer->compositedLayerMapping();
@@ -1247,6 +1245,368 @@
   EXPECT_FALSE(childMapping->ancestorClippingMaskLayer());
 }
 
+TEST_P(CompositedLayerMappingTest, AncestorClippingMaskLayerSiblingUpdates) {
+  setBodyInnerHTML(
+      "<style>"
+      "  #ancestor { width: 200px; height: 200px; overflow: hidden; }"
+      "  #child1 { width: 10px;; height: 260px; position: relative; "
+      "            left: 0px; top: -30px; background-color: green; }"
+      "  #child2 { width: 10px;; height: 260px; position: relative; "
+      "            left: 190px; top: -260px; background-color: green; }"
+      "</style>"
+      "<div id='ancestor'>"
+      "  <div id='child1'></div>"
+      "  <div id='child2'></div>"
+      "</div>");
+  document().view()->updateAllLifecyclePhases();
+
+  Element* ancestor = document().getElementById("ancestor");
+  ASSERT_TRUE(ancestor);
+  PaintLayer* ancestorPaintLayer =
+      toLayoutBoxModelObject(ancestor->layoutObject())->layer();
+  ASSERT_TRUE(ancestorPaintLayer);
+
+  CompositedLayerMapping* ancestorMapping =
+      ancestorPaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(ancestorMapping);
+
+  Element* child1 = document().getElementById("child1");
+  ASSERT_TRUE(child1);
+  PaintLayer* child1PaintLayer =
+      toLayoutBoxModelObject(child1->layoutObject())->layer();
+  ASSERT_TRUE(child1PaintLayer);
+  CompositedLayerMapping* child1Mapping =
+      child1PaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(child1Mapping);
+
+  Element* child2 = document().getElementById("child2");
+  ASSERT_TRUE(child2);
+  PaintLayer* child2PaintLayer =
+      toLayoutBoxModelObject(child2->layoutObject())->layer();
+  ASSERT_TRUE(child2PaintLayer);
+  CompositedLayerMapping* child2Mapping =
+      child2PaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(child2Mapping);
+
+  // Making child1 composited causes creation of an AncestorClippingLayer.
+  child1->setAttribute(HTMLNames::styleAttr, "will-change: transform");
+  document().view()->updateAllLifecyclePhases();
+  child1PaintLayer = toLayoutBoxModelObject(child1->layoutObject())->layer();
+  ASSERT_TRUE(child1PaintLayer);
+  child1Mapping = child1PaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(child1Mapping);
+  EXPECT_TRUE(child1Mapping->ancestorClippingLayer());
+  EXPECT_FALSE(child1Mapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_FALSE(child1Mapping->ancestorClippingMaskLayer());
+  child2PaintLayer = toLayoutBoxModelObject(child2->layoutObject())->layer();
+  ASSERT_TRUE(child2PaintLayer);
+  child2Mapping = child2PaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(child2Mapping);
+
+  // Adding border radius to the ancestor requires an
+  // ancestorClippingMaskLayer for child1
+  ancestor->setAttribute(HTMLNames::styleAttr, "border-radius: 40px;");
+  document().view()->updateAllLifecyclePhases();
+  child1PaintLayer = toLayoutBoxModelObject(child1->layoutObject())->layer();
+  ASSERT_TRUE(child1PaintLayer);
+  child1Mapping = child1PaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(child1Mapping);
+  EXPECT_TRUE(child1Mapping->ancestorClippingLayer());
+  EXPECT_TRUE(child1Mapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_TRUE(child1Mapping->ancestorClippingMaskLayer());
+  child2PaintLayer = toLayoutBoxModelObject(child2->layoutObject())->layer();
+  ASSERT_TRUE(child2PaintLayer);
+  child2Mapping = child2PaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(child2Mapping);
+
+  // Making child2 composited causes creation of an AncestorClippingLayer
+  // and a mask layer.
+  child2->setAttribute(HTMLNames::styleAttr, "will-change: transform");
+  document().view()->updateAllLifecyclePhases();
+  child1PaintLayer = toLayoutBoxModelObject(child1->layoutObject())->layer();
+  ASSERT_TRUE(child1PaintLayer);
+  child1Mapping = child1PaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(child1Mapping);
+  ASSERT_TRUE(child1Mapping->ancestorClippingLayer());
+  EXPECT_TRUE(child1Mapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_TRUE(child1Mapping->ancestorClippingMaskLayer());
+  child2PaintLayer = toLayoutBoxModelObject(child2->layoutObject())->layer();
+  ASSERT_TRUE(child2PaintLayer);
+  child2Mapping = child2PaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(child2Mapping);
+  ASSERT_TRUE(child2Mapping->ancestorClippingLayer());
+  EXPECT_TRUE(child2Mapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_TRUE(child2Mapping->ancestorClippingMaskLayer());
+
+  // Removing will-change: transform on child1 should result in the removal
+  // of all clipping and masking layers
+  child1->setAttribute(HTMLNames::styleAttr, "will-change: none");
+  document().view()->updateAllLifecyclePhases();
+  child1PaintLayer = toLayoutBoxModelObject(child1->layoutObject())->layer();
+  ASSERT_TRUE(child1PaintLayer);
+  child1Mapping = child1PaintLayer->compositedLayerMapping();
+  EXPECT_FALSE(child1Mapping);
+  child2PaintLayer = toLayoutBoxModelObject(child2->layoutObject())->layer();
+  ASSERT_TRUE(child2PaintLayer);
+  child2Mapping = child2PaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(child2Mapping);
+  ASSERT_TRUE(child2Mapping->ancestorClippingLayer());
+  EXPECT_TRUE(child2Mapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_TRUE(child2Mapping->ancestorClippingMaskLayer());
+
+  // Now change the overflow to remove the need for an ancestor clip
+  // on the children
+  ancestor->setAttribute(HTMLNames::styleAttr, "overflow: visible");
+  document().view()->updateAllLifecyclePhases();
+  child1PaintLayer = toLayoutBoxModelObject(child1->layoutObject())->layer();
+  ASSERT_TRUE(child1PaintLayer);
+  child1Mapping = child1PaintLayer->compositedLayerMapping();
+  EXPECT_FALSE(child1Mapping);
+  child2PaintLayer = toLayoutBoxModelObject(child2->layoutObject())->layer();
+  ASSERT_TRUE(child2PaintLayer);
+  child2Mapping = child2PaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(child2Mapping);
+  EXPECT_FALSE(child2Mapping->ancestorClippingLayer());
+  EXPECT_FALSE(child2Mapping->ancestorClippingMaskLayer());
+}
+
+TEST_P(CompositedLayerMappingTest, AncestorClippingMaskLayerGrandchildUpdates) {
+  setBodyInnerHTML(
+      "<style>"
+      "  #ancestor { width: 200px; height: 200px; overflow: hidden; }"
+      "  #child { width: 10px;; height: 260px; position: relative; "
+      "           left: 0px; top: -30px; background-color: green; }"
+      "  #grandchild { width: 10px;; height: 260px; position: relative; "
+      "                left: 190px; top: -30px; background-color: green; }"
+      "</style>"
+      "<div id='ancestor'>"
+      "  <div id='child'>"
+      "    <div id='grandchild'></div>"
+      "  </div>"
+      "</div>");
+  document().view()->updateAllLifecyclePhases();
+
+  Element* ancestor = document().getElementById("ancestor");
+  ASSERT_TRUE(ancestor);
+  PaintLayer* ancestorPaintLayer =
+      toLayoutBoxModelObject(ancestor->layoutObject())->layer();
+  ASSERT_TRUE(ancestorPaintLayer);
+
+  CompositedLayerMapping* ancestorMapping =
+      ancestorPaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(ancestorMapping);
+
+  Element* child = document().getElementById("child");
+  ASSERT_TRUE(child);
+  PaintLayer* childPaintLayer =
+      toLayoutBoxModelObject(child->layoutObject())->layer();
+  ASSERT_TRUE(childPaintLayer);
+  CompositedLayerMapping* childMapping =
+      childPaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(childMapping);
+
+  Element* grandchild = document().getElementById("grandchild");
+  ASSERT_TRUE(grandchild);
+  PaintLayer* grandchildPaintLayer =
+      toLayoutBoxModelObject(grandchild->layoutObject())->layer();
+  ASSERT_TRUE(grandchildPaintLayer);
+  CompositedLayerMapping* grandchildMapping =
+      grandchildPaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(grandchildMapping);
+
+  // Making grandchild composited causes creation of an AncestorClippingLayer.
+  grandchild->setAttribute(HTMLNames::styleAttr, "will-change: transform");
+  document().view()->updateAllLifecyclePhases();
+  childPaintLayer = toLayoutBoxModelObject(child->layoutObject())->layer();
+  ASSERT_TRUE(childPaintLayer);
+  childMapping = childPaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(childMapping);
+  grandchildPaintLayer =
+      toLayoutBoxModelObject(grandchild->layoutObject())->layer();
+  ASSERT_TRUE(grandchildPaintLayer);
+  grandchildMapping = grandchildPaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(grandchildMapping);
+  EXPECT_TRUE(grandchildMapping->ancestorClippingLayer());
+  EXPECT_FALSE(grandchildMapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_FALSE(grandchildMapping->ancestorClippingMaskLayer());
+
+  // Adding border radius to the ancestor requires an
+  // ancestorClippingMaskLayer for grandchild
+  ancestor->setAttribute(HTMLNames::styleAttr, "border-radius: 40px;");
+  document().view()->updateAllLifecyclePhases();
+  childPaintLayer = toLayoutBoxModelObject(child->layoutObject())->layer();
+  ASSERT_TRUE(childPaintLayer);
+  childMapping = childPaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(childMapping);
+  grandchildPaintLayer =
+      toLayoutBoxModelObject(grandchild->layoutObject())->layer();
+  ASSERT_TRUE(grandchildPaintLayer);
+  grandchildMapping = grandchildPaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(grandchildMapping);
+  ASSERT_TRUE(grandchildMapping->ancestorClippingLayer());
+  EXPECT_TRUE(grandchildMapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_TRUE(grandchildMapping->ancestorClippingMaskLayer());
+
+  // Moving the grandchild out of the clip region should result in removal
+  // of the mask layer. It also removes the grandchild from its own mapping
+  // because it is now squashed.
+  grandchild->setAttribute(HTMLNames::styleAttr,
+                           "left: 250px; will-change: transform");
+  document().view()->updateAllLifecyclePhases();
+  childPaintLayer = toLayoutBoxModelObject(child->layoutObject())->layer();
+  ASSERT_TRUE(childPaintLayer);
+  childMapping = childPaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(childMapping);
+  grandchildPaintLayer =
+      toLayoutBoxModelObject(grandchild->layoutObject())->layer();
+  ASSERT_TRUE(grandchildPaintLayer);
+  grandchildMapping = grandchildPaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(grandchildMapping);
+  ASSERT_TRUE(grandchildMapping->ancestorClippingLayer());
+  EXPECT_FALSE(grandchildMapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_FALSE(grandchildMapping->ancestorClippingMaskLayer());
+
+  // Now change the overflow to remove the need for an ancestor clip
+  // on the children
+  ancestor->setAttribute(HTMLNames::styleAttr, "overflow: visible");
+  document().view()->updateAllLifecyclePhases();
+  childPaintLayer = toLayoutBoxModelObject(child->layoutObject())->layer();
+  ASSERT_TRUE(childPaintLayer);
+  childMapping = childPaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(childMapping);
+  grandchildPaintLayer =
+      toLayoutBoxModelObject(grandchild->layoutObject())->layer();
+  ASSERT_TRUE(grandchildPaintLayer);
+  grandchildMapping = grandchildPaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(grandchildMapping);
+  EXPECT_FALSE(grandchildMapping->ancestorClippingLayer());
+}
+
+TEST_P(CompositedLayerMappingTest, AncestorClipMaskRequiredByBorderRadius) {
+  // Verify that we create the mask layer when the child is contained within
+  // the rectangular clip but not contained within the rounded rect clip.
+  setBodyInnerHTML(
+      "<style>"
+      "  #ancestor {"
+      "    width: 100px; height: 100px; overflow: hidden; border-radius: 20px;"
+      "  }"
+      "  #child { position: relative; left: 2px; top: 2px; width: 96px;"
+      "           height: 96px; background-color: green;"
+      "           will-change: transform;"
+      "  }"
+      "</style>"
+      "<div id='ancestor'>"
+      "  <div id='child'></div>"
+      "</div>");
+  document().view()->updateAllLifecyclePhases();
+
+  Element* ancestor = document().getElementById("ancestor");
+  ASSERT_TRUE(ancestor);
+  PaintLayer* ancestorPaintLayer =
+      toLayoutBoxModelObject(ancestor->layoutObject())->layer();
+  ASSERT_TRUE(ancestorPaintLayer);
+
+  CompositedLayerMapping* ancestorMapping =
+      ancestorPaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(ancestorMapping);
+
+  Element* child = document().getElementById("child");
+  ASSERT_TRUE(child);
+  PaintLayer* childPaintLayer =
+      toLayoutBoxModelObject(child->layoutObject())->layer();
+  ASSERT_TRUE(childPaintLayer);
+  CompositedLayerMapping* childMapping =
+      childPaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(childMapping);
+  EXPECT_TRUE(childMapping->ancestorClippingLayer());
+  EXPECT_TRUE(childMapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_TRUE(childMapping->ancestorClippingMaskLayer());
+}
+
+TEST_P(CompositedLayerMappingTest,
+       AncestorClipMaskNotRequiredByBorderRadiusInside) {
+  // Verify that we do not create the mask layer when the child is contained
+  // within the rounded rect clip.
+  setBodyInnerHTML(
+      "<style>"
+      "  #ancestor {"
+      "    width: 100px; height: 100px; overflow: hidden; border-radius: 5px;"
+      "  }"
+      "  #child { position: relative; left: 10px; top: 10px; width: 80px;"
+      "           height: 80px; background-color: green;"
+      "           will-change: transform;"
+      "  }"
+      "</style>"
+      "<div id='ancestor'>"
+      "  <div id='child'></div>"
+      "</div>");
+  document().view()->updateAllLifecyclePhases();
+
+  Element* ancestor = document().getElementById("ancestor");
+  ASSERT_TRUE(ancestor);
+  PaintLayer* ancestorPaintLayer =
+      toLayoutBoxModelObject(ancestor->layoutObject())->layer();
+  ASSERT_TRUE(ancestorPaintLayer);
+
+  CompositedLayerMapping* ancestorMapping =
+      ancestorPaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(ancestorMapping);
+
+  Element* child = document().getElementById("child");
+  ASSERT_TRUE(child);
+  PaintLayer* childPaintLayer =
+      toLayoutBoxModelObject(child->layoutObject())->layer();
+  ASSERT_TRUE(childPaintLayer);
+  CompositedLayerMapping* childMapping =
+      childPaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(childMapping);
+  EXPECT_TRUE(childMapping->ancestorClippingLayer());
+  EXPECT_FALSE(childMapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_FALSE(childMapping->ancestorClippingMaskLayer());
+}
+
+TEST_P(CompositedLayerMappingTest,
+       AncestorClipMaskNotRequiredByBorderRadiusOutside) {
+  // Verify that we do not create the mask layer when the child is outside
+  // the ancestors rectangular clip.
+  setBodyInnerHTML(
+      "<style>"
+      "  #ancestor {"
+      "    width: 100px; height: 100px; overflow: hidden; border-radius: 5px;"
+      "  }"
+      "  #child { position: relative; left: 110px; top: 10px; width: 80px;"
+      "           height: 80px; background-color: green;"
+      "           will-change: transform;"
+      "}"
+      "</style>"
+      "<div id='ancestor'>"
+      "  <div id='child'></div>"
+      "</div>");
+  document().view()->updateAllLifecyclePhases();
+
+  Element* ancestor = document().getElementById("ancestor");
+  ASSERT_TRUE(ancestor);
+  PaintLayer* ancestorPaintLayer =
+      toLayoutBoxModelObject(ancestor->layoutObject())->layer();
+  ASSERT_TRUE(ancestorPaintLayer);
+
+  CompositedLayerMapping* ancestorMapping =
+      ancestorPaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(ancestorMapping);
+
+  Element* child = document().getElementById("child");
+  ASSERT_TRUE(child);
+  PaintLayer* childPaintLayer =
+      toLayoutBoxModelObject(child->layoutObject())->layer();
+  ASSERT_TRUE(childPaintLayer);
+  CompositedLayerMapping* childMapping =
+      childPaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(childMapping);
+  EXPECT_TRUE(childMapping->ancestorClippingLayer());
+  EXPECT_FALSE(childMapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_FALSE(childMapping->ancestorClippingMaskLayer());
+}
+
 TEST_P(CompositedLayerMappingTest, StickyPositionContentOffset) {
   setBodyInnerHTML(
       "<div style='width: 400px; height: 400px; overflow: auto; "
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
index c04830b5..fd018690 100644
--- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -105,6 +105,7 @@
       m_originalRequest(req),
       m_substituteData(substituteData),
       m_request(req),
+      m_loadType(FrameLoadTypeStandard),
       m_isClientRedirect(clientRedirectPolicy ==
                          ClientRedirectPolicy::ClientRedirect),
       m_replacesCurrentHistoryItem(false),
@@ -375,8 +376,8 @@
   }
   if (!frameLoader().shouldContinueForNavigationPolicy(
           m_request, SubstituteData(), this, CheckContentSecurityPolicy,
-          m_navigationType, NavigationPolicyCurrentTab,
-          replacesCurrentHistoryItem(), isClientRedirect(), nullptr)) {
+          m_navigationType, NavigationPolicyCurrentTab, m_loadType,
+          isClientRedirect(), nullptr)) {
     m_fetcher->stopFetching();
     return false;
   }
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.h b/third_party/WebKit/Source/core/loader/DocumentLoader.h
index 17c65bd..8023984b 100644
--- a/third_party/WebKit/Source/core/loader/DocumentLoader.h
+++ b/third_party/WebKit/Source/core/loader/DocumentLoader.h
@@ -136,6 +136,9 @@
   void setSentDidFinishLoad() { m_state = SentDidFinishLoad; }
   bool sentDidFinishLoad() const { return m_state == SentDidFinishLoad; }
 
+  FrameLoadType loadType() const { return m_loadType; }
+  void setLoadType(FrameLoadType loadType) { m_loadType = loadType; }
+
   NavigationType getNavigationType() const { return m_navigationType; }
   void setNavigationType(NavigationType navigationType) {
     m_navigationType = navigationType;
@@ -260,6 +263,8 @@
 
   ResourceResponse m_response;
 
+  FrameLoadType m_loadType;
+
   bool m_isClientRedirect;
   bool m_replacesCurrentHistoryItem;
   bool m_dataReceived;
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index 6afd6a6..d72501a4 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -167,7 +167,7 @@
   // Do not block scripts if it is a page reload. This is to enable pages to
   // recover if blocking of a script is leading to a page break and the user
   // reloads the page.
-  const FrameLoadType loadType = document.frame()->loader().loadType();
+  const FrameLoadType loadType = document.loader()->loadType();
   if (isReloadLoadType(loadType)) {
     // Recording this metric since an increase in number of reloads for pages
     // where a script was blocked could be indicative of a page break.
@@ -260,7 +260,7 @@
   if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily())
     return;
 
-  if (frame()->loader().loadType() == FrameLoadTypeReload)
+  if (masterDocumentLoader()->loadType() == FrameLoadTypeReload)
     request.clearHTTPHeaderField("Save-Data");
 
   if (frame()->settings() && frame()->settings()->getDataSaverEnabled())
@@ -271,7 +271,7 @@
   if (m_document && m_document->loadEventFinished())
     return CachePolicyVerify;
 
-  FrameLoadType loadType = frame()->loader().loadType();
+  FrameLoadType loadType = masterDocumentLoader()->loadType();
   if (loadType == FrameLoadTypeReloadBypassingCache)
     return CachePolicyReload;
 
@@ -313,13 +313,23 @@
   return WebCachePolicy::UseProtocolCachePolicy;
 }
 
+static WebCachePolicy frameLoadTypeToWebCachePolicy(FrameLoadType type) {
+  if (type == FrameLoadTypeBackForward)
+    return WebCachePolicy::ReturnCacheDataElseLoad;
+  if (type == FrameLoadTypeReloadBypassingCache)
+    return WebCachePolicy::BypassingCache;
+  if (type == FrameLoadTypeReload)
+    return WebCachePolicy::ValidatingCacheData;
+  return WebCachePolicy::UseProtocolCachePolicy;
+}
+
 WebCachePolicy FrameFetchContext::resourceRequestCachePolicy(
     ResourceRequest& request,
     Resource::Type type,
     FetchRequest::DeferOption defer) const {
   DCHECK(frame());
   if (type == Resource::MainResource) {
-    FrameLoadType frameLoadType = frame()->loader().loadType();
+    FrameLoadType frameLoadType = masterDocumentLoader()->loadType();
     if (request.httpMethod() == "POST" &&
         frameLoadType == FrameLoadTypeBackForward)
       return WebCachePolicy::ReturnCacheDataDontLoad;
@@ -327,16 +337,17 @@
         request.isConditional() || request.httpMethod() == "POST")
       return WebCachePolicy::ValidatingCacheData;
 
-    for (Frame* f = frame(); f; f = f->tree().parent()) {
+    WebCachePolicy policy = frameLoadTypeToWebCachePolicy(frameLoadType);
+    if (policy != WebCachePolicy::UseProtocolCachePolicy)
+      return policy;
+
+    for (Frame* f = frame()->tree().parent(); f; f = f->tree().parent()) {
       if (!f->isLocalFrame())
         continue;
-      FrameLoadType parentFrameLoadType = toLocalFrame(f)->loader().loadType();
-      if (parentFrameLoadType == FrameLoadTypeBackForward)
-        return WebCachePolicy::ReturnCacheDataElseLoad;
-      if (parentFrameLoadType == FrameLoadTypeReloadBypassingCache)
-        return WebCachePolicy::BypassingCache;
-      if (parentFrameLoadType == FrameLoadTypeReload)
-        return WebCachePolicy::ValidatingCacheData;
+      policy = frameLoadTypeToWebCachePolicy(
+          toLocalFrame(f)->loader().documentLoader()->loadType());
+      if (policy != WebCachePolicy::UseProtocolCachePolicy)
+        return policy;
     }
     // Returns UseProtocolCachePolicy for other cases, parent frames not having
     // special kinds of FrameLoadType as they are checked inside the for loop
@@ -868,7 +879,7 @@
   frame()->deprecatedLocalOwner()->didLoadNonEmptyDocument();
   // Do not report iframe navigation that restored from history, since its
   // location may have been changed after initial navigation.
-  if (frame()->loader().loadType() == FrameLoadTypeInitialHistoryLoad)
+  if (masterDocumentLoader()->loadType() == FrameLoadTypeInitialHistoryLoad)
     return false;
   info->setInitiatorType(frame()->deprecatedLocalOwner()->localName());
   return true;
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp
index 5fb9dca5..61736253 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp
@@ -497,19 +497,19 @@
                 postRequest, Resource::MainResource, FetchRequest::NoDefer));
 
   // Re-post
-  document->frame()->loader().setLoadType(FrameLoadTypeBackForward);
+  document->loader()->setLoadType(FrameLoadTypeBackForward);
   EXPECT_EQ(WebCachePolicy::ReturnCacheDataDontLoad,
             fetchContext->resourceRequestCachePolicy(
                 postRequest, Resource::MainResource, FetchRequest::NoDefer));
 
   // FrameLoadTypeReloadMainResource
-  document->frame()->loader().setLoadType(FrameLoadTypeReloadMainResource);
+  document->loader()->setLoadType(FrameLoadTypeReloadMainResource);
   EXPECT_EQ(WebCachePolicy::ValidatingCacheData,
             fetchContext->resourceRequestCachePolicy(
                 request, Resource::MainResource, FetchRequest::NoDefer));
 
   // Conditional request
-  document->frame()->loader().setLoadType(FrameLoadTypeStandard);
+  document->loader()->setLoadType(FrameLoadTypeStandard);
   ResourceRequest conditional("http://www.example.com");
   conditional.setHTTPHeaderField(HTTPNames::If_Modified_Since, "foo");
   EXPECT_EQ(WebCachePolicy::ValidatingCacheData,
@@ -520,19 +520,19 @@
   FrameFetchContext* childFetchContext = createChildFrame();
 
   // Child frame as part of back/forward
-  document->frame()->loader().setLoadType(FrameLoadTypeBackForward);
+  document->loader()->setLoadType(FrameLoadTypeBackForward);
   EXPECT_EQ(WebCachePolicy::ReturnCacheDataElseLoad,
             childFetchContext->resourceRequestCachePolicy(
                 request, Resource::MainResource, FetchRequest::NoDefer));
 
   // Child frame as part of reload
-  document->frame()->loader().setLoadType(FrameLoadTypeReload);
+  document->loader()->setLoadType(FrameLoadTypeReload);
   EXPECT_EQ(WebCachePolicy::ValidatingCacheData,
             childFetchContext->resourceRequestCachePolicy(
                 request, Resource::MainResource, FetchRequest::NoDefer));
 
   // Child frame as part of reload bypassing cache
-  document->frame()->loader().setLoadType(FrameLoadTypeReloadBypassingCache);
+  document->loader()->setLoadType(FrameLoadTypeReloadBypassingCache);
   EXPECT_EQ(WebCachePolicy::BypassingCache,
             childFetchContext->resourceRequestCachePolicy(
                 request, Resource::MainResource, FetchRequest::NoDefer));
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
index 7f196f9..366381b 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -183,7 +183,6 @@
 FrameLoader::FrameLoader(LocalFrame* frame)
     : m_frame(frame),
       m_progressTracker(ProgressTracker::create(frame)),
-      m_loadType(FrameLoadTypeStandard),
       m_inStopAllLoaders(false),
       m_checkTimer(TaskRunnerHelper::get(TaskType::Networking, frame),
                    this,
@@ -271,7 +270,8 @@
     return;
 
   // Shouldn't clobber anything if we might still restore later.
-  if (needsHistoryItemRestore(m_loadType) && m_documentLoader &&
+  if (m_documentLoader &&
+      needsHistoryItemRestore(m_documentLoader->loadType()) &&
       !m_documentLoader->initialScrollState().wasScrolledByUser)
     return;
 
@@ -310,7 +310,7 @@
     if ((parent->isLocalFrame() &&
          toLocalFrame(parent)->document()->loadEventStillNeeded()) ||
         (parent->isRemoteFrame() && parent->isLoading())) {
-      m_progressTracker->progressStarted();
+      m_progressTracker->progressStarted(m_documentLoader->loadType());
     }
   }
 
@@ -458,17 +458,18 @@
   if (m_stateMachine.creatingInitialEmptyDocument())
     return;
 
-  HistoryCommitType historyCommitType = loadTypeToCommitType(m_loadType);
+  FrameLoadType loadType = m_documentLoader->loadType();
+  HistoryCommitType historyCommitType = loadTypeToCommitType(loadType);
   if (historyCommitType == StandardCommit &&
       (m_documentLoader->urlForHistory().isEmpty() ||
        (opener() && !m_currentItem &&
         m_documentLoader->originalRequest().url().isEmpty())))
     historyCommitType = HistoryInertCommit;
-  setHistoryItemStateForCommit(m_loadType, historyCommitType,
+  setHistoryItemStateForCommit(loadType, historyCommitType,
                                HistoryNavigationType::DifferentDocument);
 
   if (!m_stateMachine.committedMultipleRealLoads() &&
-      m_loadType == FrameLoadTypeStandard) {
+      loadType == FrameLoadTypeStandard) {
     m_stateMachine.advanceTo(
         FrameLoaderStateMachine::CommittedMultipleRealLoads);
   }
@@ -516,7 +517,8 @@
       m_documentLoader ? m_documentLoader->releaseContentSecurityPolicy()
                        : ContentSecurityPolicy::create());
 
-  if (m_provisionalItem && isBackForwardLoadType(m_loadType)) {
+  if (m_provisionalItem &&
+      isBackForwardLoadType(m_documentLoader->loadType())) {
     m_frame->document()->setStateForNewFormElements(
         m_provisionalItem->getDocumentState());
   }
@@ -642,7 +644,8 @@
   // Check if the scrollbars are really needed for the content. If not, remove
   // them, relayout, and repaint.
   m_frame->view()->restoreScrollbar();
-  processFragment(m_frame->document()->url(), NavigationToDifferentDocument);
+  processFragment(m_frame->document()->url(), m_documentLoader->loadType(),
+                  NavigationToDifferentDocument);
 }
 
 static bool allDescendantsAreComplete(Frame* frame) {
@@ -744,8 +747,8 @@
     // Retry restoring scroll offset since finishing loading disables content
     // size clamping.
     restoreScrollPositionAndViewState();
-
-    m_loadType = FrameLoadTypeStandard;
+    if (m_documentLoader)
+      m_documentLoader->setLoadType(FrameLoadTypeStandard);
     m_frame->domWindow()->finishedLoading();
   }
 
@@ -861,7 +864,6 @@
   detachDocumentLoader(m_provisionalDocumentLoader);
   if (!m_frame->host())
     return;
-  AutoReset<FrameLoadType> loadTypeChange(&m_loadType, frameLoadType);
   saveScrollState();
 
   KURL oldURL = m_frame->document()->url();
@@ -888,11 +890,11 @@
                                         : SerializedScriptValue::nullValue());
 
   if (historyLoadType == HistorySameDocumentLoad)
-    restoreScrollPositionAndViewState();
+    restoreScrollPositionAndViewStateForLoadType(frameLoadType);
 
   // We need to scroll to the fragment whether or not a hash change occurred,
   // since the user might have scrolled since the previous navigation.
-  processFragment(url, NavigationWithinSameDocument);
+  processFragment(url, frameLoadType, NavigationWithinSameDocument);
   takeObjectSnapshot();
 }
 
@@ -931,7 +933,7 @@
   if (m_provisionalDocumentLoader &&
       request.substituteData().failingURL() ==
           m_provisionalDocumentLoader->url() &&
-      m_loadType == FrameLoadTypeBackForward)
+      m_provisionalDocumentLoader->loadType() == FrameLoadTypeBackForward)
     return FrameLoadTypeBackForward;
   if (request.resourceRequest().getCachePolicy() ==
       WebCachePolicy::ValidatingCacheData)
@@ -958,7 +960,7 @@
 
   if (request.substituteData().failingURL() ==
           m_documentLoader->urlForHistory() &&
-      m_loadType == FrameLoadTypeReload)
+      m_documentLoader->loadType() == FrameLoadTypeReload)
     return FrameLoadTypeReload;
 
   if (m_frame->settings()->getHistoryEntryRequiresUserGesture() &&
@@ -1384,19 +1386,20 @@
   return m_frame->isMainFrame();
 }
 
-FrameLoadType FrameLoader::loadType() const {
-  return m_loadType;
+void FrameLoader::restoreScrollPositionAndViewState() {
+  if (!m_frame->page() || !documentLoader())
+    return;
+  restoreScrollPositionAndViewStateForLoadType(documentLoader()->loadType());
 }
 
-void FrameLoader::restoreScrollPositionAndViewState() {
+void FrameLoader::restoreScrollPositionAndViewStateForLoadType(
+    FrameLoadType loadType) {
   FrameView* view = m_frame->view();
-  if (!m_frame->page() || !view || !view->layoutViewportScrollableArea() ||
-      !m_currentItem || !m_stateMachine.committedFirstRealDocumentLoad() ||
-      !documentLoader()) {
+  if (!view || !view->layoutViewportScrollableArea() || !m_currentItem ||
+      !m_stateMachine.committedFirstRealDocumentLoad()) {
     return;
   }
-
-  if (!needsHistoryItemRestore(m_loadType))
+  if (!needsHistoryItemRestore(loadType))
     return;
 
   bool shouldRestoreScroll =
@@ -1488,7 +1491,8 @@
       m_frame->deprecatedLocalOwner()->renderFallbackContent();
   }
 
-  HistoryCommitType historyCommitType = loadTypeToCommitType(m_loadType);
+  HistoryCommitType historyCommitType =
+      loadTypeToCommitType(loader->loadType());
   if (loader == m_provisionalDocumentLoader) {
     m_provisionalDocumentLoader->setSentDidFinishLoad();
     client()->dispatchDidFailProvisionalLoad(error, historyCommitType);
@@ -1524,6 +1528,7 @@
 }
 
 void FrameLoader::processFragment(const KURL& url,
+                                  FrameLoadType frameLoadType,
                                   LoadStartType loadStartType) {
   FrameView* view = m_frame->view();
   if (!view)
@@ -1548,7 +1553,7 @@
   // is a same document reload.
   bool shouldScrollToFragment =
       (loadStartType == NavigationWithinSameDocument &&
-       !isBackForwardLoadType(m_loadType)) ||
+       !isBackForwardLoadType(frameLoadType)) ||
       (documentLoader() &&
        !documentLoader()->initialScrollState().didRestoreFromHistory &&
        !(m_currentItem &&
@@ -1607,7 +1612,7 @@
     ContentSecurityPolicyDisposition shouldCheckMainWorldContentSecurityPolicy,
     NavigationType type,
     NavigationPolicy policy,
-    bool replacesCurrentHistoryItem,
+    FrameLoadType frameLoadType,
     bool isClientRedirect,
     HTMLFormElement* form) {
   // Don't ask if we are loading an empty URL.
@@ -1642,6 +1647,8 @@
           request.url()))
     return false;
 
+  bool replacesCurrentHistoryItem =
+      frameLoadType == FrameLoadTypeReplaceCurrentItem;
   policy = client()->decidePolicyForNavigation(request, loader, type, policy,
                                                replacesCurrentHistoryItem,
                                                isClientRedirect, form);
@@ -1652,7 +1659,7 @@
   if (policy == NavigationPolicyHandledByClient) {
     m_isNavigationHandledByClient = true;
     // Mark the frame as loading since the embedder is handling the navigation.
-    m_progressTracker->progressStarted();
+    m_progressTracker->progressStarted(frameLoadType);
 
     m_frame->navigationScheduler().cancel();
 
@@ -1689,8 +1696,7 @@
   if (!shouldContinueForNavigationPolicy(
           resourceRequest, frameLoadRequest.substituteData(), nullptr,
           frameLoadRequest.shouldCheckMainWorldContentSecurityPolicy(),
-          navigationType, navigationPolicy,
-          type == FrameLoadTypeReplaceCurrentItem,
+          navigationType, navigationPolicy, type,
           frameLoadRequest.clientRedirect() ==
               ClientRedirectPolicy::ClientRedirect,
           frameLoadRequest.form())) {
@@ -1740,6 +1746,7 @@
           ? frameLoadRequest.substituteData()
           : defaultSubstituteDataForURL(resourceRequest.url()),
       frameLoadRequest.clientRedirect());
+  m_provisionalDocumentLoader->setLoadType(type);
   m_provisionalDocumentLoader->setNavigationType(navigationType);
   m_provisionalDocumentLoader->setReplacesCurrentHistoryItem(
       type == FrameLoadTypeReplaceCurrentItem);
@@ -1751,8 +1758,6 @@
     m_checkTimer.stop();
   }
 
-  m_loadType = type;
-
   if (frameLoadRequest.form())
     client()->dispatchWillSubmitForm(frameLoadRequest.form());
 
@@ -1760,7 +1765,7 @@
   // the progress tracker. Otherwise don't, as it was already notified before
   // sending the navigation to teh client.
   if (!m_isNavigationHandledByClient)
-    m_progressTracker->progressStarted();
+    m_progressTracker->progressStarted(type);
   else
     m_isNavigationHandledByClient = false;
 
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.h b/third_party/WebKit/Source/core/loader/FrameLoader.h
index 672c3a39..6c85d34 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoader.h
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.h
@@ -129,9 +129,6 @@
   bool shouldTreatURLAsSameAsCurrent(const KURL&) const;
   bool shouldTreatURLAsSrcdocDocument(const KURL&) const;
 
-  FrameLoadType loadType() const;
-  void setLoadType(FrameLoadType loadType) { m_loadType = loadType; }
-
   FrameLoaderClient* client() const;
 
   void setDefersLoading(bool);
@@ -210,7 +207,7 @@
                                          ContentSecurityPolicyDisposition,
                                          NavigationType,
                                          NavigationPolicy,
-                                         bool shouldReplaceCurrentEntry,
+                                         FrameLoadType,
                                          bool isClientRedirect,
                                          HTMLFormElement*);
 
@@ -240,7 +237,7 @@
                                        const String& httpMethod,
                                        FrameLoadType,
                                        const KURL&);
-  void processFragment(const KURL&, LoadStartType);
+  void processFragment(const KURL&, FrameLoadType, LoadStartType);
 
   bool checkLoadCanStart(FrameLoadRequest&,
                          FrameLoadType,
@@ -259,6 +256,7 @@
                           HistoryLoadType,
                           ClientRedirectPolicy,
                           Document*);
+  void restoreScrollPositionAndViewStateForLoadType(FrameLoadType);
 
   void scheduleCheckCompleted();
 
@@ -279,8 +277,6 @@
 
   Member<ProgressTracker> m_progressTracker;
 
-  FrameLoadType m_loadType;
-
   // Document loaders for the three phases of frame loading. Note that while a
   // new request is being loaded, the old document loader may still be
   // referenced. E.g. while a new request is in the "policy" state, the old
diff --git a/third_party/WebKit/Source/core/loader/ProgressTracker.cpp b/third_party/WebKit/Source/core/loader/ProgressTracker.cpp
index fce737a..fdda55a 100644
--- a/third_party/WebKit/Source/core/loader/ProgressTracker.cpp
+++ b/third_party/WebKit/Source/core/loader/ProgressTracker.cpp
@@ -103,13 +103,13 @@
   return m_frame->client();
 }
 
-void ProgressTracker::progressStarted() {
+void ProgressTracker::progressStarted(FrameLoadType type) {
   if (!m_frame->isLoading())
     frameLoaderClient()->didStartLoading(NavigationToDifferentDocument);
   reset();
   m_progressValue = initialProgressValue;
   m_frame->setIsLoading(true);
-  InspectorInstrumentation::frameStartedLoading(m_frame);
+  InspectorInstrumentation::frameStartedLoading(m_frame, type);
 }
 
 void ProgressTracker::progressCompleted() {
diff --git a/third_party/WebKit/Source/core/loader/ProgressTracker.h b/third_party/WebKit/Source/core/loader/ProgressTracker.h
index 3ecbe24..403688b 100644
--- a/third_party/WebKit/Source/core/loader/ProgressTracker.h
+++ b/third_party/WebKit/Source/core/loader/ProgressTracker.h
@@ -27,6 +27,7 @@
 #define ProgressTracker_h
 
 #include "core/CoreExport.h"
+#include "core/loader/FrameLoaderTypes.h"
 #include "platform/heap/Handle.h"
 #include "platform/network/ResourceLoadPriority.h"
 #include "wtf/Allocator.h"
@@ -58,7 +59,7 @@
 
   double estimatedProgress() const;
 
-  void progressStarted();
+  void progressStarted(FrameLoadType);
   void progressCompleted();
 
   void finishedParsing();
diff --git a/third_party/WebKit/Source/core/loader/ProgressTrackerTest.cpp b/third_party/WebKit/Source/core/loader/ProgressTrackerTest.cpp
index af9bfe4..64a20d0 100644
--- a/third_party/WebKit/Source/core/loader/ProgressTrackerTest.cpp
+++ b/third_party/WebKit/Source/core/loader/ProgressTrackerTest.cpp
@@ -52,7 +52,7 @@
   // to ProgressTracker with identifier 1, but tests are responsible for
   // emulating payload and load completion.
   void emulateMainResourceRequestAndResponse() const {
-    progress().progressStarted();
+    progress().progressStarted(FrameLoadTypeStandard);
     progress().willStartLoading(1ul, ResourceLoadPriorityVeryHigh);
     EXPECT_EQ(0.0, lastProgress());
     progress().incrementProgress(1ul, responseHeaders());
@@ -66,7 +66,7 @@
 };
 
 TEST_F(ProgressTrackerTest, Static) {
-  progress().progressStarted();
+  progress().progressStarted(FrameLoadTypeStandard);
   EXPECT_EQ(0.0, lastProgress());
   progress().finishedParsing();
   EXPECT_EQ(1.0, lastProgress());
diff --git a/third_party/WebKit/Source/core/page/AutoscrollController.cpp b/third_party/WebKit/Source/core/page/AutoscrollController.cpp
index 748b48d..86c6732 100644
--- a/third_party/WebKit/Source/core/page/AutoscrollController.cpp
+++ b/third_party/WebKit/Source/core/page/AutoscrollController.cpp
@@ -203,14 +203,13 @@
 
 void AutoscrollController::handleMouseReleaseForMiddleClickAutoscroll(
     LocalFrame* frame,
-    const PlatformMouseEvent& mouseEvent) {
+    const WebMouseEvent& mouseEvent) {
   DCHECK(RuntimeEnabledFeatures::middleClickAutoscrollEnabled());
   if (!frame->isMainFrame())
     return;
   switch (m_autoscrollType) {
     case AutoscrollForMiddleClick:
-      if (mouseEvent.pointerProperties().button ==
-          WebPointerProperties::Button::Middle)
+      if (mouseEvent.button == WebPointerProperties::Button::Middle)
         m_autoscrollType = AutoscrollForMiddleClickCanStop;
       break;
     case AutoscrollForMiddleClickCanStop:
diff --git a/third_party/WebKit/Source/core/page/AutoscrollController.h b/third_party/WebKit/Source/core/page/AutoscrollController.h
index aab9602b..5ab08a0 100644
--- a/third_party/WebKit/Source/core/page/AutoscrollController.h
+++ b/third_party/WebKit/Source/core/page/AutoscrollController.h
@@ -38,9 +38,9 @@
 class FrameView;
 class Node;
 class Page;
-class PlatformMouseEvent;
 class LayoutBox;
 class LayoutObject;
+class WebMouseEvent;
 
 enum AutoscrollType {
   NoAutoscroll,
@@ -72,7 +72,7 @@
                          const IntPoint& eventPosition,
                          TimeTicks eventTime);
   void handleMouseReleaseForMiddleClickAutoscroll(LocalFrame*,
-                                                  const PlatformMouseEvent&);
+                                                  const WebMouseEvent&);
   void startMiddleClickAutoscroll(LayoutBox*, const IntPoint&);
 
  private:
diff --git a/third_party/WebKit/Source/core/page/ContextMenuControllerTest.cpp b/third_party/WebKit/Source/core/page/ContextMenuControllerTest.cpp
index 94435af8..ae1100c 100644
--- a/third_party/WebKit/Source/core/page/ContextMenuControllerTest.cpp
+++ b/third_party/WebKit/Source/core/page/ContextMenuControllerTest.cpp
@@ -76,11 +76,15 @@
       "</menu>"
       "</button>");
 
+  MouseEventInit mouseInitializer;
+  mouseInitializer.setView(document().domWindow());
+  mouseInitializer.setScreenX(50);
+  mouseInitializer.setScreenY(50);
+  mouseInitializer.setButton(1);
+
   // Create right button click event and pass it to context menu controller.
-  Event* event = MouseEvent::create(
-      EventTypeNames::click, false, false, document().domWindow(), 50, 50, 0, 0,
-      0, 0, 0, PlatformEvent::NoModifiers, 1, 0, nullptr, TimeTicks(),
-      PlatformMouseEvent::RealOrIndistinguishable, String(), nullptr);
+  Event* event =
+      MouseEvent::create(nullptr, EventTypeNames::click, mouseInitializer);
   document().getElementById("button_id")->focus();
   event->setTarget(document().getElementById("button_id"));
   document().page()->contextMenuController().handleContextMenuEvent(event);
diff --git a/third_party/WebKit/Source/core/page/DragController.cpp b/third_party/WebKit/Source/core/page/DragController.cpp
index c9eef0f9..07385275 100644
--- a/third_party/WebKit/Source/core/page/DragController.cpp
+++ b/third_party/WebKit/Source/core/page/DragController.cpp
@@ -118,12 +118,19 @@
 }
 #endif  // DCHECK_IS_ON()
 
-static PlatformMouseEvent createMouseEvent(DragData* dragData) {
-  return PlatformMouseEvent(
-      dragData->clientPosition(), dragData->globalPosition(),
-      WebPointerProperties::Button::Left, PlatformEvent::MouseMoved, 0,
+static WebMouseEvent createMouseEvent(DragData* dragData) {
+  WebMouseEvent result(
+      WebInputEvent::MouseMove, WebFloatPoint(dragData->clientPosition().x(),
+                                              dragData->clientPosition().y()),
+      WebFloatPoint(dragData->globalPosition().x(),
+                    dragData->globalPosition().y()),
+      WebPointerProperties::Button::Left, 0,
       static_cast<PlatformEvent::Modifiers>(dragData->modifiers()),
-      PlatformMouseEvent::RealOrIndistinguishable, TimeTicks::Now());
+      TimeTicks::Now().InSeconds());
+  // TODO(dtapuska): Really we should chnage DragData to store the viewport
+  // coordinates and scale.
+  result.setFrameScale(1);
+  return result;
 }
 
 static DataTransfer* createDraggingDataTransfer(DataTransferAccessPolicy policy,
@@ -719,7 +726,7 @@
   DragOperation srcOpMask = dragData->draggingSourceOperationMask();
   dataTransfer->setSourceOperation(srcOpMask);
 
-  PlatformMouseEvent event = createMouseEvent(dragData);
+  WebMouseEvent event = createMouseEvent(dragData);
   if (localRoot.eventHandler().updateDragAndDrop(event, dataTransfer) ==
       WebInputEventResult::NotHandled) {
     dataTransfer->setAccessPolicy(
@@ -1050,7 +1057,7 @@
 
 bool DragController::startDrag(LocalFrame* src,
                                const DragState& state,
-                               const PlatformMouseEvent& dragEvent,
+                               const WebMouseEvent& dragEvent,
                                const IntPoint& dragOrigin) {
 #if DCHECK_IS_ON()
   DCHECK(dragTypeIsValid(state.m_dragType));
@@ -1072,8 +1079,8 @@
   const KURL& linkURL = hitTestResult.absoluteLinkURL();
   const KURL& imageURL = hitTestResult.absoluteImageURL();
 
-  IntPoint mouseDraggedPoint =
-      src->view()->rootFrameToContents(dragEvent.position());
+  IntPoint mouseDraggedPoint = src->view()->rootFrameToContents(
+      flooredIntPoint(dragEvent.positionInRootFrame()));
 
   IntPoint dragLocation;
   IntPoint dragOffset;
diff --git a/third_party/WebKit/Source/core/page/DragController.h b/third_party/WebKit/Source/core/page/DragController.h
index 3d28be6c..763f657 100644
--- a/third_party/WebKit/Source/core/page/DragController.h
+++ b/third_party/WebKit/Source/core/page/DragController.h
@@ -47,7 +47,7 @@
 class HTMLInputElement;
 class Node;
 class Page;
-class PlatformMouseEvent;
+class WebMouseEvent;
 
 class CORE_EXPORT DragController final
     : public GarbageCollected<DragController> {
@@ -76,7 +76,7 @@
                                 const IntPoint& dragOrigin);
   bool startDrag(LocalFrame* src,
                  const DragState&,
-                 const PlatformMouseEvent& dragEvent,
+                 const WebMouseEvent& dragEvent,
                  const IntPoint& dragOrigin);
 
   DECLARE_TRACE();
diff --git a/third_party/WebKit/Source/core/page/EventWithHitTestResults.h b/third_party/WebKit/Source/core/page/EventWithHitTestResults.h
index 9d0bdb7..b829255 100644
--- a/third_party/WebKit/Source/core/page/EventWithHitTestResults.h
+++ b/third_party/WebKit/Source/core/page/EventWithHitTestResults.h
@@ -23,8 +23,8 @@
 
 #include "core/layout/HitTestResult.h"
 #include "platform/PlatformEvent.h"
-#include "platform/PlatformMouseEvent.h"
 #include "public/platform/WebGestureEvent.h"
+#include "public/platform/WebMouseEvent.h"
 
 namespace blink {
 
@@ -46,14 +46,16 @@
   bool isOverLink() const { return m_hitTestResult.isOverLink(); }
   bool isOverWidget() const { return m_hitTestResult.isOverWidget(); }
   Node* innerNode() const { return m_hitTestResult.innerNode(); }
+  const String& canvasRegionId() const {
+    return m_hitTestResult.canvasRegionId();
+  }
 
  private:
   EventType m_event;
   HitTestResult m_hitTestResult;
 };
 
-using MouseEventWithHitTestResults =
-    EventWithHitTestResults<PlatformMouseEvent>;
+using MouseEventWithHitTestResults = EventWithHitTestResults<WebMouseEvent>;
 
 using GestureEventWithHitTestResults = EventWithHitTestResults<WebGestureEvent>;
 
diff --git a/third_party/WebKit/Source/core/page/PointerLockController.cpp b/third_party/WebKit/Source/core/page/PointerLockController.cpp
index 720e004..97b298b 100644
--- a/third_party/WebKit/Source/core/page/PointerLockController.cpp
+++ b/third_party/WebKit/Source/core/page/PointerLockController.cpp
@@ -31,7 +31,7 @@
 #include "core/inspector/ConsoleMessage.h"
 #include "core/page/ChromeClient.h"
 #include "core/page/Page.h"
-#include "platform/PlatformMouseEvent.h"
+#include "public/platform/WebMouseEvent.h"
 
 namespace blink {
 
@@ -132,17 +132,18 @@
 }
 
 void PointerLockController::dispatchLockedMouseEvent(
-    const PlatformMouseEvent& event,
+    const WebMouseEvent& event,
     const AtomicString& eventType) {
   if (!m_element || !m_element->document().frame())
     return;
 
-  m_element->dispatchMouseEvent(event, eventType, event.clickCount());
+  m_element->dispatchMouseEvent(event, eventType, event.clickCount);
 
   // Create click events
-  if (eventType == EventTypeNames::mouseup)
+  if (eventType == EventTypeNames::mouseup) {
     m_element->dispatchMouseEvent(event, EventTypeNames::click,
-                                  event.clickCount());
+                                  event.clickCount);
+  }
 }
 
 void PointerLockController::clearElement() {
diff --git a/third_party/WebKit/Source/core/page/PointerLockController.h b/third_party/WebKit/Source/core/page/PointerLockController.h
index cea1abb7..d4caa2f 100644
--- a/third_party/WebKit/Source/core/page/PointerLockController.h
+++ b/third_party/WebKit/Source/core/page/PointerLockController.h
@@ -36,7 +36,7 @@
 class Element;
 class Document;
 class Page;
-class PlatformMouseEvent;
+class WebMouseEvent;
 
 class CORE_EXPORT PointerLockController final
     : public GarbageCollected<PointerLockController> {
@@ -55,7 +55,7 @@
   void didAcquirePointerLock();
   void didNotAcquirePointerLock();
   void didLosePointerLock();
-  void dispatchLockedMouseEvent(const PlatformMouseEvent&,
+  void dispatchLockedMouseEvent(const WebMouseEvent&,
                                 const AtomicString& eventType);
 
   DECLARE_TRACE();
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index 894d81f..4b9c6d9 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -78,7 +78,6 @@
 #include "core/page/scrolling/ScrollingCoordinator.h"
 #include "core/page/scrolling/TopDocumentRootScrollerController.h"
 #include "core/paint/PaintLayerFragment.h"
-#include "platform/PlatformMouseEvent.h"
 #include "platform/graphics/CompositorMutableProperties.h"
 #include "platform/graphics/GraphicsLayer.h"
 #include "platform/graphics/paint/DrawingRecorder.h"
diff --git a/third_party/WebKit/Source/core/svg/SVGAElement.cpp b/third_party/WebKit/Source/core/svg/SVGAElement.cpp
index 6dec847d..a3283c6 100644
--- a/third_party/WebKit/Source/core/svg/SVGAElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGAElement.cpp
@@ -44,7 +44,6 @@
 #include "core/page/ChromeClient.h"
 #include "core/page/Page.h"
 #include "core/svg/animation/SVGSMILElement.h"
-#include "platform/PlatformMouseEvent.h"
 #include "platform/network/ResourceRequest.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
index bd0ea3c..efca992 100644
--- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
+++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
@@ -59,8 +59,8 @@
     this._executionContextComboBox.setMaxWidth(200);
     this._consoleContextSelector = new Console.ConsoleContextSelector(this._executionContextComboBox.selectElement());
 
-    this._filter = new Console.ConsoleViewFilter(this);
-    this._filter.addEventListener(Console.ConsoleViewFilter.Events.FilterChanged, this._updateMessageList.bind(this));
+    this._showAllMessagesCheckbox = new UI.ToolbarCheckbox(Common.UIString('Show all messages'));
+    this._filter = new Console.ConsoleViewFilter(this._showAllMessagesCheckbox, this._updateMessageList.bind(this));
 
     this._filterBar = new UI.FilterBar('consoleView');
 
@@ -95,9 +95,9 @@
     this._messagesElement.insertBefore(this._filterStatusMessageElement, this._messagesElement.firstChild);
     this._filterStatusTextElement = this._filterStatusMessageElement.createChild('span', 'console-info');
     this._filterStatusMessageElement.createTextChild(' ');
-    var resetFiltersLink = this._filterStatusMessageElement.createChild('span', 'console-info link');
-    resetFiltersLink.textContent = Common.UIString('Show all messages.');
-    resetFiltersLink.addEventListener('click', this._filter.reset.bind(this._filter), true);
+    this._resetFiltersLink = createElementWithClass('span', 'link');
+    this._resetFiltersLink.textContent = Common.UIString('filters');
+    this._resetFiltersLink.addEventListener('click', () => this._filterBar.showOnce(), true);
 
     this._topGroup = Console.ConsoleGroup.createTopGroup();
     this._currentGroup = this._topGroup;
@@ -112,7 +112,6 @@
     var selectAllFixer = this._messagesElement.createChild('div', 'console-view-fix-select-all');
     selectAllFixer.textContent = '.';
 
-    this._showAllMessagesCheckbox = new UI.ToolbarCheckbox(Common.UIString('Show all messages'));
     this._showAllMessagesCheckbox.inputElement.checked = true;
     this._showAllMessagesCheckbox.inputElement.addEventListener('change', this._updateMessageList.bind(this), false);
 
@@ -433,9 +432,11 @@
   }
 
   _updateFilterStatus() {
-    this._filterStatusTextElement.textContent = Common.UIString(
-        this._hiddenByFilterCount === 1 ? '%d message is hidden by filters.' : '%d messages are hidden by filters.',
-        this._hiddenByFilterCount);
+    this._filterStatusTextElement.removeChildren();
+    this._filterStatusTextElement.appendChild(UI.formatLocalized(
+        this._hiddenByFilterCount === 1 ? '1 message is hidden by %s.' :
+                                          this._hiddenByFilterCount + ' messages are hidden by %s.',
+        [this._resetFiltersLink]));
     this._filterStatusMessageElement.style.display = this._hiddenByFilterCount ? '' : 'none';
   }
 
@@ -511,8 +512,7 @@
    */
   _appendMessageToEnd(viewMessage) {
     if (!this._filter.shouldBeVisible(viewMessage)) {
-      if (this._filter.shouldBeVisibleByDefault(viewMessage))
-        this._hiddenByFilterCount++;
+      this._hiddenByFilterCount++;
       return;
     }
 
@@ -605,7 +605,7 @@
 
     var hasFilters = false;
 
-    for (var url in this._filter.messageURLFilters) {
+    for (var url in this._filter.messageURLFilters()) {
       filterSubMenu.appendCheckboxItem(
           String.sprintf('%s (%d)', new Common.ParsedURL(url).displayName, this._urlToMessageCount[url]),
           this._filter.removeMessageURLFilter.bind(this._filter, url), true);
@@ -1043,16 +1043,22 @@
  */
 Console.ConsoleViewFilter = class extends Common.Object {
   /**
-   * @param {!Console.ConsoleView} view
+   * @param {!UI.ToolbarCheckbox} showAllMessagesCheckbox
+   * @param {function()} filterChangedCallback
    */
-  constructor(view) {
+  constructor(showAllMessagesCheckbox, filterChangedCallback) {
     super();
-    this._messageURLFiltersSetting = Common.settings.createSetting('messageURLFilters', {});
-    this._messageLevelFiltersSetting = Common.settings.createSetting('messageLevelFilters', {});
+    this._showAllMessagesCheckbox = showAllMessagesCheckbox;
+    this._filterChanged = filterChangedCallback;
 
-    this._view = view;
-    this._messageURLFilters = this._messageURLFiltersSetting.get();
-    this._filterChanged = this.dispatchEventToListeners.bind(this, Console.ConsoleViewFilter.Events.FilterChanged);
+    this._messageURLFiltersSetting = Common.settings.createSetting('messageURLFilters', {});
+    this._messageLevelFiltersSetting =
+        Common.settings.createSetting('messageLevelFilters2', SDK.ConsoleMessage.MessageLevel.Info);
+    this._hideNetworkMessagesSetting = Common.moduleSetting('hideNetworkMessages');
+
+    this._messageURLFiltersSetting.addChangeListener(this._filterChanged);
+    this._messageLevelFiltersSetting.addChangeListener(this._filterChanged);
+    this._hideNetworkMessagesSetting.addChangeListener(this._filterChanged);
   }
 
   addFilters(filterBar) {
@@ -1061,28 +1067,22 @@
     filterBar.addFilter(this._textFilterUI);
 
     this._hideNetworkMessagesCheckbox =
-        new UI.CheckboxFilterUI('', Common.UIString('Hide network'), true, Common.moduleSetting('hideNetworkMessages'));
-    this._hideViolationMessagesCheckbox = new UI.CheckboxFilterUI(
-        '', Common.UIString('Hide violations'), false, Common.moduleSetting('hideViolationMessages'));
-    Common.moduleSetting('hideNetworkMessages').addChangeListener(this._filterChanged, this);
-    Common.moduleSetting('hideViolationMessages').addChangeListener(this._filterChanged, this);
-    filterBar.addFilter(this._hideNetworkMessagesCheckbox);
-    filterBar.addFilter(this._hideViolationMessagesCheckbox);
+        new UI.CheckboxFilterUI('', Common.UIString('Hide network'), true, this._hideNetworkMessagesSetting);
 
     var levels = [
-      {name: SDK.ConsoleMessage.MessageLevel.Error, label: Common.UIString('Errors')},
-      {name: SDK.ConsoleMessage.MessageLevel.Warning, label: Common.UIString('Warnings')},
-      {name: SDK.ConsoleMessage.MessageLevel.Info, label: Common.UIString('Info')},
-      {name: SDK.ConsoleMessage.MessageLevel.Verbose, label: Common.UIString('Verbose')}
+      {value: SDK.ConsoleMessage.MessageLevel.Verbose, label: Common.UIString('Verbose')},
+      {value: SDK.ConsoleMessage.MessageLevel.Info, label: Common.UIString('Info'), default: true},
+      {value: SDK.ConsoleMessage.MessageLevel.Warning, label: Common.UIString('Warnings')},
+      {value: SDK.ConsoleMessage.MessageLevel.Error, label: Common.UIString('Errors')}
     ];
-    this._levelFilterUI = new UI.NamedBitSetFilterUI(levels, this._messageLevelFiltersSetting);
-    this._levelFilterUI.addEventListener(UI.FilterUI.Events.FilterChanged, this._filterChanged, this);
-    filterBar.addFilter(this._levelFilterUI);
+
+    var levelFilter = new UI.ComboBoxFilterUI(levels, Common.UIString('Level: '), this._messageLevelFiltersSetting);
+    filterBar.addFilter(levelFilter);
+    filterBar.addFilter(this._hideNetworkMessagesCheckbox);
   }
 
   _textFilterChanged(event) {
     this._filterRegex = this._textFilterUI.regex();
-
     this._filterChanged();
   }
 
@@ -1090,29 +1090,30 @@
    * @param {string} url
    */
   addMessageURLFilter(url) {
-    this._messageURLFilters[url] = true;
-    this._messageURLFiltersSetting.set(this._messageURLFilters);
-    this._filterChanged();
+    var value = this._messageURLFiltersSetting.get();
+    value[url] = true;
+    this._messageURLFiltersSetting.set(value);
   }
 
   /**
    * @param {string} url
    */
   removeMessageURLFilter(url) {
-    if (!url)
-      this._messageURLFilters = {};
-    else
-      delete this._messageURLFilters[url];
-
-    this._messageURLFiltersSetting.set(this._messageURLFilters);
-    this._filterChanged();
+    var value;
+    if (url) {
+      value = this._messageURLFiltersSetting.get();
+      delete value[url];
+    } else {
+      value = {};
+    }
+    this._messageURLFiltersSetting.set(value);
   }
 
   /**
    * @returns {!Object}
    */
-  get messageURLFilters() {
-    return this._messageURLFilters;
+  messageURLFilters() {
+    return this._messageURLFiltersSetting.get();
   }
 
   /**
@@ -1125,7 +1126,7 @@
     if (!message.target())
       return true;
 
-    if (!this._view._showAllMessagesCheckbox.checked() && executionContext) {
+    if (!this._showAllMessagesCheckbox.checked() && executionContext) {
       if (message.target() !== executionContext.target())
         return false;
       if (message.executionContextId && message.executionContextId !== executionContext.id)
@@ -1136,10 +1137,6 @@
         viewMessage.consoleMessage().source === SDK.ConsoleMessage.MessageSource.Network)
       return false;
 
-    if (Common.moduleSetting('hideViolationMessages').get() &&
-        viewMessage.consoleMessage().source === SDK.ConsoleMessage.MessageSource.Violation)
-      return false;
-
     if (viewMessage.consoleMessage().isGroupMessage())
       return true;
 
@@ -1147,10 +1144,12 @@
         message.type === SDK.ConsoleMessage.MessageType.Command)
       return true;
 
-    if (message.url && this._messageURLFilters[message.url])
+    if (message.url && this._messageURLFiltersSetting.get()[message.url])
       return false;
 
-    if (message.level && !this._levelFilterUI.accept(message.level))
+    var filterOrdinal = SDK.ConsoleMessage.MessageLevel.ordinal(
+        /** @type {!SDK.ConsoleMessage.MessageLevel} */ (this._messageLevelFiltersSetting.get()));
+    if (message.level && SDK.ConsoleMessage.MessageLevel.ordinal(message.level) < filterOrdinal)
       return false;
 
     if (this._filterRegex) {
@@ -1162,30 +1161,16 @@
     return true;
   }
 
-  /**
-   * @return {boolean}
-   */
-  shouldBeVisibleByDefault(viewMessage) {
-    return viewMessage.consoleMessage().source !== SDK.ConsoleMessage.MessageSource.Violation;
-  }
-
   reset() {
-    this._messageURLFilters = {};
-    this._messageURLFiltersSetting.set(this._messageURLFilters);
-    this._messageLevelFiltersSetting.set({});
-    this._view._showAllMessagesCheckbox.inputElement.checked = true;
+    this._messageURLFiltersSetting.set({});
+    this._messageLevelFiltersSetting.set(SDK.ConsoleMessage.MessageLevel.Info);
+    this._showAllMessagesCheckbox.inputElement.checked = true;
     Common.moduleSetting('hideNetworkMessages').set(false);
-    Common.moduleSetting('hideViolationMessages').set(true);
     this._textFilterUI.setValue('');
     this._filterChanged();
   }
 };
 
-/** @enum {symbol} */
-Console.ConsoleViewFilter.Events = {
-  FilterChanged: Symbol('FilterChanged')
-};
-
 /**
  * @unrestricted
  */
diff --git a/third_party/WebKit/Source/devtools/front_end/console/consoleView.css b/third_party/WebKit/Source/devtools/front_end/console/consoleView.css
index 81dc4de..ff4e77e 100644
--- a/third_party/WebKit/Source/devtools/front_end/console/consoleView.css
+++ b/third_party/WebKit/Source/devtools/front_end/console/consoleView.css
@@ -137,6 +137,7 @@
 .console-info {
     color: rgb(128, 128, 128);
     font-style: italic;
+    padding-bottom: 2px;
 }
 
 .console-group .console-group > .console-group-messages {
@@ -233,10 +234,6 @@
     color: hsl(0, 100%, 75%) !important;
 }
 
-.console-verbose-level .console-message-text {
-    color: blue;
-}
-
 .-theme-with-dark-background .console-verbose-level .console-message-text {
     color: hsl(220, 100%, 65%) !important;
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js
index 161b1d3..cec8d429 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js
@@ -731,6 +731,8 @@
    * @param {!Element} cell
    */
   _renderNameCell(cell) {
+    var leftPadding = this.leftPadding ? this.leftPadding + 'px' : '';
+    cell.style.setProperty('padding-left', leftPadding);
     this._nameCell = cell;
     cell.addEventListener('dblclick', this._openInNewTab.bind(this), false);
     var iconElement;
@@ -948,6 +950,8 @@
   createCell(columnIdentifier) {
     var cell = this.createTD(columnIdentifier);
     if (columnIdentifier === 'name') {
+      var leftPadding = this.leftPadding ? this.leftPadding + 'px' : '';
+      cell.style.setProperty('padding-left', leftPadding);
       cell.classList.add('disclosure');
       this._setTextAndTitle(cell, this._displayName);
     }
diff --git a/third_party/WebKit/Source/devtools/front_end/network/networkConfigView.css b/third_party/WebKit/Source/devtools/front_end/network/networkConfigView.css
index df43e5a..5580678 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/networkConfigView.css
+++ b/third_party/WebKit/Source/devtools/front_end/network/networkConfigView.css
@@ -57,7 +57,11 @@
     line-height: 20px;
 }
 
-.network-config-ua input {
+.network-config-ua label[is="dt-radio"].checked > * {
+    display: none
+}
+
+.network-config-ua input:not(.dt-radio-button) {
     display: block;
     width: calc(100% - 20px);
     max-width: 250px;
@@ -89,6 +93,10 @@
     max-width: 250px;
 }
 
+.network-config-ua label[is="dt-radio"] {
+    display: block;
+}
+
 .network-config-ua-auto, .network-config-ua-custom {
     opacity: 0.5;
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/quick_open/filteredListWidget.css b/third_party/WebKit/Source/devtools/front_end/quick_open/filteredListWidget.css
index f9f51f5..2bde335 100644
--- a/third_party/WebKit/Source/devtools/front_end/quick_open/filteredListWidget.css
+++ b/third_party/WebKit/Source/devtools/front_end/quick_open/filteredListWidget.css
@@ -26,6 +26,7 @@
     height: 18px;
     margin-top: 12px;
     overflow: hidden;
+    flex: auto;
 }
 
 .filtered-list-widget-progress {
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
index 77825f6..9793a4b 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
@@ -273,7 +273,7 @@
       workerId) {
     this._target = target;
     this.source = source;
-    this.level = level;
+    this.level = /** @type {?SDK.ConsoleMessage.MessageLevel} */ (level);
     this.messageText = messageText;
     this.type = type || SDK.ConsoleMessage.MessageType.Log;
     /** @type {string|undefined} */
@@ -519,6 +519,19 @@
   Error: 'error'
 };
 
+/**
+ * @param {!SDK.ConsoleMessage.MessageLevel} level
+ * @return {number}
+ */
+SDK.ConsoleMessage.MessageLevel.ordinal = function(level) {
+  if (level === SDK.ConsoleMessage.MessageLevel.Verbose)
+    return 0;
+  if (level === SDK.ConsoleMessage.MessageLevel.Info)
+    return 1;
+  if (level === SDK.ConsoleMessage.MessageLevel.Warning)
+    return 2;
+  return 3;
+};
 
 /**
  * @implements {Protocol.LogDispatcher}
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
index dd7b378..5e6d0f07 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
@@ -1355,7 +1355,7 @@
     while (stack) {
       if (stack.description === 'async function' && stack.callFrames.length)
         stack.callFrames.shift();
-      if (previous && !stack.callFrames.length)
+      if (previous && (!stack.callFrames.length && !stack.promiseCreationFrame))
         previous.parent = stack.parent;
       else
         previous = stack;
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js
index f4c19d1..3869aa84 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js
@@ -93,7 +93,8 @@
     var peviousStackTrace = details.callFrames;
     while (asyncStackTrace) {
       var title = '';
-      if (asyncStackTrace.description === 'async function') {
+      if (asyncStackTrace.description === 'async function' && peviousStackTrace.length &&
+          asyncStackTrace.callFrames.length) {
         var lastPreviousFrame = peviousStackTrace[peviousStackTrace.length - 1];
         var topFrame = asyncStackTrace.callFrames[0];
         var lastPreviousFrameName = UI.beautifyFunctionName(lastPreviousFrame.functionName);
@@ -110,8 +111,11 @@
                 /** @type {!SDK.DebuggerModel.Location} */ (this._itemLocation(item))));
         hiddenCallFramesCount += asyncStackTrace.callFrames.length - asyncItems.length;
       }
-      if (asyncItems.length) {
-        items.push({asyncStackHeader: title});
+      if (asyncItems.length || asyncStackTrace.promiseCreationFrame) {
+        var titleItem = {asyncStackHeader: title};
+        if (asyncStackTrace.promiseCreationFrame)
+          titleItem.promiseCreationFrame = asyncStackTrace.promiseCreationFrame;
+        items.push(titleItem);
         items = items.concat(asyncItems);
       }
 
@@ -149,6 +153,7 @@
 
     var location = this._itemLocation(item);
     if (location) {
+      element.classList.add('contains-location');
       if (Bindings.blackboxManager.isBlackboxedRawLocation(location))
         element.classList.add('blackboxed-call-frame');
 
@@ -159,12 +164,13 @@
         var uiLocation = liveLocation.uiLocation();
         if (!uiLocation)
           return;
-        var text = uiLocation.linkText();
+        var text = (hasPromiseCreationFrame ? Common.UIString('created:  ') : '') + uiLocation.linkText();
         linkElement.textContent = text.trimMiddle(30);
         linkElement.title = text;
       }
 
       var linkElement = element.createChild('div', 'call-frame-location');
+      var hasPromiseCreationFrame = !!item.promiseCreationFrame;
       Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(location, updateLocation, this._locationPool);
     }
 
@@ -237,10 +243,9 @@
   _itemLocation(item) {
     if (item.debuggerCallFrame)
       return item.debuggerCallFrame.location();
-    if (item.runtimeCallFrame) {
-      return new SDK.DebuggerModel.Location(
-          this._debuggerModel, item.runtimeCallFrame.scriptId, item.runtimeCallFrame.lineNumber,
-          item.runtimeCallFrame.columnNumber);
+    if (item.runtimeCallFrame || item.promiseCreationFrame) {
+      var frame = item.runtimeCallFrame || item.promiseCreationFrame;
+      return new SDK.DebuggerModel.Location(this._debuggerModel, frame.scriptId, frame.lineNumber, frame.columnNumber);
     }
     return null;
   }
@@ -284,7 +289,7 @@
    */
   _onClick(event) {
     var item = this._list.itemForNode(/** @type {?Node} */ (event.target));
-    if (!item || !item.runtimeCallFrame)
+    if (!item || (!item.runtimeCallFrame && !item.promiseCreationFrame))
       return;
     var location = this._itemLocation(item);
     if (!location)
@@ -374,7 +379,8 @@
  * @typedef {{
  *     debuggerCallFrame: (SDK.DebuggerModel.CallFrame|undefined),
  *     asyncStackHeader: (string|undefined),
- *     runtimeCallFrame: (Protocol.Runtime.CallFrame|undefined)
+ *     runtimeCallFrame: (Protocol.Runtime.CallFrame|undefined),
+ *     promiseCreationFrame: (Protocol.Runtime.CallFrame|undefined)
  * }}
  */
 Sources.CallStackSidebarPane.Item;
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/callStackSidebarPane.css b/third_party/WebKit/Source/devtools/front_end/sources/callStackSidebarPane.css
index 6190422..652f133c 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/callStackSidebarPane.css
+++ b/third_party/WebKit/Source/devtools/front_end/sources/callStackSidebarPane.css
@@ -29,7 +29,7 @@
     border-top: 1px solid #efefef;
 }
 
-.call-frame-item:not(.async-header):hover {
+.call-frame-item.contains-location:hover {
     background-color: #eee;
 }
 
@@ -48,6 +48,12 @@
     color: #888;
     margin-left: auto;
     padding: 0 10px 0 10px;
+    background-color: white;
+    white-space: pre;
+}
+
+.call-frame-item:hover .call-frame-location {
+    background-color: inherit;
 }
 
 .async-header::before {
@@ -68,6 +74,10 @@
     padding: 0 5px;
 }
 
+.call-frame-item.contains-location:hover .call-frame-item-title {
+    background-color: inherit;
+}
+
 .blackboxed-call-frame {
     opacity: 0.6;
     font-style: italic;
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineEventOverview.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineEventOverview.js
index 8d634e0..73ea48d 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineEventOverview.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineEventOverview.js
@@ -157,59 +157,29 @@
    */
   update() {
     super.update();
-    const height = this.height();
-    const numBands = categoryBand(Timeline.TimelineUIUtils.NetworkCategory.Other) + 1;
-    const devicePixelRatio = window.devicePixelRatio;
-    const bandHeight = height - (numBands + 1) * devicePixelRatio;
-    const timeOffset = this._model.minimumRecordTime();
-    const timeSpan = this._model.maximumRecordTime() - timeOffset;
-    const canvasWidth = this.width();
-    const scale = canvasWidth / timeSpan;
-    const ctx = this.context();
-    const paths = [];
-    for (const categoryName in Timeline.TimelineUIUtils.NetworkCategory) {
-      const category = Timeline.TimelineUIUtils.NetworkCategory[categoryName];
-      paths[categoryBand(category)] = {
-        style: Timeline.TimelineUIUtils.networkCategoryColor(category),
-        path: new Path2D()
-      };
+    var bandHeight = this.height() / 2;
+    var timeOffset = this._model.minimumRecordTime();
+    var timeSpan = this._model.maximumRecordTime() - timeOffset;
+    var canvasWidth = this.width();
+    var scale = canvasWidth / timeSpan;
+    var highPath = new Path2D();
+    var lowPath = new Path2D();
+    var priorities = Protocol.Network.ResourcePriority;
+    var highPrioritySet = new Set([priorities.VeryHigh, priorities.High, priorities.Medium]);
+    for (var request of this._model.networkRequests()) {
+      var path = highPrioritySet.has(request.priority) ? highPath : lowPath;
+      var s = Math.max(Math.floor((request.startTime - timeOffset) * scale), 0);
+      var e = Math.min(Math.ceil((request.endTime - timeOffset) * scale + 1), canvasWidth);
+      path.rect(s, 0, e - s, bandHeight - 1);
     }
-    for (const request of this._model.networkRequests()) {
-      const category = Timeline.TimelineUIUtils.networkRequestCategory(request);
-      const band = categoryBand(category);
-      const y = (numBands - band - 1) * devicePixelRatio;
-      const s = Math.max(Math.floor((request.startTime - timeOffset) * scale), 0);
-      const e = Math.min(Math.ceil((request.endTime - timeOffset) * scale + 1), canvasWidth);
-      paths[band].path.rect(s, y, e - s, bandHeight);
-    }
-    for (const path of paths.reverse()) {
-      ctx.globalAlpha = 1;
-      ctx.fillStyle = path.style;
-      ctx.fill(path.path);
-      ctx.globalAlpha = 0.4;
-      ctx.fillStyle = 'white';
-      ctx.fill(path.path);
-    }
-
-    /**
-     * @param {!Timeline.TimelineUIUtils.NetworkCategory} category
-     * @return {number}
-     */
-    function categoryBand(category) {
-      const categories = Timeline.TimelineUIUtils.NetworkCategory;
-      switch (category) {
-        case categories.HTML:
-          return 0;
-        case categories.Script:
-          return 1;
-        case categories.Style:
-          return 2;
-        case categories.Media:
-          return 3;
-        default:
-          return 4;
-      }
-    }
+    var ctx = this.context();
+    ctx.save();
+    ctx.fillStyle = 'hsl(214, 60%, 60%)';
+    ctx.fill(/** @type {?} */ (highPath));
+    ctx.translate(0, bandHeight);
+    ctx.fillStyle = 'hsl(214, 80%, 80%)';
+    ctx.fill(/** @type {?} */ (lowPath));
+    ctx.restore();
   }
 };
 
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineNetworkFlameChart.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineNetworkFlameChart.js
index edc7062..08c90933 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineNetworkFlameChart.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineNetworkFlameChart.js
@@ -298,19 +298,17 @@
    * @return {?string}
    */
   _colorForPriority(priority) {
-    switch (/** @type {!Protocol.Network.ResourcePriority} */ (priority)) {
-      case Protocol.Network.ResourcePriority.VeryLow:
-        return '#080';
-      case Protocol.Network.ResourcePriority.Low:
-        return '#6c0';
-      case Protocol.Network.ResourcePriority.Medium:
-        return '#fa0';
-      case Protocol.Network.ResourcePriority.High:
-        return '#f60';
-      case Protocol.Network.ResourcePriority.VeryHigh:
-        return '#f00';
+    if (!this._priorityToValue) {
+      var priorities = Protocol.Network.ResourcePriority;
+      this._priorityToValue = new Map([
+        [priorities.VeryLow, 1],
+        [priorities.Low, 2],
+        [priorities.Medium, 3],
+        [priorities.High, 4],
+        [priorities.VeryHigh, 5]]);
     }
-    return null;
+    var value = this._priorityToValue.get(priority);
+    return value ? `hsla(214, 80%, 50%, ${value / 5})` : null;
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js
index b08edf6..3cfffb69 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js
@@ -965,11 +965,12 @@
       if (!durationMs) {
         durationOption.label = Common.UIString('All');
         durationOption.title = Common.UIString('Show all records');
+        durationOption.default = true;
       } else {
         durationOption.label = Common.UIString('\u2265 %dms', durationMs);
         durationOption.title = Common.UIString('Hide records shorter than %dms', durationMs);
       }
-      durationOption.value = durationMs;
+      durationOption.value = String(durationMs);
       durationOptions.push(durationOption);
     }
     var durationFilterUI = new UI.ComboBoxFilterUI(durationOptions);
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css b/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css
index 82a6533..35f271ca 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css
@@ -109,7 +109,7 @@
     background-color: rgba(255, 255, 255, 0.7);
     padding: 0 4px;
     position: absolute;
-    top: 0;
+    top: -2px;
     right: 0;
 }
 
@@ -118,7 +118,7 @@
 }
 
 #timeline-overview-network {
-    flex-basis: 12px;
+    flex-basis: 8px;
 }
 
 #timeline-overview-framerate {
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/FilterBar.js b/third_party/WebKit/Source/devtools/front_end/ui/FilterBar.js
index 59d6161..a050aed 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/FilterBar.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/FilterBar.js
@@ -79,6 +79,10 @@
     this._updateFilterBar();
   }
 
+  showOnce() {
+    this._stateSetting.set(true);
+  }
+
   /**
    * @param {!Common.Event} event
    */
@@ -452,26 +456,28 @@
  */
 UI.ComboBoxFilterUI = class extends Common.Object {
   /**
-   * @param {!Array.<!{value: *, label: string, title: string}>} options
+   * @param {!Array.<!{value: string, label: string, title: string, default:(boolean|undefined)}>} options
+   * @param {string=} label
+   * @param {!Common.Setting=} setting
    */
-  constructor(options) {
+  constructor(options, label, setting) {
     super();
-    this._filterElement = createElement('div');
-    this._filterElement.className = 'filter-combobox-filter';
+    this._setting = setting;
+    this._toolbar = new UI.Toolbar('');
+    this._filterComboBox = new UI.ToolbarComboBox(this._filterChanged.bind(this));
+    this._toolbar.appendToolbarItem(this._filterComboBox);
 
     this._options = options;
-    this._filterComboBox = createElementWithClass('select', 'chrome-select');
-    this._filterComboBox.addEventListener('input', this._filterChanged.bind(this), false);
     for (var i = 0; i < options.length; ++i) {
       var filterOption = options[i];
-      var option = createElement('option');
-      option.text = filterOption.label;
-      option.title = filterOption.title;
-      this._filterComboBox.appendChild(option);
+      var option = this._filterComboBox.createOption(filterOption.label, filterOption.title, filterOption.value);
+      this._filterComboBox.addOption(option);
+      if (setting && setting.get() === filterOption.value)
+        this._filterComboBox.setSelectedIndex(i);
     }
-    if (options.length)
-      this._filterComboBox.title = options[0].title;
-    this._filterElement.appendChild(this._filterComboBox);
+
+    if (setting)
+      setting.addChangeListener(this._settingChanged, this);
   }
 
   /**
@@ -479,7 +485,8 @@
    * @return {boolean}
    */
   isActive() {
-    return this._filterComboBox.selectedIndex !== 0;
+    var option = this._options[this._filterComboBox.selectedIndex()];
+    return !option || !option.default;
   }
 
   /**
@@ -487,37 +494,53 @@
    * @return {!Element}
    */
   element() {
-    return this._filterElement;
+    return this._toolbar.element;
   }
 
   /**
-   * @return {*}
+   * @return {string}
    */
   value() {
-    var option = this._options[this._filterComboBox.selectedIndex];
-    return option.value;
+    return this._options[this._filterComboBox.selectedIndex()].value;
   }
 
   /**
    * @param {number} index
    */
   setSelectedIndex(index) {
-    this._filterComboBox.selectedIndex = index;
+    this._filterComboBox.setSelectedIndex(index);
   }
 
   /**
    * @return {number}
    */
   selectedIndex(index) {
-    return this._filterComboBox.selectedIndex;
+    return this._filterComboBox.selectedIndex();
+  }
+
+  _settingChanged() {
+    if (this._muteSettingListener)
+      return;
+
+    var value = this._setting.get();
+    for (var i = 0; i < this._options.length; ++i) {
+      if (value === this._options[i].value) {
+        this._filterComboBox.setSelectedIndex(i);
+        break;
+      }
+    }
   }
 
   /**
    * @param {!Event} event
    */
   _filterChanged(event) {
-    var option = this._options[this._filterComboBox.selectedIndex];
-    this._filterComboBox.title = option.title;
+    var option = this._options[this._filterComboBox.selectedIndex()];
+    if (this._setting) {
+      this._muteSettingListener = true;
+      this._setting.set(option.value);
+      this._muteSettingListener = false;
+    }
     this.dispatchEventToListeners(UI.FilterUI.Events.FilterChanged, null);
   }
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js b/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js
index 2579859e..2372c64 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js
@@ -109,7 +109,7 @@
     this._boundClearAutocomplete = this.clearAutocomplete.bind(this);
     this._proxyElement = element.ownerDocument.createElement('span');
     var shadowRoot = UI.createShadowRootWithCoreStyles(this._proxyElement, 'ui/textPrompt.css');
-    this._contentElement = shadowRoot.createChild('div');
+    this._contentElement = shadowRoot.createChild('div', 'text-prompt-root');
     this._contentElement.createChild('content');
     this._proxyElement.style.display = this._proxyElementDisplay;
     element.parentElement.insertBefore(this._proxyElement, element);
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
index cea913c..2dc28a22 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
@@ -752,8 +752,13 @@
  * @return {string}
  */
 UI.asyncStackTraceLabel = function(description) {
-  if (description)
+  if (description) {
+    if (description === 'Promise.resolve')
+      description = Common.UIString('Promise resolved');
+    else if (description === 'Promise.reject')
+      description = Common.UIString('Promise rejected');
     return description + ' ' + Common.UIString('(async)');
+  }
   return Common.UIString('Async Call');
 };
 
@@ -1354,9 +1359,10 @@
      * @this {Element}
      */
     createdCallback: function() {
-      var root = UI.createShadowRootWithCoreStyles(this, 'ui/radioButton.css');
-      this.radioElement = root.createChild('input', 'dt-radio-button');
+      this.radioElement = this.createChild('input', 'dt-radio-button');
       this.radioElement.type = 'radio';
+      var root = UI.createShadowRootWithCoreStyles(this, 'ui/radioButton.css');
+      root.createChild('content').select = '.dt-radio-button';
       root.createChild('content');
       this.addEventListener('click', radioClickHandler, false);
     },
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/filter.css b/third_party/WebKit/Source/devtools/front_end/ui/filter.css
index 2de512b5..9dd6558 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/filter.css
+++ b/third_party/WebKit/Source/devtools/front_end/ui/filter.css
@@ -30,7 +30,6 @@
 
 .filter-bar {
     background-color: #f3f3f3;
-    padding: 2px 0;
     flex: none;
     flex-wrap: wrap;
     align-items: center;
@@ -142,7 +141,7 @@
     border: 1px solid rgb(163, 163, 163);
     border-radius: 2px;
     padding: 1px 3px 0;
-    margin: 0 0 0 1px;
+    margin: 0 0 0 3px;
     width: 143px;
     height: 20px;
     line-height: 17px;
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/radioButton.css b/third_party/WebKit/Source/devtools/front_end/ui/radioButton.css
index f0e77c6..47f4775b 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/radioButton.css
+++ b/third_party/WebKit/Source/devtools/front_end/ui/radioButton.css
@@ -4,7 +4,7 @@
  * found in the LICENSE file.
  */
 
-.dt-radio-button {
+::content .dt-radio-button {
     height: 17px;
     width: 17px;
     min-width: 17px;
@@ -16,16 +16,16 @@
     margin: 0 5px 5px 0;
 }
 
-.dt-radio-button:active:not(:disabled) {
+::content .dt-radio-button:active:not(:disabled) {
     background-image: linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));
 }
 
-.dt-radio-button:checked {
+::content .dt-radio-button:checked {
     background: url(Images/radioDot.png) center no-repeat,
                 linear-gradient(to bottom, rgb(252, 252, 252), rgb(223, 223, 223));
 }
 
-.dt-radio-button:checked:active {
+::content .dt-radio-button:checked:active {
     background: url(Images/radioDot.png) center no-repeat,
                 linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/textPrompt.css b/third_party/WebKit/Source/devtools/front_end/ui/textPrompt.css
index a39597a..2996f8c5 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/textPrompt.css
+++ b/third_party/WebKit/Source/devtools/front_end/ui/textPrompt.css
@@ -4,6 +4,11 @@
  * found in the LICENSE file.
  */
 
+.text-prompt-root {
+    display: flex;
+    align-items: center;
+}
+
 .text-prompt-editing {
     -webkit-user-select: text;
     box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2),
diff --git a/third_party/WebKit/Source/devtools/package.json b/third_party/WebKit/Source/devtools/package.json
index d065909..1e2519f 100644
--- a/third_party/WebKit/Source/devtools/package.json
+++ b/third_party/WebKit/Source/devtools/package.json
@@ -7,6 +7,7 @@
     "server": "node scripts/hosted_mode/server.js",
     "test": "node scripts/npm_test.js",
     "debug-test": "node scripts/npm_test.js --debug-devtools",
+    "compat-test": "node scripts/npm_test.js --compat-protocol=1.2",
     "lint": "eslint front_end",
     "format": "node scripts/format.js",
     "closure": "python scripts/compile_frontend.py",
diff --git a/third_party/WebKit/Source/devtools/scripts/npm_test.js b/third_party/WebKit/Source/devtools/scripts/npm_test.js
index bfde075..b07453b 100644
--- a/third_party/WebKit/Source/devtools/scripts/npm_test.js
+++ b/third_party/WebKit/Source/devtools/scripts/npm_test.js
@@ -13,7 +13,8 @@
   DEBUG_DEVTOOLS: '--debug-devtools',
   DEBUG_DEVTOOLS_SHORTHAND: '-d',
   FETCH_CONTENT_SHELL: '--fetch-content-shell',
-  COMPAT_PROTOCOL: '--compat-protocol',
+  COMPAT_PROTOCOL: '--compat-protocol',  // backwards compatibility testing
+  CHROMIUM_PATH: '--chromium-path'       // useful for bisecting
 };
 
 var COMPAT_URL_MAPPING = {
@@ -23,6 +24,7 @@
 var IS_DEBUG_ENABLED =
     utils.includes(process.argv, Flags.DEBUG_DEVTOOLS) || utils.includes(process.argv, Flags.DEBUG_DEVTOOLS_SHORTHAND);
 var COMPAT_PROTOCOL = utils.parseArgs(process.argv)[Flags.COMPAT_PROTOCOL];
+var CUSTOM_CHROMIUM_PATH = utils.parseArgs(process.argv)[Flags.CHROMIUM_PATH];
 var IS_FETCH_CONTENT_SHELL = utils.includes(process.argv, Flags.FETCH_CONTENT_SHELL);
 
 var CONTENT_SHELL_ZIP = 'content-shell.zip';
@@ -30,10 +32,10 @@
 var PLATFORM = getPlatform();
 var PYTHON = process.platform === 'win32' ? 'python.bat' : 'python';
 
-var CHROMIUM_SRC_PATH = path.resolve(__dirname, '..', '..', '..', '..', '..');
+var CHROMIUM_SRC_PATH = CUSTOM_CHROMIUM_PATH || path.resolve(__dirname, '..', '..', '..', '..', '..');
 var RELEASE_PATH = path.resolve(CHROMIUM_SRC_PATH, 'out', 'Release');
 var BLINK_TEST_PATH = path.resolve(CHROMIUM_SRC_PATH, 'blink', 'tools', 'run_layout_tests.py');
-var DEVTOOLS_PATH = path.resolve(__dirname, '..');
+var DEVTOOLS_PATH = path.resolve(CHROMIUM_SRC_PATH, 'third_party', 'WebKit', 'Source', 'devtools');
 var CACHE_PATH = path.resolve(DEVTOOLS_PATH, '.test_cache');
 var SOURCE_PATH = path.resolve(DEVTOOLS_PATH, 'front_end');
 
@@ -67,6 +69,7 @@
 
 function runCompatibilityTests() {
   const folder = `compat-protocol-${COMPAT_PROTOCOL}`;
+  utils.removeRecursive(path.resolve(RELEASE_PATH, 'resources', 'inspector'));
   compileFrontend();
   var outPath = path.resolve(CACHE_PATH, folder, 'out');
   var contentShellDirPath = path.resolve(outPath, 'Release');
@@ -87,7 +90,7 @@
 function compileFrontend() {
   console.log('Compiling devtools frontend');
   try {
-    shell(`ninja -C ${RELEASE_PATH} devtools_frontend_resources`);
+    shell(`ninja -C ${RELEASE_PATH} devtools_frontend_resources`, {cwd: CHROMIUM_SRC_PATH});
   } catch (err) {
     console.log(err.stdout.toString());
     console.log('ERROR: Cannot compile frontend\n' + err);
@@ -271,9 +274,12 @@
     console.log('TIP: You can debug a test using: npm run debug-test inspector/test-name.html');
 
   if (COMPAT_PROTOCOL) {
-    let platform = `protocol-${COMPAT_PROTOCOL}`;
-    let compatBaselinePath = path.resolve(DEVTOOLS_PATH, 'tests', 'baseline', platform);
+    const platform = `protocol-${COMPAT_PROTOCOL}`;
+    const testsPath = path.resolve(DEVTOOLS_PATH, 'tests');
+    const compatBaselinePath = path.resolve(testsPath, 'baseline', platform);
     testArgs.push(`--additional-platform-directory=${compatBaselinePath}`);
+    const expectationsPath = path.resolve(testsPath, 'TestExpectations');
+    testArgs.push(`--additional-expectations=${expectationsPath}`);
   }
   if (IS_DEBUG_ENABLED) {
     testArgs.push('--additional-driver-flag=--remote-debugging-port=9222');
diff --git a/third_party/WebKit/Source/devtools/tests/TestExpectations b/third_party/WebKit/Source/devtools/tests/TestExpectations
new file mode 100644
index 0000000..fb45c50
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/tests/TestExpectations
@@ -0,0 +1,55 @@
+# Skipping service worker tests b/c migration from ServiceWorker domain to Target domain
+# https://crrev.com/c2cea7d490e0b9ec93b72b0e00502bb9fa79f10a
+http/tests/inspector/elements/event-listeners-framework-with-service-worker.html [ Skip ]
+http/tests/inspector/service-workers/lazy-addeventlisteners.html [ Skip ]
+http/tests/inspector/service-workers/service-worker-agents.html [ Skip ]
+http/tests/inspector/service-workers/service-worker-manager.html [ Skip ]
+http/tests/inspector/service-workers/service-worker-pause.html [ Skip ]
+http/tests/inspector/service-workers/service-workers-force-update-on-page-load.html [ Skip ]
+http/tests/inspector/service-workers/service-workers-navigation-preload.html [ Skip ]
+http/tests/inspector/service-workers/service-workers-redundant.html [ Skip ]
+http/tests/inspector/service-workers/service-workers-view.html [ Skip ]
+http/tests/inspector/service-workers/service-workers-bypass-for-network-redirect.html [ Skip ]
+
+# Skipping worker tests b/c migration from Worker domain to Target domain
+# https://crrev.com/14d5ae1493499885e5f9820490e77aef43d0d083
+http/tests/inspector-enabled/dedicated-workers-list.html [ Skip ]
+http/tests/inspector/sources/debugger/worker-debugging-script-mapping.html [ Skip ]
+http/tests/inspector/sources/debugger/worker-debugging.html [ Skip ]
+inspector/console/console-revoke-error-in-worker.html [ Skip ]
+inspector/console/worker-eval-contains-stack.html [ Skip ]
+inspector/sources/debugger-frameworks/frameworks-with-worker.html [ Skip ]
+inspector/sources/debugger-ui/script-snippet-model.html [ Skip ] # TODO(chenwilliam): extract the worker test
+
+# Skipping accessibility tests b/c of protocol change
+# https://crrev.com/3a46cc72d58945804dd4919a679a8ce26690bfc0
+inspector-protocol/accessibility/accessibility-getNodeWithNoAXNode.html [ Skip ]
+inspector-protocol/accessibility/accessibility-getRelationships.html [ Skip ]
+inspector-protocol/accessibility/accessibility-ignoredNodes.html [ Skip ]
+inspector-protocol/accessibility/accessibility-ignoredNodesModal.html [ Skip ]
+inspector-protocol/accessibility/accessibility-nameSources-buttons.html [ Skip ]
+inspector-protocol/accessibility/accessibility-nameSources-img-figure.html [ Skip ]
+inspector-protocol/accessibility/accessibility-nameSources-input-buttons.html [ Skip ]
+inspector-protocol/accessibility/accessibility-nameSources-input.html [ Skip ]
+inspector-protocol/accessibility/accessibility-nameSources-labelledby.html [ Skip ]
+inspector-protocol/accessibility/accessibility-nameSources-summary.html [ Skip ]
+inspector-protocol/accessibility/accessibility-nameSources-visiblity.html [ Skip ]
+
+# Skipping async await tests b/c 1.2 content shell (DevTools runtime) does not
+# support async await
+inspector/sources/debugger-async/async-await/async-callstack-async-await1.html [ Skip ]
+inspector/sources/debugger-async/async-await/async-callstack-async-await2.html [ Skip ]
+inspector/sources/debugger-async/async-await/async-callstack-async-await3.html [ Skip ]
+inspector/sources/debugger-async/async-await/async-pause-on-exception.html [ Skip ]
+inspector/sources/debugger-ui/async-call-stack-async-function.html [ Skip ]
+
+# 1.2 content shell does not support inspector-unit
+http/tests/inspector-unit/filtered-item-selection-dialog-filtering.js [ Skip ]
+http/tests/inspector-unit/list-control-equal-height.js [ Skip ]
+http/tests/inspector-unit/list-control-non-viewport.js [ Skip ]
+http/tests/inspector-unit/list-control-various-height.js [ Skip ]
+http/tests/inspector-unit/suggest-box.js [ Skip ]
+http/tests/inspector-unit/test-failure.js [ Skip ]
+http/tests/inspector-unit/text-prompt-hint.js [ Skip ]
+http/tests/inspector-unit/text-prompt.js [ Skip ]
+http/tests/inspector-unit/trie.js [ Skip ]
\ No newline at end of file
diff --git a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTCharacteristic.cpp b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTCharacteristic.cpp
index 1de9bc3..c462463ac 100644
--- a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTCharacteristic.cpp
+++ b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTCharacteristic.cpp
@@ -51,6 +51,8 @@
 
 void BluetoothRemoteGATTCharacteristic::dispatchCharacteristicValueChanged(
     const Vector<uint8_t>& value) {
+  if (!getGatt()->connected())
+    return;
   this->setValue(BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(value));
   dispatchEvent(Event::create(EventTypeNames::characteristicvaluechanged));
 }
diff --git a/third_party/WebKit/Source/modules/mediasession/MediaSession.cpp b/third_party/WebKit/Source/modules/mediasession/MediaSession.cpp
index 70f4bb5..2d4bf56 100644
--- a/third_party/WebKit/Source/modules/mediasession/MediaSession.cpp
+++ b/third_party/WebKit/Source/modules/mediasession/MediaSession.cpp
@@ -13,6 +13,7 @@
 #include "modules/mediasession/MediaMetadataSanitizer.h"
 #include "platform/UserGestureIndicator.h"
 #include "public/platform/InterfaceProvider.h"
+#include "public/platform/Platform.h"
 #include "wtf/Optional.h"
 #include <memory>
 
@@ -205,8 +206,12 @@
     return nullptr;
 
   interfaceProvider->getInterface(mojo::MakeRequest(&m_service));
-  if (m_service.get())
+  if (m_service.get()) {
+    // Record the eTLD+1 of the frame using the API.
+    Platform::current()->recordRapporURL("Media.Session.APIUsage.Origin",
+                                         document->url());
     m_service->SetClient(m_clientBinding.CreateInterfacePtrAndBind());
+  }
 
   return m_service.get();
 }
diff --git a/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientationControllerImpl.cpp b/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientationControllerImpl.cpp
index b3f4e3e..abc7d9a 100644
--- a/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientationControllerImpl.cpp
+++ b/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientationControllerImpl.cpp
@@ -101,8 +101,16 @@
   m_orientation->setAngle(screenInfo.orientationAngle);
 }
 
+bool ScreenOrientationControllerImpl::isActive() const {
+  return m_orientation && m_client;
+}
+
+bool ScreenOrientationControllerImpl::isVisible() const {
+  return page() && page()->isPageVisible();
+}
+
 bool ScreenOrientationControllerImpl::isActiveAndVisible() const {
-  return m_orientation && m_client && page() && page()->isPageVisible();
+  return isActive() && isVisible();
 }
 
 void ScreenOrientationControllerImpl::pageVisibilityChanged() {
@@ -130,10 +138,11 @@
 }
 
 void ScreenOrientationControllerImpl::notifyOrientationChanged() {
-  if (!isActiveAndVisible())
+  if (!isVisible())
     return;
 
-  updateOrientation();
+  if (isActive())
+    updateOrientation();
 
   // Keep track of the frames that need to be notified before notifying the
   // current frame as it will prevent side effects from the change event
@@ -146,14 +155,15 @@
   }
 
   // Notify current orientation object.
-  if (!m_dispatchEventTimer.isActive())
+  if (isActive() && !m_dispatchEventTimer.isActive())
     m_dispatchEventTimer.startOneShot(0, BLINK_FROM_HERE);
 
   // ... and child frames, if they have a ScreenOrientationControllerImpl.
   for (size_t i = 0; i < childFrames.size(); ++i) {
     if (ScreenOrientationControllerImpl* controller =
-            ScreenOrientationControllerImpl::from(*childFrames[i]))
+            ScreenOrientationControllerImpl::from(*childFrames[i])) {
       controller->notifyOrientationChanged();
+    }
   }
 }
 
diff --git a/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientationControllerImpl.h b/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientationControllerImpl.h
index 88010b7..dadb7f5d 100644
--- a/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientationControllerImpl.h
+++ b/third_party/WebKit/Source/modules/screen_orientation/ScreenOrientationControllerImpl.h
@@ -64,6 +64,8 @@
 
   void dispatchEventTimerFired(TimerBase*);
 
+  bool isActive() const;
+  bool isVisible() const;
   bool isActiveAndVisible() const;
 
   Member<ScreenOrientation> m_orientation;
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index c100adc..0c68523 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -304,7 +304,6 @@
     "PlatformEvent.h",
     "PlatformInstrumentation.cpp",
     "PlatformInstrumentation.h",
-    "PlatformMouseEvent.h",
     "PlatformResourceLoader.cpp",
     "PlatformResourceLoader.h",
     "PluginScriptForbiddenScope.cpp",
diff --git a/third_party/WebKit/Source/platform/PlatformEvent.h b/third_party/WebKit/Source/platform/PlatformEvent.h
index d8c09cb4..21ab74c 100644
--- a/third_party/WebKit/Source/platform/PlatformEvent.h
+++ b/third_party/WebKit/Source/platform/PlatformEvent.h
@@ -36,12 +36,6 @@
  public:
   enum EventType {
     NoType = 0,
-
-    // PlatformMouseEvent
-    MouseMoved,
-    MousePressed,
-    MouseReleased,
-    MouseScroll,
   };
 
   // These values are direct mappings of the values in WebInputEvent so the
diff --git a/third_party/WebKit/Source/platform/PlatformMouseEvent.h b/third_party/WebKit/Source/platform/PlatformMouseEvent.h
deleted file mode 100644
index f8234d7..0000000
--- a/third_party/WebKit/Source/platform/PlatformMouseEvent.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PlatformMouseEvent_h
-#define PlatformMouseEvent_h
-
-#include "platform/PlatformEvent.h"
-#include "platform/geometry/FloatPoint.h"
-#include "platform/geometry/IntPoint.h"
-#include "public/platform/WebGestureEvent.h"
-#include "public/platform/WebPointerProperties.h"
-#include "wtf/text/WTFString.h"
-
-namespace blink {
-
-class PlatformMouseEvent : public PlatformEvent {
- public:
-  enum SyntheticEventType {
-    // Real mouse input events or synthetic events that behave just like real
-    // events
-    RealOrIndistinguishable,
-    // Synthetic mouse events derived from touch input
-    FromTouch,
-    // Synthetic mouse events generated without a position, for example those
-    // generated from keyboard input.
-    Positionless,
-  };
-
-  PlatformMouseEvent() : PlatformMouseEvent(PlatformEvent::MouseMoved) {}
-
-  explicit PlatformMouseEvent(EventType type)
-      : PlatformEvent(type),
-        m_clickCount(0),
-        m_synthesized(RealOrIndistinguishable) {}
-
-  PlatformMouseEvent(const IntPoint& position,
-                     const IntPoint& globalPosition,
-                     WebPointerProperties::Button button,
-                     EventType type,
-                     int clickCount,
-                     Modifiers modifiers,
-                     TimeTicks timestamp)
-      : PlatformEvent(type, modifiers, timestamp),
-        m_position(position),
-        m_globalPosition(globalPosition),
-        m_clickCount(clickCount),
-        m_synthesized(RealOrIndistinguishable) {
-    m_pointerProperties.button = button;
-  }
-
-  PlatformMouseEvent(const IntPoint& position,
-                     const IntPoint& globalPosition,
-                     WebPointerProperties::Button button,
-                     EventType type,
-                     int clickCount,
-                     Modifiers modifiers,
-                     SyntheticEventType synthesized,
-                     TimeTicks timestamp,
-                     WebPointerProperties::PointerType pointerType =
-                         WebPointerProperties::PointerType::Unknown)
-      : PlatformEvent(type, modifiers, timestamp),
-        m_position(position),
-        m_globalPosition(globalPosition),
-        m_clickCount(clickCount),
-        m_synthesized(synthesized) {
-    m_pointerProperties.pointerType = pointerType;
-    m_pointerProperties.button = button;
-  }
-
-#if INSIDE_BLINK
-  PlatformMouseEvent(const WebGestureEvent& gestureEvent,
-                     WebPointerProperties::Button button,
-                     EventType type,
-                     int clickCount,
-                     Modifiers modifiers,
-                     SyntheticEventType synthesized,
-                     TimeTicks timestamp,
-                     WebPointerProperties::PointerType pointerType =
-                         WebPointerProperties::PointerType::Unknown)
-      : PlatformMouseEvent(flooredIntPoint(gestureEvent.positionInRootFrame()),
-                           IntPoint(gestureEvent.globalX, gestureEvent.globalY),
-                           button,
-                           type,
-                           clickCount,
-                           modifiers,
-                           synthesized,
-                           timestamp,
-                           pointerType) {}
-#endif
-
-  const WebPointerProperties& pointerProperties() const {
-    return m_pointerProperties;
-  }
-  const IntPoint& position() const { return m_position; }
-  const IntPoint& globalPosition() const { return m_globalPosition; }
-  const IntPoint& movementDelta() const { return m_movementDelta; }
-
-  int clickCount() const { return m_clickCount; }
-  bool fromTouch() const { return m_synthesized == FromTouch; }
-  SyntheticEventType getSyntheticEventType() const { return m_synthesized; }
-
-  const String& region() const { return m_region; }
-  void setRegion(const String& region) { m_region = region; }
-
- protected:
-  WebPointerProperties m_pointerProperties;
-
-  // In local root frame coordinates. (Except possibly if the Widget under
-  // the mouse is a popup, see FIXME in PlatformMouseEventBuilder).
-  IntPoint m_position;
-
-  // In screen coordinates.
-  IntPoint m_globalPosition;
-
-  IntPoint m_movementDelta;
-  int m_clickCount;
-  SyntheticEventType m_synthesized;
-
-  // For canvas hit region.
-  // TODO(zino): This might make more sense to put in HitTestResults or
-  // some other part of MouseEventWithHitTestResults, but for now it's
-  // most convenient to stash it here. Please see: http://crbug.com/592947.
-  String m_region;
-};
-
-}  // namespace blink
-
-#endif  // PlatformMouseEvent_h
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
index cd2b3ae4..f0f5226d 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -258,7 +258,7 @@
 WebBluetooth status=experimental
 WebGLDraftExtensions status=experimental
 WebGLImageChromium
-WebUSB status=experimental, origin_trial_feature_name=WebUSB
+WebUSB status=experimental, origin_trial_feature_name=WebUSB2
 WebVR status=test, origin_trial_feature_name=WebVR
 WebVTTRegions status=experimental
 V8BasedStructuredClone status=stable
diff --git a/third_party/WebKit/Source/platform/WebMouseEvent.cpp b/third_party/WebKit/Source/platform/WebMouseEvent.cpp
index 4e6e9575..8e297fa 100644
--- a/third_party/WebKit/Source/platform/WebMouseEvent.cpp
+++ b/third_party/WebKit/Source/platform/WebMouseEvent.cpp
@@ -4,8 +4,28 @@
 
 #include "public/platform/WebMouseEvent.h"
 
+#include "public/platform/WebGestureEvent.h"
+
 namespace blink {
 
+WebMouseEvent::WebMouseEvent(WebInputEvent::Type type,
+                             const WebGestureEvent& gestureEvent,
+                             Button buttonParam,
+                             int clickCountParam,
+                             int modifiers,
+                             double timeStampSeconds)
+    : WebInputEvent(sizeof(WebMouseEvent), type, modifiers, timeStampSeconds),
+      WebPointerProperties(buttonParam,
+                           WebPointerProperties::PointerType::Mouse),
+      x(gestureEvent.x),
+      y(gestureEvent.y),
+      globalX(gestureEvent.globalX),
+      globalY(gestureEvent.globalY),
+      clickCount(clickCountParam) {
+  setFrameScale(gestureEvent.frameScale());
+  setFrameTranslate(gestureEvent.frameTranslate());
+}
+
 WebFloatPoint WebMouseEvent::movementInRootFrame() const {
   return WebFloatPoint((movementX / m_frameScale), (movementY / m_frameScale));
 }
@@ -15,6 +35,12 @@
                        (y / m_frameScale) + m_frameTranslate.y);
 }
 
+WebMouseEvent WebMouseEvent::flattenTransform() const {
+  WebMouseEvent result = *this;
+  result.flattenTransformSelf();
+  return result;
+}
+
 void WebMouseEvent::flattenTransformSelf() {
   x = (x / m_frameScale) + m_frameTranslate.x;
   y = (y / m_frameScale) + m_frameTranslate.y;
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
index bb9cfa9..b647e3d 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
@@ -987,7 +987,7 @@
     if (contextLost) {
       deleteCHROMIUMImage(releasedMailboxInfo->m_imageInfo);
     } else {
-      m_imageInfoCache.append(releasedMailboxInfo->m_imageInfo);
+      m_imageInfoCache.push_back(releasedMailboxInfo->m_imageInfo);
     }
   }
 #endif  // USE_IOSURFACE_FOR_2D_CANVAS
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
index 8c850d7..5effe8e 100644
--- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
+++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
@@ -13,6 +13,7 @@
 #include "cc/playback/filter_display_item.h"
 #include "cc/playback/float_clip_display_item.h"
 #include "cc/playback/transform_display_item.h"
+#include "cc/trees/layer_tree_host.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/graphics/compositing/PropertyTreeManager.h"
 #include "platform/graphics/paint/ClipPaintPropertyNode.h"
@@ -677,11 +678,11 @@
 
   DCHECK(m_rootLayer);
 
-  cc::LayerTree* layerTree = m_rootLayer->GetLayerTree();
+  cc::LayerTreeHost* layerTreeHost = m_rootLayer->layer_tree_host();
 
   // The tree will be null after detaching and this update can be ignored.
   // See: WebViewImpl::detachPaintArtifactCompositor().
-  if (!layerTree)
+  if (!layerTreeHost)
     return;
 
   if (m_extraDataForTestingEnabled)
@@ -691,7 +692,7 @@
   m_rootLayer->set_property_tree_sequence_number(
       PropertyTreeManager::kPropertyTreeSequenceNumber);
 
-  PropertyTreeManager propertyTreeManager(*layerTree->property_trees(),
+  PropertyTreeManager propertyTreeManager(*layerTreeHost->property_trees(),
                                           m_rootLayer.get());
 
   Vector<PendingLayer, 0> pendingLayers;
@@ -734,10 +735,10 @@
   m_contentLayerClients.swap(newContentLayerClients);
 
   // Mark the property trees as having been rebuilt.
-  layerTree->property_trees()->sequence_number =
+  layerTreeHost->property_trees()->sequence_number =
       PropertyTreeManager::kPropertyTreeSequenceNumber;
-  layerTree->property_trees()->needs_rebuild = false;
-  layerTree->property_trees()->ResetCachedData();
+  layerTreeHost->property_trees()->needs_rebuild = false;
+  layerTreeHost->property_trees()->ResetCachedData();
 }
 
 #ifndef NDEBUG
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
index 704d509..1ad40ee 100644
--- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
@@ -92,27 +92,23 @@
 
   const cc::PropertyTrees& propertyTrees() {
     return *m_webLayerTreeView->layerTreeHost()
-                ->GetLayerTree()
                 ->property_trees();
   }
 
   int elementIdToEffectNodeIndex(CompositorElementId elementId) {
     return m_webLayerTreeView->layerTreeHost()
-        ->GetLayerTree()
         ->property_trees()
         ->element_id_to_effect_node_index[elementId];
   }
 
   int elementIdToTransformNodeIndex(CompositorElementId elementId) {
     return m_webLayerTreeView->layerTreeHost()
-        ->GetLayerTree()
         ->property_trees()
         ->element_id_to_transform_node_index[elementId];
   }
 
   int elementIdToScrollNodeIndex(CompositorElementId elementId) {
     return m_webLayerTreeView->layerTreeHost()
-        ->GetLayerTree()
         ->property_trees()
         ->element_id_to_scroll_node_index[elementId];
   }
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp
index 1ea38a2..088dab80 100644
--- a/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp
+++ b/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp
@@ -7,6 +7,7 @@
 #include "cc/layers/layer.h"
 #include "cc/trees/clip_node.h"
 #include "cc/trees/effect_node.h"
+#include "cc/trees/layer_tree_host.h"
 #include "cc/trees/property_tree.h"
 #include "cc/trees/scroll_node.h"
 #include "cc/trees/transform_node.h"
@@ -73,7 +74,8 @@
   // TODO(jaydasika): We shouldn't set ToScreen and FromScreen of root
   // transform node here. They should be set while updating transform tree in
   // cc.
-  float deviceScaleFactor = m_rootLayer->GetLayerTree()->device_scale_factor();
+  float deviceScaleFactor =
+      m_rootLayer->layer_tree_host()->device_scale_factor();
   gfx::Transform toScreen;
   toScreen.Scale(deviceScaleFactor, deviceScaleFactor);
   transformTree.SetToScreen(kRealRootNodeId, toScreen);
@@ -100,7 +102,7 @@
   clipNode.owning_layer_id = m_rootLayer->id();
   clipNode.clip_type = cc::ClipNode::ClipType::APPLIES_LOCAL_CLIP;
   clipNode.clip = gfx::RectF(
-      gfx::SizeF(m_rootLayer->GetLayerTree()->device_viewport_size()));
+      gfx::SizeF(m_rootLayer->layer_tree_host()->device_viewport_size()));
   clipNode.transform_id = kRealRootNodeId;
   clipNode.target_transform_id = kRealRootNodeId;
   clipNode.target_effect_id = kSecondaryRootNodeId;
diff --git a/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp b/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
index 442518d..cd3b8ac 100644
--- a/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
+++ b/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
@@ -27,13 +27,13 @@
 
 #include <algorithm>
 #include "platform/HostWindow.h"
-#include "platform/PlatformMouseEvent.h"
 #include "platform/geometry/FloatRect.h"
 #include "platform/graphics/paint/CullRect.h"
 #include "platform/scroll/ScrollAnimatorBase.h"
 #include "platform/scroll/ScrollableArea.h"
 #include "platform/scroll/ScrollbarTheme.h"
 #include "public/platform/WebGestureEvent.h"
+#include "public/platform/WebMouseEvent.h"
 
 namespace blink {
 
@@ -418,7 +418,8 @@
   }
 }
 
-void Scrollbar::mouseMoved(const PlatformMouseEvent& evt) {
+void Scrollbar::mouseMoved(const WebMouseEvent& evt) {
+  IntPoint position = flooredIntPoint(evt.positionInRootFrame());
   if (m_pressedPart == ThumbPart) {
     if (theme().shouldSnapBackToDragOrigin(*this, evt)) {
       if (m_scrollableArea) {
@@ -429,19 +430,20 @@
       }
     } else {
       moveThumb(m_orientation == HorizontalScrollbar
-                    ? convertFromRootFrame(evt.position()).x()
-                    : convertFromRootFrame(evt.position()).y(),
+                    ? convertFromRootFrame(position).x()
+                    : convertFromRootFrame(position).y(),
                 theme().shouldDragDocumentInsteadOfThumb(*this, evt));
     }
     return;
   }
 
-  if (m_pressedPart != NoPart)
+  if (m_pressedPart != NoPart) {
     m_pressedPos = orientation() == HorizontalScrollbar
-                       ? convertFromRootFrame(evt.position()).x()
-                       : convertFromRootFrame(evt.position()).y();
+                       ? convertFromRootFrame(position).x()
+                       : convertFromRootFrame(position).y();
+  }
 
-  ScrollbarPart part = theme().hitTest(*this, evt.position());
+  ScrollbarPart part = theme().hitTest(*this, position);
   if (part != m_hoveredPart) {
     if (m_pressedPart != NoPart) {
       if (part == m_pressedPart) {
@@ -472,7 +474,7 @@
   setHoveredPart(NoPart);
 }
 
-void Scrollbar::mouseUp(const PlatformMouseEvent& mouseEvent) {
+void Scrollbar::mouseUp(const WebMouseEvent& mouseEvent) {
   bool isCaptured = m_pressedPart == ThumbPart;
   setPressedPart(NoPart);
   m_pressedPos = 0;
@@ -483,7 +485,8 @@
     if (isCaptured)
       m_scrollableArea->mouseReleasedScrollbar();
 
-    ScrollbarPart part = theme().hitTest(*this, mouseEvent.position());
+    ScrollbarPart part = theme().hitTest(
+        *this, flooredIntPoint(mouseEvent.positionInRootFrame()));
     if (part == NoPart) {
       setHoveredPart(NoPart);
       m_scrollableArea->mouseExitedScrollbar(*this);
@@ -491,15 +494,16 @@
   }
 }
 
-void Scrollbar::mouseDown(const PlatformMouseEvent& evt) {
+void Scrollbar::mouseDown(const WebMouseEvent& evt) {
   // Early exit for right click
-  if (evt.pointerProperties().button == WebPointerProperties::Button::Right)
+  if (evt.button == WebPointerProperties::Button::Right)
     return;
 
-  setPressedPart(theme().hitTest(*this, evt.position()));
+  IntPoint position = flooredIntPoint(evt.positionInRootFrame());
+  setPressedPart(theme().hitTest(*this, position));
   int pressedPos = orientation() == HorizontalScrollbar
-                       ? convertFromRootFrame(evt.position()).x()
-                       : convertFromRootFrame(evt.position()).y();
+                       ? convertFromRootFrame(position).x()
+                       : convertFromRootFrame(position).y();
 
   if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) &&
       theme().shouldCenterOnThumb(*this, evt)) {
diff --git a/third_party/WebKit/Source/platform/scroll/Scrollbar.h b/third_party/WebKit/Source/platform/scroll/Scrollbar.h
index 6af3ef1..914c9aa 100644
--- a/third_party/WebKit/Source/platform/scroll/Scrollbar.h
+++ b/third_party/WebKit/Source/platform/scroll/Scrollbar.h
@@ -39,10 +39,10 @@
 class GraphicsContext;
 class HostWindow;
 class IntRect;
-class PlatformMouseEvent;
 class ScrollableArea;
 class ScrollbarTheme;
 class WebGestureEvent;
+class WebMouseEvent;
 
 class PLATFORM_EXPORT Scrollbar : public Widget,
                                   public ScrollbarThemeClient,
@@ -145,14 +145,14 @@
   // They will not get called when the mouse went down in a scrollbar, since it
   // is assumed the scrollbar will start
   // grabbing all events in that case anyway.
-  void mouseMoved(const PlatformMouseEvent&);
+  void mouseMoved(const WebMouseEvent&);
   void mouseEntered();
   void mouseExited();
 
   // Used by some platform scrollbars to know when they've been released from
   // capture.
-  void mouseUp(const PlatformMouseEvent&);
-  void mouseDown(const PlatformMouseEvent&);
+  void mouseUp(const WebMouseEvent&);
+  void mouseDown(const WebMouseEvent&);
 
   ScrollbarTheme& theme() const { return m_theme; }
 
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarTheme.cpp b/third_party/WebKit/Source/platform/scroll/ScrollbarTheme.cpp
index 00b2e02..91c71596 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollbarTheme.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollbarTheme.cpp
@@ -25,7 +25,6 @@
 
 #include "platform/scroll/ScrollbarTheme.h"
 
-#include "platform/PlatformMouseEvent.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/graphics/Color.h"
 #include "platform/graphics/GraphicsContext.h"
@@ -39,6 +38,7 @@
 #include "platform/scroll/ScrollbarThemeMock.h"
 #include "platform/scroll/ScrollbarThemeOverlayMock.h"
 #include "public/platform/Platform.h"
+#include "public/platform/WebMouseEvent.h"
 #include "public/platform/WebPoint.h"
 #include "public/platform/WebRect.h"
 #include "public/platform/WebScrollbarBehavior.h"
@@ -219,9 +219,10 @@
 }
 
 bool ScrollbarTheme::shouldCenterOnThumb(const ScrollbarThemeClient& scrollbar,
-                                         const PlatformMouseEvent& evt) {
+                                         const WebMouseEvent& evt) {
   return Platform::current()->scrollbarBehavior()->shouldCenterOnThumb(
-      evt.pointerProperties().button, evt.shiftKey(), evt.altKey());
+      evt.button, evt.modifiers() & WebInputEvent::ShiftKey,
+      evt.modifiers() & WebInputEvent::AltKey);
 }
 
 void ScrollbarTheme::paintTickmarks(GraphicsContext& context,
@@ -270,8 +271,9 @@
 
 bool ScrollbarTheme::shouldSnapBackToDragOrigin(
     const ScrollbarThemeClient& scrollbar,
-    const PlatformMouseEvent& evt) {
-  IntPoint mousePosition = scrollbar.convertFromRootFrame(evt.position());
+    const WebMouseEvent& evt) {
+  IntPoint mousePosition = scrollbar.convertFromRootFrame(
+      flooredIntPoint(evt.positionInRootFrame()));
   mousePosition.move(scrollbar.x(), scrollbar.y());
   return Platform::current()->scrollbarBehavior()->shouldSnapBackToDragOrigin(
       mousePosition, trackRect(scrollbar),
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarTheme.h b/third_party/WebKit/Source/platform/scroll/ScrollbarTheme.h
index 948af56..a7a5f70 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollbarTheme.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollbarTheme.h
@@ -37,7 +37,7 @@
 
 class CullRect;
 class GraphicsContext;
-class PlatformMouseEvent;
+class WebMouseEvent;
 
 class PLATFORM_EXPORT ScrollbarTheme {
   WTF_MAKE_NONCOPYABLE(ScrollbarTheme);
@@ -106,11 +106,11 @@
                               const IntRect&);
 
   virtual bool shouldCenterOnThumb(const ScrollbarThemeClient&,
-                                   const PlatformMouseEvent&);
+                                   const WebMouseEvent&);
   virtual bool shouldSnapBackToDragOrigin(const ScrollbarThemeClient&,
-                                          const PlatformMouseEvent&);
+                                          const WebMouseEvent&);
   virtual bool shouldDragDocumentInsteadOfThumb(const ScrollbarThemeClient&,
-                                                const PlatformMouseEvent&) {
+                                                const WebMouseEvent&) {
     return false;
   }
 
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeAura.cpp b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeAura.cpp
index ce7f749..45c1d47 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeAura.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeAura.cpp
@@ -31,7 +31,6 @@
 #include "platform/scroll/ScrollbarThemeAura.h"
 
 #include "platform/LayoutTestSupport.h"
-#include "platform/PlatformMouseEvent.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/graphics/GraphicsContext.h"
 #include "platform/graphics/paint/DrawingRecorder.h"
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeMac.h b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeMac.h
index 2dd3765..558b170d 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeMac.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeMac.h
@@ -89,7 +89,7 @@
   int maxOverlapBetweenPages() override { return 40; }
 
   bool shouldDragDocumentInsteadOfThumb(const ScrollbarThemeClient&,
-                                        const PlatformMouseEvent&) override;
+                                        const WebMouseEvent&) override;
   int scrollbarPartToHIPressedState(ScrollbarPart);
 
   virtual void updateButtonPlacement(WebScrollbarButtonsPlacement) {}
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeMac.mm b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeMac.mm
index 88c92c3..5fd9bd0d 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeMac.mm
+++ b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeMac.mm
@@ -27,7 +27,6 @@
 #include "platform/scroll/ScrollbarThemeMac.h"
 
 #include <Carbon/Carbon.h>
-#include "platform/PlatformMouseEvent.h"
 #include "platform/graphics/GraphicsContext.h"
 #include "platform/graphics/GraphicsContextStateSaver.h"
 #include "platform/graphics/paint/DrawingRecorder.h"
@@ -36,6 +35,7 @@
 #include "platform/mac/NSScrollerImpDetails.h"
 #include "platform/mac/ScrollAnimatorMac.h"
 #include "platform/scroll/ScrollbarThemeClient.h"
+#include "public/platform/WebMouseEvent.h"
 #include "public/platform/WebThemeEngine.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebRect.h"
@@ -172,8 +172,8 @@
 
 bool ScrollbarThemeMac::shouldDragDocumentInsteadOfThumb(
     const ScrollbarThemeClient&,
-    const PlatformMouseEvent& event) {
-  return event.altKey();
+    const WebMouseEvent& event) {
+  return (event.modifiers() & WebInputEvent::Modifiers::AltKey) != 0;
 }
 
 int ScrollbarThemeMac::scrollbarPartToHIPressedState(ScrollbarPart part) {
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlay.cpp b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlay.cpp
index 14878b96..9753dcc 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlay.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlay.cpp
@@ -25,7 +25,6 @@
 
 #include "platform/scroll/ScrollbarThemeOverlay.h"
 
-#include "platform/PlatformMouseEvent.h"
 #include "platform/graphics/GraphicsContext.h"
 #include "platform/graphics/paint/DrawingRecorder.h"
 #include "platform/scroll/Scrollbar.h"
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlayMock.h b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlayMock.h
index 1022c2b..8f657e4 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlayMock.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlayMock.h
@@ -59,7 +59,7 @@
   }
 
   bool shouldSnapBackToDragOrigin(const ScrollbarThemeClient& scrollbar,
-                                  const PlatformMouseEvent& evt) override {
+                                  const WebMouseEvent& evt) override {
     return false;
   }
 
diff --git a/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp b/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp
index 0a4e6e6..a41b2bea 100644
--- a/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp
+++ b/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp
@@ -53,12 +53,12 @@
 }
 
 void WebLayerTreeViewImplForTesting::setRootLayer(const blink::WebLayer& root) {
-  m_layerTreeHost->GetLayerTree()->SetRootLayer(
+  m_layerTreeHost->SetRootLayer(
       static_cast<const cc_blink::WebLayerImpl*>(&root)->layer());
 }
 
 void WebLayerTreeViewImplForTesting::clearRootLayer() {
-  m_layerTreeHost->GetLayerTree()->SetRootLayer(scoped_refptr<cc::Layer>());
+  m_layerTreeHost->SetRootLayer(scoped_refptr<cc::Layer>());
 }
 
 cc::AnimationHost* WebLayerTreeViewImplForTesting::compositorAnimationHost() {
@@ -70,34 +70,33 @@
     const WebSize& deviceViewportSize) {
   gfx::Size gfxSize(std::max(0, deviceViewportSize.width),
                     std::max(0, deviceViewportSize.height));
-  m_layerTreeHost->GetLayerTree()->SetViewportSize(gfxSize);
+  m_layerTreeHost->SetViewportSize(gfxSize);
 }
 
 void WebLayerTreeViewImplForTesting::setViewportSize(
     const WebSize& deviceViewportSize) {
   gfx::Size gfxSize(std::max(0, deviceViewportSize.width),
                     std::max(0, deviceViewportSize.height));
-  m_layerTreeHost->GetLayerTree()->SetViewportSize(gfxSize);
+  m_layerTreeHost->SetViewportSize(gfxSize);
 }
 
 WebSize WebLayerTreeViewImplForTesting::getViewportSize() const {
-  return WebSize(
-      m_layerTreeHost->GetLayerTree()->device_viewport_size().width(),
-      m_layerTreeHost->GetLayerTree()->device_viewport_size().height());
+  return WebSize(m_layerTreeHost->device_viewport_size().width(),
+                 m_layerTreeHost->device_viewport_size().height());
 }
 
 void WebLayerTreeViewImplForTesting::setDeviceScaleFactor(
     float deviceScaleFactor) {
-  m_layerTreeHost->GetLayerTree()->SetDeviceScaleFactor(deviceScaleFactor);
+  m_layerTreeHost->SetDeviceScaleFactor(deviceScaleFactor);
 }
 
 void WebLayerTreeViewImplForTesting::setBackgroundColor(WebColor color) {
-  m_layerTreeHost->GetLayerTree()->set_background_color(color);
+  m_layerTreeHost->set_background_color(color);
 }
 
 void WebLayerTreeViewImplForTesting::setHasTransparentBackground(
     bool transparent) {
-  m_layerTreeHost->GetLayerTree()->set_has_transparent_background(transparent);
+  m_layerTreeHost->set_has_transparent_background(transparent);
 }
 
 void WebLayerTreeViewImplForTesting::setVisible(bool visible) {
@@ -108,8 +107,8 @@
     float pageScaleFactor,
     float minimum,
     float maximum) {
-  m_layerTreeHost->GetLayerTree()->SetPageScaleFactorAndLimits(
-      pageScaleFactor, minimum, maximum);
+  m_layerTreeHost->SetPageScaleFactorAndLimits(pageScaleFactor, minimum,
+                                               maximum);
 }
 
 void WebLayerTreeViewImplForTesting::startPageScaleAnimation(
@@ -154,7 +153,7 @@
     const blink::WebLayer* pageScaleLayer,
     const blink::WebLayer* innerViewportScrollLayer,
     const blink::WebLayer* outerViewportScrollLayer) {
-  m_layerTreeHost->GetLayerTree()->RegisterViewportLayers(
+  m_layerTreeHost->RegisterViewportLayers(
       // The scroll elasticity layer will only exist when using pinch virtual
       // viewports.
       overscrollElasticityLayer
@@ -174,7 +173,7 @@
 }
 
 void WebLayerTreeViewImplForTesting::clearViewportLayers() {
-  m_layerTreeHost->GetLayerTree()->RegisterViewportLayers(
+  m_layerTreeHost->RegisterViewportLayers(
       scoped_refptr<cc::Layer>(), scoped_refptr<cc::Layer>(),
       scoped_refptr<cc::Layer>(), scoped_refptr<cc::Layer>());
 }
@@ -188,7 +187,7 @@
     blink::WebEventListenerClass eventClass,
     blink::WebEventListenerProperties properties) {
   // Equality of static_cast is checked in render_widget_compositor.cc.
-  m_layerTreeHost->GetLayerTree()->SetEventListenerProperties(
+  m_layerTreeHost->SetEventListenerProperties(
       static_cast<cc::EventListenerClass>(eventClass),
       static_cast<cc::EventListenerProperties>(properties));
 }
@@ -198,17 +197,17 @@
     blink::WebEventListenerClass eventClass) const {
   // Equality of static_cast is checked in render_widget_compositor.cc.
   return static_cast<blink::WebEventListenerProperties>(
-      m_layerTreeHost->GetLayerTree()->event_listener_properties(
+      m_layerTreeHost->event_listener_properties(
           static_cast<cc::EventListenerClass>(eventClass)));
 }
 
 void WebLayerTreeViewImplForTesting::setHaveScrollEventHandlers(
     bool haveEentHandlers) {
-  m_layerTreeHost->GetLayerTree()->SetHaveScrollEventHandlers(haveEentHandlers);
+  m_layerTreeHost->SetHaveScrollEventHandlers(haveEentHandlers);
 }
 
 bool WebLayerTreeViewImplForTesting::haveScrollEventHandlers() const {
-  return m_layerTreeHost->GetLayerTree()->have_scroll_event_handlers();
+  return m_layerTreeHost->have_scroll_event_handlers();
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/text/LocaleMac.mm b/third_party/WebKit/Source/platform/text/LocaleMac.mm
index 16f88a8..11b5ddf0 100644
--- a/third_party/WebKit/Source/platform/text/LocaleMac.mm
+++ b/third_party/WebKit/Source/platform/text/LocaleMac.mm
@@ -124,11 +124,11 @@
   NSArray* array = [shortDateFormatter().get() monthSymbols];
   if ([array count] == 12) {
     for (unsigned i = 0; i < 12; ++i)
-      m_monthLabels.append(String([array objectAtIndex:i]));
+      m_monthLabels.push_back(String([array objectAtIndex:i]));
     return m_monthLabels;
   }
   for (unsigned i = 0; i < WTF_ARRAY_LENGTH(WTF::monthFullName); ++i)
-    m_monthLabels.append(WTF::monthFullName[i]);
+    m_monthLabels.push_back(WTF::monthFullName[i]);
   return m_monthLabels;
 }
 
@@ -139,12 +139,12 @@
   NSArray* array = [shortDateFormatter().get() shortWeekdaySymbols];
   if ([array count] == 7) {
     for (unsigned i = 0; i < 7; ++i)
-      m_weekDayShortLabels.append(String([array objectAtIndex:i]));
+      m_weekDayShortLabels.push_back(String([array objectAtIndex:i]));
     return m_weekDayShortLabels;
   }
   for (unsigned i = 0; i < WTF_ARRAY_LENGTH(WTF::weekdayName); ++i) {
     // weekdayName starts with Monday.
-    m_weekDayShortLabels.append(WTF::weekdayName[(i + 6) % 7]);
+    m_weekDayShortLabels.push_back(WTF::weekdayName[(i + 6) % 7]);
   }
   return m_weekDayShortLabels;
 }
@@ -251,11 +251,11 @@
   NSArray* array = [shortDateFormatter().get() shortMonthSymbols];
   if ([array count] == 12) {
     for (unsigned i = 0; i < 12; ++i)
-      m_shortMonthLabels.append([array objectAtIndex:i]);
+      m_shortMonthLabels.push_back([array objectAtIndex:i]);
     return m_shortMonthLabels;
   }
   for (unsigned i = 0; i < WTF_ARRAY_LENGTH(WTF::monthName); ++i)
-    m_shortMonthLabels.append(WTF::monthName[i]);
+    m_shortMonthLabels.push_back(WTF::monthName[i]);
   return m_shortMonthLabels;
 }
 
@@ -266,7 +266,7 @@
   if ([array count] == 12) {
     m_standAloneMonthLabels.reserveCapacity(12);
     for (unsigned i = 0; i < 12; ++i)
-      m_standAloneMonthLabels.append([array objectAtIndex:i]);
+      m_standAloneMonthLabels.push_back([array objectAtIndex:i]);
     return m_standAloneMonthLabels;
   }
   m_standAloneMonthLabels = shortMonthLabels();
@@ -280,7 +280,7 @@
   if ([array count] == 12) {
     m_shortStandAloneMonthLabels.reserveCapacity(12);
     for (unsigned i = 0; i < 12; ++i)
-      m_shortStandAloneMonthLabels.append([array objectAtIndex:i]);
+      m_shortStandAloneMonthLabels.push_back([array objectAtIndex:i]);
     return m_shortStandAloneMonthLabels;
   }
   m_shortStandAloneMonthLabels = shortMonthLabels();
@@ -292,8 +292,8 @@
     return m_timeAMPMLabels;
   m_timeAMPMLabels.reserveCapacity(2);
   RetainPtr<NSDateFormatter> formatter = shortTimeFormatter();
-  m_timeAMPMLabels.append([formatter.get() AMSymbol]);
-  m_timeAMPMLabels.append([formatter.get() PMSymbol]);
+  m_timeAMPMLabels.push_back([formatter.get() AMSymbol]);
+  m_timeAMPMLabels.push_back([formatter.get() PMSymbol]);
   return m_timeAMPMLabels;
 }
 
@@ -315,11 +315,11 @@
     return;
   Vector<String, DecimalSymbolsSize> symbols;
   for (unsigned i = 0; i < 10; ++i)
-    symbols.append(nineToZero.substring(9 - i, 1));
+    symbols.push_back(nineToZero.substring(9 - i, 1));
   ASSERT(symbols.size() == DecimalSeparatorIndex);
-  symbols.append([formatter.get() decimalSeparator]);
+  symbols.push_back([formatter.get() decimalSeparator]);
   ASSERT(symbols.size() == GroupSeparatorIndex);
-  symbols.append([formatter.get() groupingSeparator]);
+  symbols.push_back([formatter.get() groupingSeparator]);
   ASSERT(symbols.size() == DecimalSymbolsSize);
 
   String positivePrefix([formatter.get() positivePrefix]);
diff --git a/third_party/WebKit/Source/platform/text/LocaleWin.cpp b/third_party/WebKit/Source/platform/text/LocaleWin.cpp
index 919d1b8..071fdc2 100644
--- a/third_party/WebKit/Source/platform/text/LocaleWin.cpp
+++ b/third_party/WebKit/Source/platform/text/LocaleWin.cpp
@@ -148,12 +148,12 @@
   };
   m_shortMonthLabels.reserveCapacity(WTF_ARRAY_LENGTH(types));
   for (unsigned i = 0; i < WTF_ARRAY_LENGTH(types); ++i) {
-    m_shortMonthLabels.append(getLocaleInfoString(types[i]));
+    m_shortMonthLabels.push_back(getLocaleInfoString(types[i]));
     if (m_shortMonthLabels.back().isEmpty()) {
       m_shortMonthLabels.shrink(0);
       m_shortMonthLabels.reserveCapacity(WTF_ARRAY_LENGTH(WTF::monthName));
       for (unsigned m = 0; m < WTF_ARRAY_LENGTH(WTF::monthName); ++m)
-        m_shortMonthLabels.append(WTF::monthName[m]);
+        m_shortMonthLabels.push_back(WTF::monthName[m]);
       return;
     }
   }
@@ -274,12 +274,12 @@
   };
   m_monthLabels.reserveCapacity(WTF_ARRAY_LENGTH(types));
   for (unsigned i = 0; i < WTF_ARRAY_LENGTH(types); ++i) {
-    m_monthLabels.append(getLocaleInfoString(types[i]));
+    m_monthLabels.push_back(getLocaleInfoString(types[i]));
     if (m_monthLabels.back().isEmpty()) {
       m_monthLabels.shrink(0);
       m_monthLabels.reserveCapacity(WTF_ARRAY_LENGTH(WTF::monthFullName));
       for (unsigned m = 0; m < WTF_ARRAY_LENGTH(WTF::monthFullName); ++m)
-        m_monthLabels.append(WTF::monthFullName[m]);
+        m_monthLabels.push_back(WTF::monthFullName[m]);
       return;
     }
   }
@@ -295,13 +295,13 @@
                            LOCALE_SABBREVDAYNAME6};
   m_weekDayShortLabels.reserveCapacity(WTF_ARRAY_LENGTH(types));
   for (unsigned i = 0; i < WTF_ARRAY_LENGTH(types); ++i) {
-    m_weekDayShortLabels.append(getLocaleInfoString(types[i]));
+    m_weekDayShortLabels.push_back(getLocaleInfoString(types[i]));
     if (m_weekDayShortLabels.back().isEmpty()) {
       m_weekDayShortLabels.shrink(0);
       m_weekDayShortLabels.reserveCapacity(WTF_ARRAY_LENGTH(WTF::weekdayName));
       for (unsigned w = 0; w < WTF_ARRAY_LENGTH(WTF::weekdayName); ++w) {
         // weekdayName starts with Monday.
-        m_weekDayShortLabels.append(WTF::weekdayName[(w + 6) % 7]);
+        m_weekDayShortLabels.push_back(WTF::weekdayName[(w + 6) % 7]);
       }
       return;
     }
@@ -419,8 +419,8 @@
 
 const Vector<String>& LocaleWin::timeAMPMLabels() {
   if (m_timeAMPMLabels.isEmpty()) {
-    m_timeAMPMLabels.append(getLocaleInfoString(LOCALE_S1159));
-    m_timeAMPMLabels.append(getLocaleInfoString(LOCALE_S2359));
+    m_timeAMPMLabels.push_back(getLocaleInfoString(LOCALE_S1159));
+    m_timeAMPMLabels.push_back(getLocaleInfoString(LOCALE_S2359));
   }
   return m_timeAMPMLabels;
 }
@@ -438,26 +438,26 @@
   DWORD digitSubstitution = DigitSubstitution0to9;
   getLocaleInfo(LOCALE_IDIGITSUBSTITUTION, digitSubstitution);
   if (digitSubstitution == DigitSubstitution0to9) {
-    symbols.append("0");
-    symbols.append("1");
-    symbols.append("2");
-    symbols.append("3");
-    symbols.append("4");
-    symbols.append("5");
-    symbols.append("6");
-    symbols.append("7");
-    symbols.append("8");
-    symbols.append("9");
+    symbols.push_back("0");
+    symbols.push_back("1");
+    symbols.push_back("2");
+    symbols.push_back("3");
+    symbols.push_back("4");
+    symbols.push_back("5");
+    symbols.push_back("6");
+    symbols.push_back("7");
+    symbols.push_back("8");
+    symbols.push_back("9");
   } else {
     String digits = getLocaleInfoString(LOCALE_SNATIVEDIGITS);
     ASSERT(digits.length() >= 10);
     for (unsigned i = 0; i < 10; ++i)
-      symbols.append(digits.substring(i, 1));
+      symbols.push_back(digits.substring(i, 1));
   }
   ASSERT(symbols.size() == DecimalSeparatorIndex);
-  symbols.append(getLocaleInfoString(LOCALE_SDECIMAL));
+  symbols.push_back(getLocaleInfoString(LOCALE_SDECIMAL));
   ASSERT(symbols.size() == GroupSeparatorIndex);
-  symbols.append(getLocaleInfoString(LOCALE_STHOUSAND));
+  symbols.push_back(getLocaleInfoString(LOCALE_STHOUSAND));
   ASSERT(symbols.size() == DecimalSymbolsSize);
 
   String negativeSign = getLocaleInfoString(LOCALE_SNEGATIVESIGN);
diff --git a/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.cpp b/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.cpp
index ab972fc6..54d24a1 100644
--- a/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.cpp
+++ b/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.cpp
@@ -113,7 +113,7 @@
   for (size_t i = text.length() - minimumSuffixLength - 1;
        i >= minimumPrefixLength; i--) {
     if (result[i])
-      hyphenLocations.append(i);
+      hyphenLocations.push_back(i);
   }
   return hyphenLocations;
 }
diff --git a/third_party/WebKit/Source/web/AssertMatchingEnums.cpp b/third_party/WebKit/Source/web/AssertMatchingEnums.cpp
index dbfbb05a..3518f80 100644
--- a/third_party/WebKit/Source/web/AssertMatchingEnums.cpp
+++ b/third_party/WebKit/Source/web/AssertMatchingEnums.cpp
@@ -66,7 +66,7 @@
 #include "platform/Cursor.h"
 #include "platform/FileMetadata.h"
 #include "platform/FileSystemType.h"
-#include "platform/PlatformMouseEvent.h"
+#include "platform/PlatformEvent.h"
 #include "platform/fonts/FontDescription.h"
 #include "platform/fonts/FontSmoothingMode.h"
 #include "platform/mediastream/MediaStreamSource.h"
diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp
index 683027a..f54da40 100644
--- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp
+++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp
@@ -529,7 +529,8 @@
       isBackForwardLoadType(toWebLocalFrameImpl(m_webFrame->parent())
                                 ->frame()
                                 ->loader()
-                                .loadType()) &&
+                                .documentLoader()
+                                ->loadType()) &&
       !toWebLocalFrameImpl(m_webFrame->parent())
            ->frame()
            ->document()
diff --git a/third_party/WebKit/Source/web/InspectorOverlay.cpp b/third_party/WebKit/Source/web/InspectorOverlay.cpp
index 210ddea..4c14f47 100644
--- a/third_party/WebKit/Source/web/InspectorOverlay.cpp
+++ b/third_party/WebKit/Source/web/InspectorOverlay.cpp
@@ -89,9 +89,11 @@
 }
 
 Node* hoveredNodeForEvent(LocalFrame* frame,
-                          const PlatformMouseEvent& event,
+                          const WebMouseEvent& event,
                           bool ignorePointerEventsNone) {
-  return hoveredNodeForPoint(frame, event.position(), ignorePointerEventsNone);
+  return hoveredNodeForPoint(frame,
+                             roundedIntPoint(event.positionInRootFrame()),
+                             ignorePointerEventsNone);
 }
 
 Node* hoveredNodeForEvent(LocalFrame* frame,
@@ -245,33 +247,30 @@
 
     overlayMainFrame()->eventHandler().handleGestureEvent(transformedEvent);
   }
-  if (WebInputEvent::isMouseEventType(inputEvent.type()) &&
-      inputEvent.type() != WebInputEvent::MouseEnter) {
-    // PlatformMouseEventBuilder does not work with MouseEnter type, so we
-    // filter it out manually.
-    PlatformMouseEvent mouseEvent = PlatformMouseEventBuilder(
-        m_frameImpl->frameView(),
-        static_cast<const WebMouseEvent&>(inputEvent));
+  if (WebInputEvent::isMouseEventType(inputEvent.type())) {
+    WebMouseEvent mouseEvent =
+        TransformWebMouseEvent(m_frameImpl->frameView(),
+                               static_cast<const WebMouseEvent&>(inputEvent));
 
-    if (mouseEvent.type() == PlatformEvent::MouseMoved)
+    if (mouseEvent.type() == WebInputEvent::MouseMove)
       handled = handleMouseMove(mouseEvent);
-    else if (mouseEvent.type() == PlatformEvent::MousePressed)
+    else if (mouseEvent.type() == WebInputEvent::MouseDown)
       handled = handleMousePress();
 
     if (handled)
       return true;
 
-    if (mouseEvent.type() == PlatformEvent::MouseMoved) {
+    if (mouseEvent.type() == WebInputEvent::MouseMove) {
       handled = overlayMainFrame()->eventHandler().handleMouseMoveEvent(
-                    mouseEvent, createPlatformMouseEventVector(
+                    mouseEvent, TransformWebMouseEventVector(
                                     m_frameImpl->frameView(),
                                     std::vector<const WebInputEvent*>())) !=
                 WebInputEventResult::NotHandled;
     }
-    if (mouseEvent.type() == PlatformEvent::MousePressed)
+    if (mouseEvent.type() == WebInputEvent::MouseDown)
       handled = overlayMainFrame()->eventHandler().handleMousePressEvent(
                     mouseEvent) != WebInputEventResult::NotHandled;
-    if (mouseEvent.type() == PlatformEvent::MouseReleased)
+    if (mouseEvent.type() == WebInputEvent::MouseUp)
       handled = overlayMainFrame()->eventHandler().handleMouseReleaseEvent(
                     mouseEvent) != WebInputEventResult::NotHandled;
   }
@@ -706,14 +705,15 @@
   m_drawViewSize = show;
 }
 
-bool InspectorOverlay::handleMouseMove(const PlatformMouseEvent& event) {
+bool InspectorOverlay::handleMouseMove(const WebMouseEvent& event) {
   if (!shouldSearchForNode())
     return false;
 
   LocalFrame* frame = m_frameImpl->frame();
   if (!frame || !frame->view() || frame->contentLayoutItem().isNull())
     return false;
-  Node* node = hoveredNodeForEvent(frame, event, event.shiftKey());
+  Node* node = hoveredNodeForEvent(frame, event,
+                                   event.modifiers() & WebInputEvent::ShiftKey);
 
   // Do not highlight within user agent shadow root unless requested.
   if (m_inspectMode != InspectorDOMAgent::SearchingForUAShadow) {
@@ -729,8 +729,9 @@
   if (!node)
     return true;
 
-  Node* eventTarget =
-      event.shiftKey() ? hoveredNodeForEvent(frame, event, false) : nullptr;
+  Node* eventTarget = (event.modifiers() & WebInputEvent::ShiftKey)
+                          ? hoveredNodeForEvent(frame, event, false)
+                          : nullptr;
   if (eventTarget == node)
     eventTarget = nullptr;
 
@@ -739,7 +740,8 @@
     if (m_domAgent)
       m_domAgent->nodeHighlightedInOverlay(node);
     highlightNode(node, eventTarget, *m_inspectModeHighlightConfig,
-                  event.ctrlKey() || event.metaKey());
+                  (event.modifiers() &
+                   (WebInputEvent::ControlKey | WebInputEvent::MetaKey)));
   }
   return true;
 }
diff --git a/third_party/WebKit/Source/web/InspectorOverlay.h b/third_party/WebKit/Source/web/InspectorOverlay.h
index a03cb44..7276894c 100644
--- a/third_party/WebKit/Source/web/InspectorOverlay.h
+++ b/third_party/WebKit/Source/web/InspectorOverlay.h
@@ -50,8 +50,8 @@
 class Node;
 class Page;
 class PageOverlay;
-class PlatformMouseEvent;
 class WebGestureEvent;
+class WebMouseEvent;
 class WebLocalFrameImpl;
 class WebTouchEvent;
 
@@ -133,7 +133,7 @@
   bool handleMousePress();
   bool handleGestureEvent(const WebGestureEvent&);
   bool handleTouchEvent(const WebTouchEvent&);
-  bool handleMouseMove(const PlatformMouseEvent&);
+  bool handleMouseMove(const WebMouseEvent&);
   bool shouldSearchForNode();
   void inspect(Node*);
 
diff --git a/third_party/WebKit/Source/web/PageWidgetDelegate.cpp b/third_party/WebKit/Source/web/PageWidgetDelegate.cpp
index bdc5f91..a0fbb325 100644
--- a/third_party/WebKit/Source/web/PageWidgetDelegate.cpp
+++ b/third_party/WebKit/Source/web/PageWidgetDelegate.cpp
@@ -119,10 +119,11 @@
   const WebInputEvent& event = coalescedEvent.event();
   if (event.modifiers() & WebInputEvent::IsTouchAccessibility &&
       WebInputEvent::isMouseEventType(event.type())) {
-    PlatformMouseEventBuilder pme(root->view(),
-                                  static_cast<const WebMouseEvent&>(event));
+    WebMouseEvent mouseEvent = TransformWebMouseEvent(
+        root->view(), static_cast<const WebMouseEvent&>(event));
 
-    IntPoint docPoint(root->view()->rootFrameToContents(pme.position()));
+    IntPoint docPoint(root->view()->rootFrameToContents(
+        flooredIntPoint(mouseEvent.positionInRootFrame())));
     HitTestResult result = root->eventHandler().hitTestResultAtPoint(
         docPoint, HitTestRequest::ReadOnly | HitTestRequest::Active);
     result.setToShadowHostIfInUserAgentShadowRoot();
@@ -225,27 +226,32 @@
     LocalFrame& mainFrame,
     const WebMouseEvent& event,
     const std::vector<const WebInputEvent*>& coalescedEvents) {
+  WebMouseEvent transformedEvent =
+      TransformWebMouseEvent(mainFrame.view(), event);
   mainFrame.eventHandler().handleMouseMoveEvent(
-      PlatformMouseEventBuilder(mainFrame.view(), event),
-      createPlatformMouseEventVector(mainFrame.view(), coalescedEvents));
+      transformedEvent,
+      TransformWebMouseEventVector(mainFrame.view(), coalescedEvents));
 }
 
 void PageWidgetEventHandler::handleMouseLeave(LocalFrame& mainFrame,
                                               const WebMouseEvent& event) {
-  mainFrame.eventHandler().handleMouseLeaveEvent(
-      PlatformMouseEventBuilder(mainFrame.view(), event));
+  WebMouseEvent transformedEvent =
+      TransformWebMouseEvent(mainFrame.view(), event);
+  mainFrame.eventHandler().handleMouseLeaveEvent(transformedEvent);
 }
 
 void PageWidgetEventHandler::handleMouseDown(LocalFrame& mainFrame,
                                              const WebMouseEvent& event) {
-  mainFrame.eventHandler().handleMousePressEvent(
-      PlatformMouseEventBuilder(mainFrame.view(), event));
+  WebMouseEvent transformedEvent =
+      TransformWebMouseEvent(mainFrame.view(), event);
+  mainFrame.eventHandler().handleMousePressEvent(transformedEvent);
 }
 
 void PageWidgetEventHandler::handleMouseUp(LocalFrame& mainFrame,
                                            const WebMouseEvent& event) {
-  mainFrame.eventHandler().handleMouseReleaseEvent(
-      PlatformMouseEventBuilder(mainFrame.view(), event));
+  WebMouseEvent transformedEvent =
+      TransformWebMouseEvent(mainFrame.view(), event);
+  mainFrame.eventHandler().handleMouseReleaseEvent(transformedEvent);
 }
 
 WebInputEventResult PageWidgetEventHandler::handleMouseWheel(
diff --git a/third_party/WebKit/Source/web/PopupMenuImpl.cpp b/third_party/WebKit/Source/web/PopupMenuImpl.cpp
index 7b2b88f..97bf482 100644
--- a/third_party/WebKit/Source/web/PopupMenuImpl.cpp
+++ b/third_party/WebKit/Source/web/PopupMenuImpl.cpp
@@ -446,7 +446,9 @@
   // We dispatch events on the owner element to match the legacy behavior.
   // Other browsers dispatch click events before and after showing the popup.
   if (m_ownerElement) {
-    PlatformMouseEvent event;
+    // TODO(dtapuska): Why is this event positionless?
+    WebMouseEvent event;
+    event.setFrameScale(1);
     Element* owner = &ownerElement();
     owner->dispatchMouseEvent(event, EventTypeNames::mouseup);
     owner->dispatchMouseEvent(event, EventTypeNames::click);
diff --git a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
index 8ff5670..2f1df5b 100644
--- a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
+++ b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
@@ -540,9 +540,9 @@
                            WTF::monotonicallyIncreasingTimeMS());
   dummyEvent.x = pointInRootFrame.x;
   dummyEvent.y = pointInRootFrame.y;
-  IntPoint transformedPoint =
-      PlatformMouseEventBuilder(m_webLocalFrameImpl->frameView(), dummyEvent)
-          .position();
+  IntPoint transformedPoint = flooredIntPoint(
+      TransformWebMouseEvent(m_webLocalFrameImpl->frameView(), dummyEvent)
+          .positionInRootFrame());
   HitTestResult result(
       request,
       m_webLocalFrameImpl->frameView()->rootFrameToContents(transformedPoint));
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetBase.cpp b/third_party/WebKit/Source/web/WebFrameWidgetBase.cpp
index 00a0c734..5a34a0e 100644
--- a/third_party/WebKit/Source/web/WebFrameWidgetBase.cpp
+++ b/third_party/WebKit/Source/web/WebFrameWidgetBase.cpp
@@ -131,16 +131,19 @@
     cancelDrag();
     return;
   }
-  WebPoint pointInRootFrame(
+  WebFloatPoint pointInRootFrame(
       page()->frameHost().visualViewport().viewportToRootFrame(
           pointInViewport));
-  PlatformMouseEvent pme(
-      pointInRootFrame, screenPoint, WebPointerProperties::Button::Left,
-      PlatformEvent::MouseMoved, 0, PlatformEvent::NoModifiers,
-      PlatformMouseEvent::RealOrIndistinguishable, TimeTicks::Now());
+
+  WebMouseEvent fakeMouseMove(WebInputEvent::MouseMove, pointInRootFrame,
+                              WebFloatPoint(screenPoint.x, screenPoint.y),
+                              WebPointerProperties::Button::Left, 0,
+                              PlatformEvent::NoModifiers,
+                              TimeTicks::Now().InSeconds());
+  fakeMouseMove.setFrameScale(1);
   toCoreFrame(localRoot())
       ->eventHandler()
-      .dragSourceEndedAt(pme, static_cast<DragOperation>(operation));
+      .dragSourceEndedAt(fakeMouseMove, static_cast<DragOperation>(operation));
 }
 
 void WebFrameWidgetBase::dragSourceSystemDragEnded() {
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
index 563b887b6..b015b9b 100644
--- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
+++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
@@ -372,11 +372,11 @@
         NOTREACHED();
     }
 
-    node->dispatchMouseEvent(
-        PlatformMouseEventBuilder(
-            m_localRoot->frameView(),
-            static_cast<const WebMouseEvent&>(inputEvent)),
-        eventType, static_cast<const WebMouseEvent&>(inputEvent).clickCount);
+    WebMouseEvent transformedEvent =
+        TransformWebMouseEvent(m_localRoot->frameView(),
+                               static_cast<const WebMouseEvent&>(inputEvent));
+    node->dispatchMouseEvent(transformedEvent, eventType,
+                             transformedEvent.clickCount);
     return WebInputEventResult::HandledSystem;
   }
 
@@ -776,10 +776,13 @@
 void WebFrameWidgetImpl::mouseContextMenu(const WebMouseEvent& event) {
   page()->contextMenuController().clearContextMenu();
 
-  PlatformMouseEventBuilder pme(m_localRoot->frameView(), event);
+  WebMouseEvent transformedEvent =
+      TransformWebMouseEvent(m_localRoot->frameView(), event);
+  IntPoint positionInRootFrame =
+      flooredIntPoint(transformedEvent.positionInRootFrame());
 
   // Find the right target frame. See issue 1186900.
-  HitTestResult result = hitTestResultForRootFramePos(pme.position());
+  HitTestResult result = hitTestResultForRootFramePos(positionInRootFrame);
   Frame* targetFrame;
   if (result.innerNodeOrImageMapImage())
     targetFrame = result.innerNodeOrImageMapImage()->document().frame();
@@ -801,7 +804,8 @@
 
   {
     ContextMenuAllowedScope scope;
-    targetLocalFrame->eventHandler().sendContextMenuEvent(pme, nullptr);
+    targetLocalFrame->eventHandler().sendContextMenuEvent(transformedEvent,
+                                                          nullptr);
   }
   // Actually showing the context menu is handled by the ContextMenuClient
   // implementation...
diff --git a/third_party/WebKit/Source/web/WebInputEventConversion.cpp b/third_party/WebKit/Source/web/WebInputEventConversion.cpp
index aed825c..4c58568 100644
--- a/third_party/WebKit/Source/web/WebInputEventConversion.cpp
+++ b/third_party/WebKit/Source/web/WebInputEventConversion.cpp
@@ -85,54 +85,6 @@
           overscrollOffset.height());
 }
 
-float scaleDeltaToWindow(const Widget* widget, float delta) {
-  return delta / frameScale(widget);
-}
-
-// This method converts from the renderer's coordinate space into Blink's root
-// frame coordinate space.  It's somewhat unique in that it takes into account
-// DevTools emulation, which applies a scale and offset in the root layer (see
-// updateRootLayerTransform in WebViewImpl) as well as the overscroll effect on
-// OSX.  This is in addition to the visual viewport "pinch-zoom" transformation
-// and is one of the few cases where the visual viewport is not equal to the
-// renderer's coordinate-space.
-FloatPoint convertHitPointToRootFrame(const Widget* widget,
-                                      FloatPoint pointInRendererViewport) {
-  float scale = 1;
-  IntSize offset;
-  IntPoint visualViewport;
-  FloatSize overscrollOffset;
-  if (widget) {
-    FrameView* rootView = toFrameView(widget->root());
-    if (rootView) {
-      scale = rootView->inputEventsScaleFactor();
-      offset = rootView->inputEventsOffsetForEmulation();
-      visualViewport = flooredIntPoint(rootView->page()
-                                           ->frameHost()
-                                           .visualViewport()
-                                           .visibleRect()
-                                           .location());
-      overscrollOffset =
-          rootView->page()->frameHost().chromeClient().elasticOverscroll();
-    }
-  }
-  return FloatPoint((pointInRendererViewport.x() - offset.width()) / scale +
-                        visualViewport.x() + overscrollOffset.width(),
-                    (pointInRendererViewport.y() - offset.height()) / scale +
-                        visualViewport.y() + overscrollOffset.height());
-}
-
-unsigned toPlatformModifierFrom(WebMouseEvent::Button button) {
-  if (button == WebMouseEvent::Button::NoButton)
-    return 0;
-
-  unsigned webMouseButtonToPlatformModifier[] = {
-      PlatformEvent::LeftButtonDown, PlatformEvent::MiddleButtonDown,
-      PlatformEvent::RightButtonDown};
-
-  return webMouseButtonToPlatformModifier[static_cast<int>(button)];
-}
-
 FloatPoint convertAbsoluteLocationForLayoutObjectFloat(
     const DoublePoint& location,
     const LayoutItem layoutItem) {
@@ -172,51 +124,40 @@
   webEvent.y = localPoint.y();
 }
 
+unsigned toWebInputEventModifierFrom(WebMouseEvent::Button button) {
+  if (button == WebMouseEvent::Button::NoButton)
+    return 0;
+
+  unsigned webMouseButtonToPlatformModifier[] = {
+      WebInputEvent::LeftButtonDown, WebInputEvent::MiddleButtonDown,
+      WebInputEvent::RightButtonDown};
+
+  return webMouseButtonToPlatformModifier[static_cast<int>(button)];
+}
+
 }  // namespace
 
-// MakePlatformMouseEvent -----------------------------------------------------
+WebMouseEvent TransformWebMouseEvent(Widget* widget,
+                                     const WebMouseEvent& event) {
+  WebMouseEvent result = event;
 
-// TODO(mustaq): Add tests for this.
-PlatformMouseEventBuilder::PlatformMouseEventBuilder(Widget* widget,
-                                                     const WebMouseEvent& e) {
-  // FIXME: Widget is always toplevel, unless it's a popup. We may be able
-  // to get rid of this once we abstract popups into a WebKit API.
-  m_position = widget->convertFromRootFrame(
-      flooredIntPoint(convertHitPointToRootFrame(widget, IntPoint(e.x, e.y))));
-  m_globalPosition = IntPoint(e.globalX, e.globalY);
-  m_movementDelta = IntPoint(scaleDeltaToWindow(widget, e.movementX),
-                             scaleDeltaToWindow(widget, e.movementY));
-  m_modifiers = e.modifiers();
-
-  m_timestamp = TimeTicks::FromSeconds(e.timeStampSeconds());
-  m_clickCount = e.clickCount;
-
-  m_pointerProperties = static_cast<WebPointerProperties>(e);
-
-  switch (e.type()) {
-    case WebInputEvent::MouseMove:
-    case WebInputEvent::MouseEnter:  // synthesize a move event
-    case WebInputEvent::MouseLeave:  // synthesize a move event
-      m_type = PlatformEvent::MouseMoved;
-      break;
-
-    case WebInputEvent::MouseDown:
-      m_type = PlatformEvent::MousePressed;
-      break;
-
-    case WebInputEvent::MouseUp:
-      m_type = PlatformEvent::MouseReleased;
-
-      // The MouseEvent spec requires that buttons indicates the state
-      // immediately after the event takes place. To ensure consistency
-      // between platforms here, we explicitly clear the button that is
-      // in the process of being released.
-      m_modifiers &= ~toPlatformModifierFrom(e.button);
-      break;
-
-    default:
-      NOTREACHED();
+  // TODO(dtapuska): Remove this translation. In the past blink has
+  // converted leaves into moves and not known about leaves. It should
+  // be educated about them. crbug.com/686196
+  if (event.type() == WebInputEvent::MouseEnter ||
+      event.type() == WebInputEvent::MouseLeave) {
+    result.setType(WebInputEvent::MouseMove);
   }
+
+  // TODO(dtapuska): Perhaps the event should be constructed correctly?
+  // crbug.com/686200
+  if (event.type() == WebInputEvent::MouseUp) {
+    result.setModifiers(event.modifiers() &
+                        ~toWebInputEventModifierFrom(event.button));
+  }
+  result.setFrameScale(frameScale(widget));
+  result.setFrameTranslate(frameTranslation(widget));
+  return result;
 }
 
 WebMouseWheelEvent TransformWebMouseWheelEvent(
@@ -258,6 +199,21 @@
 WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget,
                                            const LayoutItem layoutItem,
                                            const MouseEvent& event) {
+  if (event.nativeEvent()) {
+    *static_cast<WebMouseEvent*>(this) =
+        event.nativeEvent()->flattenTransform();
+    WebFloatPoint absoluteRootFrameLocation = positionInRootFrame();
+    IntPoint localPoint = roundedIntPoint(
+        layoutItem.absoluteToLocal(absoluteRootFrameLocation, UseTransforms));
+    x = localPoint.x();
+    y = localPoint.y();
+    return;
+  }
+
+  // Code below here can be removed once OOPIF ships.
+  // OOPIF will prevent synthetic events being dispatched into
+  // other frames; but for now we allow the fallback to generate
+  // WebMouseEvents from synthetic events.
   if (event.type() == EventTypeNames::mousemove)
     m_type = WebInputEvent::MouseMove;
   else if (event.type() == EventTypeNames::mouseout)
@@ -308,8 +264,6 @@
   clickCount = event.detail();
 
   pointerType = WebPointerProperties::PointerType::Mouse;
-  if (event.mouseEvent())
-    pointerType = event.mouseEvent()->pointerProperties().pointerType;
 }
 
 // Generate a synthetic WebMouseEvent given a TouchEvent (eg. for emulating a
@@ -396,13 +350,13 @@
   windowsKeyCode = event.keyCode();
 }
 
-Vector<PlatformMouseEvent> createPlatformMouseEventVector(
+Vector<WebMouseEvent> TransformWebMouseEventVector(
     Widget* widget,
     const std::vector<const WebInputEvent*>& coalescedEvents) {
-  Vector<PlatformMouseEvent> result;
+  Vector<WebMouseEvent> result;
   for (const auto& event : coalescedEvents) {
     DCHECK(WebInputEvent::isMouseEventType(event->type()));
-    result.push_back(PlatformMouseEventBuilder(
+    result.push_back(TransformWebMouseEvent(
         widget, static_cast<const WebMouseEvent&>(*event)));
   }
   return result;
diff --git a/third_party/WebKit/Source/web/WebInputEventConversion.h b/third_party/WebKit/Source/web/WebInputEventConversion.h
index f2972ec..0d48783 100644
--- a/third_party/WebKit/Source/web/WebInputEventConversion.h
+++ b/third_party/WebKit/Source/web/WebInputEventConversion.h
@@ -31,7 +31,6 @@
 #ifndef WebInputEventConversion_h
 #define WebInputEventConversion_h
 
-#include "platform/PlatformMouseEvent.h"
 #include "platform/scroll/ScrollTypes.h"
 #include "public/platform/WebInputEvent.h"
 #include "public/platform/WebKeyboardEvent.h"
@@ -48,19 +47,12 @@
 class LayoutItem;
 class TouchEvent;
 class WebGestureEvent;
-class WebMouseEvent;
 class WebKeyboardEvent;
-class WebTouchEvent;
 class Widget;
 
 // These classes are used to convert from WebInputEvent subclasses to
 // corresponding WebCore events.
 
-class WEB_EXPORT PlatformMouseEventBuilder
-    : NON_EXPORTED_BASE(public PlatformMouseEvent) {
- public:
-  PlatformMouseEventBuilder(Widget*, const WebMouseEvent&);
-};
 
 class WEB_EXPORT WebMouseEventBuilder
     : NON_EXPORTED_BASE(public WebMouseEvent) {
@@ -96,14 +88,15 @@
 // and translation.
 WEB_EXPORT WebGestureEvent TransformWebGestureEvent(Widget*,
                                                     const WebGestureEvent&);
+WEB_EXPORT WebMouseEvent TransformWebMouseEvent(Widget*, const WebMouseEvent&);
+
 WEB_EXPORT WebMouseWheelEvent
 TransformWebMouseWheelEvent(Widget*, const WebMouseWheelEvent&);
 
 WEB_EXPORT WebTouchEvent TransformWebTouchEvent(Widget*, const WebTouchEvent&);
 
-Vector<PlatformMouseEvent> WEB_EXPORT
-createPlatformMouseEventVector(Widget*,
-                               const std::vector<const WebInputEvent*>&);
+Vector<WebMouseEvent> WEB_EXPORT
+TransformWebMouseEventVector(Widget*, const std::vector<const WebInputEvent*>&);
 Vector<WebTouchEvent> WEB_EXPORT
 TransformWebTouchEventVector(Widget*, const std::vector<const WebInputEvent*>&);
 
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
index 3485341..f20abcf5 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -1631,7 +1631,7 @@
   // If we're moving in the back/forward list, we might want to replace the
   // content of this child frame with whatever was there at that point.
   HistoryItem* childItem = nullptr;
-  if (isBackForwardLoadType(frame()->loader().loadType()) &&
+  if (isBackForwardLoadType(frame()->loader().documentLoader()->loadType()) &&
       !frame()->document()->loadEventFinished())
     childItem = webframeChild->client()->historyItemForNewChildFrame();
 
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
index 865ab97..00617d0 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -706,16 +706,16 @@
   // in the call to HandleEvent. See http://b/issue?id=1362948
   FrameView* parentView = toFrameView(parent());
 
-  WebMouseEventBuilder webEvent(this, LayoutItem(m_element->layoutObject()),
-                                *event);
-  if (webEvent.type() == WebInputEvent::Undefined)
+  WebMouseEventBuilder transformedEvent(
+      this, LayoutItem(m_element->layoutObject()), *event);
+  if (transformedEvent.type() == WebInputEvent::Undefined)
     return;
 
   if (event->type() == EventTypeNames::mousedown)
     focusPlugin();
 
   WebCursorInfo cursorInfo;
-  if (m_webPlugin->handleInputEvent(webEvent, cursorInfo) !=
+  if (m_webPlugin->handleInputEvent(transformedEvent, cursorInfo) !=
       WebInputEventResult::NotHandled)
     event->setDefaultHandled();
 
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp
index fe11916..ddc23b9 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -97,7 +97,6 @@
 #include "platform/Cursor.h"
 #include "platform/Histogram.h"
 #include "platform/KeyboardCodes.h"
-#include "platform/PlatformMouseEvent.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/UserGestureIndicator.h"
 #include "platform/animation/CompositorAnimationHost.h"
@@ -556,10 +555,13 @@
 
   m_page->contextMenuController().clearContextMenu();
 
-  PlatformMouseEventBuilder pme(mainFrameImpl()->frameView(), event);
+  WebMouseEvent transformedEvent =
+      TransformWebMouseEvent(mainFrameImpl()->frameView(), event);
+  IntPoint positionInRootFrame =
+      flooredIntPoint(transformedEvent.positionInRootFrame());
 
   // Find the right target frame. See issue 1186900.
-  HitTestResult result = hitTestResultForRootFramePos(pme.position());
+  HitTestResult result = hitTestResultForRootFramePos(positionInRootFrame);
   Frame* targetFrame;
   if (result.innerNodeOrImageMapImage())
     targetFrame = result.innerNodeOrImageMapImage()->document().frame();
@@ -577,7 +579,8 @@
 
   {
     ContextMenuAllowedScope scope;
-    targetLocalFrame->eventHandler().sendContextMenuEvent(pme, nullptr);
+    targetLocalFrame->eventHandler().sendContextMenuEvent(transformedEvent,
+                                                          nullptr);
   }
   // Actually showing the context menu is handled by the ContextMenuClient
   // implementation...
@@ -2189,11 +2192,11 @@
         NOTREACHED();
     }
 
-    node->dispatchMouseEvent(
-        PlatformMouseEventBuilder(
-            mainFrameImpl()->frameView(),
-            static_cast<const WebMouseEvent&>(inputEvent)),
-        eventType, static_cast<const WebMouseEvent&>(inputEvent).clickCount);
+    WebMouseEvent transformedEvent =
+        TransformWebMouseEvent(mainFrameImpl()->frameView(),
+                               static_cast<const WebMouseEvent&>(inputEvent));
+    node->dispatchMouseEvent(transformedEvent, eventType,
+                             transformedEvent.clickCount);
     return WebInputEventResult::HandledSystem;
   }
 
@@ -4125,10 +4128,12 @@
 
   const WebMouseEvent& mouseEvent = static_cast<const WebMouseEvent&>(event);
 
-  if (page())
-    page()->pointerLockController().dispatchLockedMouseEvent(
-        PlatformMouseEventBuilder(mainFrameImpl()->frameView(), mouseEvent),
-        eventType);
+  if (page()) {
+    WebMouseEvent transformedEvent =
+        TransformWebMouseEvent(mainFrameImpl()->frameView(), mouseEvent);
+    page()->pointerLockController().dispatchLockedMouseEvent(transformedEvent,
+                                                             eventType);
+  }
 }
 
 void WebViewImpl::forceNextWebGLContextCreationToFail() {
diff --git a/third_party/WebKit/Source/web/tests/ProgrammaticScrollTest.cpp b/third_party/WebKit/Source/web/tests/ProgrammaticScrollTest.cpp
index e15730c..13e15a6a 100644
--- a/third_party/WebKit/Source/web/tests/ProgrammaticScrollTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ProgrammaticScrollTest.cpp
@@ -50,7 +50,7 @@
 
   WebViewImpl* webViewImpl = toWebViewImpl(webView);
   FrameLoader& loader = webViewImpl->mainFrameImpl()->frame()->loader();
-  loader.setLoadType(FrameLoadTypeBackForward);
+  loader.documentLoader()->setLoadType(FrameLoadTypeBackForward);
 
   webViewImpl->setPageScaleFactor(3.0f);
   webViewImpl->mainFrame()->setScrollOffset(WebSize(0, 500));
@@ -80,7 +80,7 @@
 
   WebViewImpl* webViewImpl = toWebViewImpl(webView);
   FrameLoader& loader = webViewImpl->mainFrameImpl()->frame()->loader();
-  loader.setLoadType(FrameLoadTypeBackForward);
+  loader.documentLoader()->setLoadType(FrameLoadTypeBackForward);
 
   webViewImpl->setPageScaleFactor(3.0f);
   webViewImpl->mainFrame()->setScrollOffset(WebSize(0, 500));
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index 70d4e1f8d..d123a03 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -79,7 +79,6 @@
 #include "modules/mediastream/MediaStreamRegistry.h"
 #include "platform/Cursor.h"
 #include "platform/DragImage.h"
-#include "platform/PlatformMouseEvent.h"
 #include "platform/PlatformResourceLoader.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/UserGestureIndicator.h"
@@ -6873,10 +6872,12 @@
   KURL destination = document->url();
   destination.setFragmentIdentifier("test");
 
-  Event* event = MouseEvent::create(
-      EventTypeNames::click, false, false, document->domWindow(), 0, 0, 0, 0, 0,
-      0, 0, PlatformEvent::NoModifiers, 1, 0, nullptr, TimeTicks(),
-      PlatformMouseEvent::RealOrIndistinguishable, String(), nullptr);
+  MouseEventInit mouseInitializer;
+  mouseInitializer.setView(document->domWindow());
+  mouseInitializer.setButton(1);
+
+  Event* event =
+      MouseEvent::create(nullptr, EventTypeNames::click, mouseInitializer);
   FrameLoadRequest frameRequest(document, ResourceRequest(destination));
   frameRequest.setTriggeringEvent(event);
   toLocalFrame(webViewHelper.webView()->page()->mainFrame())
@@ -6928,10 +6929,13 @@
   KURL destination = toKURL(m_baseURL + "hello_world.html");
 
   // ctrl+click event
-  Event* event = MouseEvent::create(
-      EventTypeNames::click, false, false, document->domWindow(), 0, 0, 0, 0, 0,
-      0, 0, PlatformEvent::CtrlKey, 0, 0, nullptr, TimeTicks(),
-      PlatformMouseEvent::RealOrIndistinguishable, String(), nullptr);
+  MouseEventInit mouseInitializer;
+  mouseInitializer.setView(document->domWindow());
+  mouseInitializer.setButton(1);
+  mouseInitializer.setCtrlKey(true);
+
+  Event* event =
+      MouseEvent::create(nullptr, EventTypeNames::click, mouseInitializer);
   FrameLoadRequest frameRequest(document, ResourceRequest(destination));
   frameRequest.setTriggeringEvent(event);
   UserGestureIndicator gesture(DocumentUserGestureToken::create(document));
@@ -7155,7 +7159,8 @@
       : m_frameLoadTypeReloadMainResourceSeen(false) {}
 
   virtual void willSendRequest(WebLocalFrame* frame, WebURLRequest&) {
-    if (toWebLocalFrameImpl(frame)->frame()->loader().loadType() ==
+    FrameLoader& frameLoader = toWebLocalFrameImpl(frame)->frame()->loader();
+    if (frameLoader.provisionalDocumentLoader()->loadType() ==
         FrameLoadTypeReloadMainResource)
       m_frameLoadTypeReloadMainResourceSeen = true;
   }
@@ -10794,13 +10799,15 @@
   EXPECT_TRUE(hitTestResult.innerElement());
 
   // Mouse over link. Mouse cursor should be hand.
-  PlatformMouseEvent mouseMoveOverLinkEvent(
-      IntPoint(div1Tag->offsetLeft() + 5, div1Tag->offsetTop() + 5),
-      IntPoint(div1Tag->offsetLeft() + 5, div1Tag->offsetTop() + 5),
-      WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, 0,
-      PlatformEvent::NoModifiers, TimeTicks::Now());
+  WebMouseEvent mouseMoveOverLinkEvent(
+      WebInputEvent::MouseMove,
+      WebFloatPoint(div1Tag->offsetLeft() + 5, div1Tag->offsetTop() + 5),
+      WebFloatPoint(div1Tag->offsetLeft() + 5, div1Tag->offsetTop() + 5),
+      WebPointerProperties::Button::NoButton, 0, WebInputEvent::NoModifiers,
+      TimeTicks::Now().InSeconds());
+  mouseMoveOverLinkEvent.setFrameScale(1);
   document->frame()->eventHandler().handleMouseMoveEvent(
-      mouseMoveOverLinkEvent, Vector<PlatformMouseEvent>());
+      mouseMoveOverLinkEvent, Vector<WebMouseEvent>());
 
   EXPECT_EQ(document->hoverNode(),
             document->frame()->chromeClient().lastSetTooltipNodeForTesting());
@@ -10809,13 +10816,15 @@
 
   Element* div2Tag = document->getElementById("div2");
 
-  PlatformMouseEvent mouseMoveEvent(
-      IntPoint(div2Tag->offsetLeft() + 5, div2Tag->offsetTop() + 5),
-      IntPoint(div2Tag->offsetLeft() + 5, div2Tag->offsetTop() + 5),
-      WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, 0,
-      PlatformEvent::NoModifiers, TimeTicks::Now());
+  WebMouseEvent mouseMoveEvent(
+      WebInputEvent::MouseMove,
+      WebFloatPoint(div2Tag->offsetLeft() + 5, div2Tag->offsetTop() + 5),
+      WebFloatPoint(div2Tag->offsetLeft() + 5, div2Tag->offsetTop() + 5),
+      WebPointerProperties::Button::NoButton, 0, WebInputEvent::NoModifiers,
+      TimeTicks::Now().InSeconds());
+  mouseMoveEvent.setFrameScale(1);
   document->frame()->eventHandler().handleMouseMoveEvent(
-      mouseMoveEvent, Vector<PlatformMouseEvent>());
+      mouseMoveEvent, Vector<WebMouseEvent>());
 
   EXPECT_EQ(document->hoverNode(),
             document->frame()->chromeClient().lastSetTooltipNodeForTesting());
@@ -10856,13 +10865,15 @@
   EXPECT_FALSE(hitTestResult.scrollbar()->isCustomScrollbar());
 
   // Mouse over link. Mouse cursor should be hand.
-  PlatformMouseEvent mouseMoveOverLinkEvent(
-      IntPoint(aTag->offsetLeft(), aTag->offsetTop()),
-      IntPoint(aTag->offsetLeft(), aTag->offsetTop()),
-      WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, 0,
-      PlatformEvent::NoModifiers, TimeTicks::Now());
+  WebMouseEvent mouseMoveOverLinkEvent(
+      WebInputEvent::MouseMove,
+      WebFloatPoint(aTag->offsetLeft(), aTag->offsetTop()),
+      WebFloatPoint(aTag->offsetLeft(), aTag->offsetTop()),
+      WebPointerProperties::Button::NoButton, 0, WebInputEvent::NoModifiers,
+      TimeTicks::Now().InSeconds());
+  mouseMoveOverLinkEvent.setFrameScale(1);
   document->frame()->eventHandler().handleMouseMoveEvent(
-      mouseMoveOverLinkEvent, Vector<PlatformMouseEvent>());
+      mouseMoveOverLinkEvent, Vector<WebMouseEvent>());
 
   EXPECT_EQ(
       Cursor::Type::Hand,
@@ -10870,31 +10881,37 @@
 
   // Mouse over enabled overlay scrollbar. Mouse cursor should be pointer and no
   // active hover element.
-  PlatformMouseEvent mouseMoveEvent(
-      IntPoint(18, aTag->offsetTop()), IntPoint(18, aTag->offsetTop()),
-      WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, 0,
-      PlatformEvent::NoModifiers, TimeTicks::Now());
+  WebMouseEvent mouseMoveEvent(
+      WebInputEvent::MouseMove, WebFloatPoint(18, aTag->offsetTop()),
+      WebFloatPoint(18, aTag->offsetTop()),
+      WebPointerProperties::Button::NoButton, 0, WebInputEvent::NoModifiers,
+      TimeTicks::Now().InSeconds());
+  mouseMoveEvent.setFrameScale(1);
   document->frame()->eventHandler().handleMouseMoveEvent(
-      mouseMoveEvent, Vector<PlatformMouseEvent>());
+      mouseMoveEvent, Vector<WebMouseEvent>());
 
   EXPECT_EQ(
       Cursor::Type::Pointer,
       document->frame()->chromeClient().lastSetCursorForTesting().getType());
 
-  PlatformMouseEvent mousePressEvent(
-      IntPoint(18, aTag->offsetTop()), IntPoint(18, aTag->offsetTop()),
-      WebPointerProperties::Button::Left, PlatformEvent::MousePressed, 0,
-      PlatformEvent::Modifiers::LeftButtonDown, TimeTicks::Now());
+  WebMouseEvent mousePressEvent(
+      WebInputEvent::MouseDown, WebFloatPoint(18, aTag->offsetTop()),
+      WebFloatPoint(18, aTag->offsetTop()), WebPointerProperties::Button::Left,
+      0, WebInputEvent::Modifiers::LeftButtonDown,
+      TimeTicks::Now().InSeconds());
+  mousePressEvent.setFrameScale(1);
   document->frame()->eventHandler().handleMousePressEvent(mousePressEvent);
 
   EXPECT_FALSE(document->activeHoverElement());
   EXPECT_FALSE(document->hoverNode());
 
-  PlatformMouseEvent MouseReleaseEvent(
-      IntPoint(18, aTag->offsetTop()), IntPoint(18, aTag->offsetTop()),
-      WebPointerProperties::Button::Left, PlatformEvent::MouseReleased, 0,
-      PlatformEvent::Modifiers::LeftButtonDown, TimeTicks::Now());
-  document->frame()->eventHandler().handleMouseReleaseEvent(MouseReleaseEvent);
+  WebMouseEvent mouseReleaseEvent(
+      WebInputEvent::MouseUp, WebFloatPoint(18, aTag->offsetTop()),
+      WebFloatPoint(18, aTag->offsetTop()), WebPointerProperties::Button::Left,
+      0, WebInputEvent::Modifiers::LeftButtonDown,
+      TimeTicks::Now().InSeconds());
+  mouseReleaseEvent.setFrameScale(1);
+  document->frame()->eventHandler().handleMouseReleaseEvent(mouseReleaseEvent);
 
   // Mouse over disabled overlay scrollbar. Mouse cursor should be hand and has
   // active hover element.
@@ -10908,7 +10925,7 @@
   EXPECT_FALSE(hitTestResult.scrollbar());
 
   document->frame()->eventHandler().handleMouseMoveEvent(
-      mouseMoveEvent, Vector<PlatformMouseEvent>());
+      mouseMoveEvent, Vector<WebMouseEvent>());
 
   EXPECT_EQ(
       Cursor::Type::Hand,
@@ -10919,7 +10936,7 @@
   EXPECT_TRUE(document->activeHoverElement());
   EXPECT_TRUE(document->hoverNode());
 
-  document->frame()->eventHandler().handleMouseReleaseEvent(MouseReleaseEvent);
+  document->frame()->eventHandler().handleMouseReleaseEvent(mouseReleaseEvent);
 }
 
 // Makes sure that mouse hover over an custom scrollbar doesn't change the
@@ -10946,12 +10963,13 @@
   EXPECT_FALSE(hitTestResult.scrollbar());
 
   // Mouse over DIV
-  PlatformMouseEvent mouseMoveOverDiv(
-      IntPoint(1, 1), IntPoint(1, 1), WebPointerProperties::Button::NoButton,
-      PlatformEvent::MouseMoved, 0, PlatformEvent::NoModifiers,
-      TimeTicks::Now());
+  WebMouseEvent mouseMoveOverDiv(
+      WebInputEvent::MouseMove, WebFloatPoint(1, 1), WebFloatPoint(1, 1),
+      WebPointerProperties::Button::NoButton, 0, WebInputEvent::NoModifiers,
+      TimeTicks::Now().InSeconds());
+  mouseMoveOverDiv.setFrameScale(1);
   document->frame()->eventHandler().handleMouseMoveEvent(
-      mouseMoveOverDiv, Vector<PlatformMouseEvent>());
+      mouseMoveOverDiv, Vector<WebMouseEvent>());
 
   // DIV :hover
   EXPECT_EQ(document->hoverNode(), scrollbarDiv);
@@ -10964,12 +10982,13 @@
   EXPECT_TRUE(hitTestResult.scrollbar()->isCustomScrollbar());
 
   // Mouse over scrollbar
-  PlatformMouseEvent mouseMoveOverDivAndScrollbar(
-      IntPoint(175, 1), IntPoint(175, 1),
-      WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, 0,
-      PlatformEvent::NoModifiers, TimeTicks::Now());
+  WebMouseEvent mouseMoveOverDivAndScrollbar(
+      WebInputEvent::MouseMove, WebFloatPoint(175, 1), WebFloatPoint(175, 1),
+      WebPointerProperties::Button::NoButton, 0, WebInputEvent::NoModifiers,
+      TimeTicks::Now().InSeconds());
+  mouseMoveOverDivAndScrollbar.setFrameScale(1);
   document->frame()->eventHandler().handleMouseMoveEvent(
-      mouseMoveOverDivAndScrollbar, Vector<PlatformMouseEvent>());
+      mouseMoveOverDivAndScrollbar, Vector<WebMouseEvent>());
 
   // Custom not change the DIV :hover
   EXPECT_EQ(document->hoverNode(), scrollbarDiv);
@@ -11000,41 +11019,45 @@
   EXPECT_EQ(scrollbar->hoveredPart(), ScrollbarPart::NoPart);
 
   // Mouse moved over the scrollbar.
-  PlatformMouseEvent mouseMoveOverScrollbar(
-      IntPoint(175, 1), IntPoint(175, 1),
-      WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, 0,
-      PlatformEvent::NoModifiers, TimeTicks::Now());
+  WebMouseEvent mouseMoveOverScrollbar(
+      WebInputEvent::MouseMove, WebFloatPoint(175, 1), WebFloatPoint(175, 1),
+      WebPointerProperties::Button::NoButton, 0, WebInputEvent::NoModifiers,
+      TimeTicks::Now().InSeconds());
+  mouseMoveOverScrollbar.setFrameScale(1);
   document->frame()->eventHandler().handleMouseMoveEvent(
-      mouseMoveOverScrollbar, Vector<PlatformMouseEvent>());
+      mouseMoveOverScrollbar, Vector<WebMouseEvent>());
   HitTestResult hitTestResult = webView->coreHitTestResultAt(WebPoint(175, 1));
   EXPECT_EQ(scrollbar->pressedPart(), ScrollbarPart::NoPart);
   EXPECT_EQ(scrollbar->hoveredPart(), ScrollbarPart::ThumbPart);
 
   // Mouse pressed.
-  PlatformMouseEvent mousePressEvent(
-      IntPoint(175, 1), IntPoint(175, 1), WebPointerProperties::Button::Left,
-      PlatformEvent::MousePressed, 0, PlatformEvent::Modifiers::LeftButtonDown,
-      TimeTicks::Now());
+  WebMouseEvent mousePressEvent(
+      WebInputEvent::MouseDown, WebFloatPoint(175, 1), WebFloatPoint(175, 1),
+      WebPointerProperties::Button::Left, 0,
+      WebInputEvent::Modifiers::LeftButtonDown, TimeTicks::Now().InSeconds());
+  mousePressEvent.setFrameScale(1);
   document->frame()->eventHandler().handleMousePressEvent(mousePressEvent);
   EXPECT_EQ(scrollbar->pressedPart(), ScrollbarPart::ThumbPart);
   EXPECT_EQ(scrollbar->hoveredPart(), ScrollbarPart::ThumbPart);
 
   // Mouse moved off the scrollbar while still pressed.
-  PlatformMouseEvent mouseMoveOffScrollbar(
-      IntPoint(1, 1), IntPoint(1, 1), WebPointerProperties::Button::Left,
-      PlatformEvent::MouseMoved, 0, PlatformEvent::Modifiers::LeftButtonDown,
-      TimeTicks::Now());
+  WebMouseEvent mouseMoveOffScrollbar(
+      WebInputEvent::MouseMove, WebFloatPoint(1, 1), WebFloatPoint(1, 1),
+      WebPointerProperties::Button::Left, 0,
+      WebInputEvent::Modifiers::LeftButtonDown, TimeTicks::Now().InSeconds());
+  mouseMoveOffScrollbar.setFrameScale(1);
   document->frame()->eventHandler().handleMouseLeaveEvent(
       mouseMoveOffScrollbar);
   EXPECT_EQ(scrollbar->pressedPart(), ScrollbarPart::ThumbPart);
   EXPECT_EQ(scrollbar->hoveredPart(), ScrollbarPart::ThumbPart);
 
   // Mouse released.
-  PlatformMouseEvent MouseReleaseEvent(
-      IntPoint(1, 1), IntPoint(1, 1), WebPointerProperties::Button::Left,
-      PlatformEvent::MouseReleased, 0, PlatformEvent::Modifiers::LeftButtonDown,
-      TimeTicks::Now());
-  document->frame()->eventHandler().handleMouseReleaseEvent(MouseReleaseEvent);
+  WebMouseEvent mouseReleaseEvent(
+      WebInputEvent::MouseUp, WebFloatPoint(1, 1), WebFloatPoint(1, 1),
+      WebPointerProperties::Button::Left, 0,
+      WebInputEvent::Modifiers::LeftButtonDown, TimeTicks::Now().InSeconds());
+  mouseReleaseEvent.setFrameScale(1);
+  document->frame()->eventHandler().handleMouseReleaseEvent(mouseReleaseEvent);
   EXPECT_EQ(scrollbar->pressedPart(), ScrollbarPart::NoPart);
   EXPECT_EQ(scrollbar->hoveredPart(), ScrollbarPart::NoPart);
 }
diff --git a/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp b/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp
index 4de6fd5..6189e7b 100644
--- a/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp
@@ -121,10 +121,6 @@
   webViewImpl->setPageScaleFactor(2);
 
   FrameView* view = toLocalFrame(webViewImpl->page()->mainFrame())->view();
-  Document* document =
-      toLocalFrame(webViewImpl->page()->mainFrame())->document();
-  LocalDOMWindow* domWindow = document->domWindow();
-  LayoutViewItem documentLayoutView = document->layoutViewItem();
 
   {
     WebMouseEvent webMouseEvent(WebInputEvent::MouseMove,
@@ -139,13 +135,17 @@
     webMouseEvent.movementX = 10;
     webMouseEvent.movementY = 10;
 
-    PlatformMouseEventBuilder platformMouseBuilder(view, webMouseEvent);
-    EXPECT_EQ(5, platformMouseBuilder.position().x());
-    EXPECT_EQ(5, platformMouseBuilder.position().y());
-    EXPECT_EQ(10, platformMouseBuilder.globalPosition().x());
-    EXPECT_EQ(10, platformMouseBuilder.globalPosition().y());
-    EXPECT_EQ(5, platformMouseBuilder.movementDelta().x());
-    EXPECT_EQ(5, platformMouseBuilder.movementDelta().y());
+    WebMouseEvent transformedEvent =
+        TransformWebMouseEvent(view, webMouseEvent);
+    IntPoint position = flooredIntPoint(transformedEvent.positionInRootFrame());
+    EXPECT_EQ(5, position.x());
+    EXPECT_EQ(5, position.y());
+    EXPECT_EQ(10, transformedEvent.globalX);
+    EXPECT_EQ(10, transformedEvent.globalY);
+
+    IntPoint movement = flooredIntPoint(transformedEvent.movementInRootFrame());
+    EXPECT_EQ(5, movement.x());
+    EXPECT_EQ(5, movement.y());
   }
 
   {
@@ -326,37 +326,6 @@
     EXPECT_FLOAT_EQ(5.3f, transformedPoint.radiusX);
     EXPECT_FLOAT_EQ(5.2f, transformedPoint.radiusY);
   }
-
-  // Reverse builders should *not* go back to physical pixels, as they are used
-  // for plugins which expect CSS pixel coordinates.
-  {
-    PlatformMouseEvent platformMouseEvent(
-        IntPoint(10, 10), IntPoint(10, 10), WebPointerProperties::Button::Left,
-        PlatformEvent::MouseMoved, 1, PlatformEvent::NoModifiers,
-        PlatformMouseEvent::RealOrIndistinguishable, TimeTicks());
-    MouseEvent* mouseEvent = MouseEvent::create(
-        EventTypeNames::mousemove, domWindow, platformMouseEvent, 0, document);
-    WebMouseEventBuilder webMouseBuilder(view, documentLayoutView, *mouseEvent);
-
-    EXPECT_EQ(10, webMouseBuilder.x);
-    EXPECT_EQ(10, webMouseBuilder.y);
-    EXPECT_EQ(10, webMouseBuilder.globalX);
-    EXPECT_EQ(10, webMouseBuilder.globalY);
-    EXPECT_EQ(10, webMouseBuilder.windowX);
-    EXPECT_EQ(10, webMouseBuilder.windowY);
-  }
-
-  {
-    PlatformMouseEvent platformMouseEvent(
-        IntPoint(10, 10), IntPoint(10, 10),
-        WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, 1,
-        PlatformEvent::NoModifiers, PlatformMouseEvent::RealOrIndistinguishable,
-        TimeTicks());
-    MouseEvent* mouseEvent = MouseEvent::create(
-        EventTypeNames::mousemove, domWindow, platformMouseEvent, 0, document);
-    WebMouseEventBuilder webMouseBuilder(view, documentLayoutView, *mouseEvent);
-    EXPECT_EQ(WebMouseEvent::Button::NoButton, webMouseBuilder.button);
-  }
 }
 
 TEST(WebInputEventConversionTest, InputEventsTransform) {
@@ -394,13 +363,18 @@
     webMouseEvent.movementX = 60;
     webMouseEvent.movementY = 60;
 
-    PlatformMouseEventBuilder platformMouseBuilder(view, webMouseEvent);
-    EXPECT_EQ(30, platformMouseBuilder.position().x());
-    EXPECT_EQ(30, platformMouseBuilder.position().y());
-    EXPECT_EQ(100, platformMouseBuilder.globalPosition().x());
-    EXPECT_EQ(110, platformMouseBuilder.globalPosition().y());
-    EXPECT_EQ(20, platformMouseBuilder.movementDelta().x());
-    EXPECT_EQ(20, platformMouseBuilder.movementDelta().y());
+    WebMouseEvent transformedEvent =
+        TransformWebMouseEvent(view, webMouseEvent);
+    FloatPoint position = transformedEvent.positionInRootFrame();
+
+    EXPECT_FLOAT_EQ(30, position.x());
+    EXPECT_FLOAT_EQ(30, position.y());
+    EXPECT_EQ(100, transformedEvent.globalX);
+    EXPECT_EQ(110, transformedEvent.globalY);
+
+    IntPoint movement = flooredIntPoint(transformedEvent.movementInRootFrame());
+    EXPECT_EQ(20, movement.x());
+    EXPECT_EQ(20, movement.y());
   }
 
   {
@@ -426,23 +400,30 @@
     events.push_back(&webMouseEvent1);
     events.push_back(&webMouseEvent2);
 
-    Vector<PlatformMouseEvent> coalescedevents =
-        createPlatformMouseEventVector(view, events);
+    Vector<WebMouseEvent> coalescedevents =
+        TransformWebMouseEventVector(view, events);
     EXPECT_EQ(events.size(), coalescedevents.size());
 
-    EXPECT_EQ(30, coalescedevents[0].position().x());
-    EXPECT_EQ(30, coalescedevents[0].position().y());
-    EXPECT_EQ(100, coalescedevents[0].globalPosition().x());
-    EXPECT_EQ(110, coalescedevents[0].globalPosition().y());
-    EXPECT_EQ(20, coalescedevents[0].movementDelta().x());
-    EXPECT_EQ(20, coalescedevents[0].movementDelta().y());
+    FloatPoint position = coalescedevents[0].positionInRootFrame();
+    EXPECT_FLOAT_EQ(30, position.x());
+    EXPECT_FLOAT_EQ(30, position.y());
+    EXPECT_EQ(100, coalescedevents[0].globalX);
+    EXPECT_EQ(110, coalescedevents[0].globalY);
 
-    EXPECT_EQ(30, coalescedevents[1].position().x());
-    EXPECT_EQ(40, coalescedevents[1].position().y());
-    EXPECT_EQ(100, coalescedevents[1].globalPosition().x());
-    EXPECT_EQ(140, coalescedevents[1].globalPosition().y());
-    EXPECT_EQ(20, coalescedevents[1].movementDelta().x());
-    EXPECT_EQ(10, coalescedevents[1].movementDelta().y());
+    IntPoint movement =
+        flooredIntPoint(coalescedevents[0].movementInRootFrame());
+    EXPECT_EQ(20, movement.x());
+    EXPECT_EQ(20, movement.y());
+
+    position = coalescedevents[1].positionInRootFrame();
+    EXPECT_FLOAT_EQ(30, position.x());
+    EXPECT_FLOAT_EQ(40, position.y());
+    EXPECT_EQ(100, coalescedevents[1].globalX);
+    EXPECT_EQ(140, coalescedevents[1].globalY);
+
+    movement = flooredIntPoint(coalescedevents[1].movementInRootFrame());
+    EXPECT_EQ(20, movement.x());
+    EXPECT_EQ(10, movement.y());
   }
 
   {
@@ -703,11 +684,14 @@
     webMouseEvent.globalX = 10;
     webMouseEvent.globalY = 10;
 
-    PlatformMouseEventBuilder platformMouseBuilder(view, webMouseEvent);
-    EXPECT_EQ(5 + visualOffset.x(), platformMouseBuilder.position().x());
-    EXPECT_EQ(5 + visualOffset.y(), platformMouseBuilder.position().y());
-    EXPECT_EQ(10, platformMouseBuilder.globalPosition().x());
-    EXPECT_EQ(10, platformMouseBuilder.globalPosition().y());
+    WebMouseEvent transformedMouseEvent =
+        TransformWebMouseEvent(view, webMouseEvent);
+    IntPoint position =
+        flooredIntPoint(transformedMouseEvent.positionInRootFrame());
+    EXPECT_EQ(5 + visualOffset.x(), position.x());
+    EXPECT_EQ(5 + visualOffset.y(), position.y());
+    EXPECT_EQ(10, transformedMouseEvent.globalX);
+    EXPECT_EQ(10, transformedMouseEvent.globalY);
   }
 
   {
@@ -811,13 +795,15 @@
     webMouseEvent.globalX = 10;
     webMouseEvent.globalY = 50;
 
-    PlatformMouseEventBuilder platformMouseBuilder(view, webMouseEvent);
-    EXPECT_EQ(webMouseEvent.x + elasticOverscroll.width(),
-              platformMouseBuilder.position().x());
-    EXPECT_EQ(webMouseEvent.y + elasticOverscroll.height(),
-              platformMouseBuilder.position().y());
-    EXPECT_EQ(webMouseEvent.globalX, platformMouseBuilder.globalPosition().x());
-    EXPECT_EQ(webMouseEvent.globalY, platformMouseBuilder.globalPosition().y());
+    WebMouseEvent transformedMouseEvent =
+        TransformWebMouseEvent(view, webMouseEvent);
+    IntPoint position =
+        flooredIntPoint(transformedMouseEvent.positionInRootFrame());
+
+    EXPECT_EQ(webMouseEvent.x + elasticOverscroll.width(), position.x());
+    EXPECT_EQ(webMouseEvent.y + elasticOverscroll.height(), position.y());
+    EXPECT_EQ(webMouseEvent.globalX, transformedMouseEvent.globalX);
+    EXPECT_EQ(webMouseEvent.globalY, transformedMouseEvent.globalY);
   }
 
   // Elastic overscroll and pinch-zoom (this doesn't actually ever happen,
@@ -838,15 +824,19 @@
     webMouseEvent.globalX = 10;
     webMouseEvent.globalY = 10;
 
-    PlatformMouseEventBuilder platformMouseBuilder(view, webMouseEvent);
+    WebMouseEvent transformedMouseEvent =
+        TransformWebMouseEvent(view, webMouseEvent);
+    IntPoint position =
+        flooredIntPoint(transformedMouseEvent.positionInRootFrame());
+
     EXPECT_EQ(webMouseEvent.x / pageScale + visualOffset.x() +
                   elasticOverscroll.width(),
-              platformMouseBuilder.position().x());
+              position.x());
     EXPECT_EQ(webMouseEvent.y / pageScale + visualOffset.y() +
                   elasticOverscroll.height(),
-              platformMouseBuilder.position().y());
-    EXPECT_EQ(webMouseEvent.globalX, platformMouseBuilder.globalPosition().x());
-    EXPECT_EQ(webMouseEvent.globalY, platformMouseBuilder.globalPosition().y());
+              position.y());
+    EXPECT_EQ(webMouseEvent.globalX, transformedMouseEvent.globalX);
+    EXPECT_EQ(webMouseEvent.globalY, transformedMouseEvent.globalY);
   }
 }
 
@@ -884,13 +874,15 @@
     webMouseEvent.globalX = 10;
     webMouseEvent.globalY = 50;
 
-    PlatformMouseEventBuilder platformMouseBuilder(view, webMouseEvent);
-    EXPECT_EQ(webMouseEvent.x + elasticOverscroll.width(),
-              platformMouseBuilder.position().x());
-    EXPECT_EQ(webMouseEvent.y + elasticOverscroll.height(),
-              platformMouseBuilder.position().y());
-    EXPECT_EQ(webMouseEvent.globalX, platformMouseBuilder.globalPosition().x());
-    EXPECT_EQ(webMouseEvent.globalY, platformMouseBuilder.globalPosition().y());
+    WebMouseEvent transformedMouseEvent =
+        TransformWebMouseEvent(view, webMouseEvent);
+    IntPoint position =
+        flooredIntPoint(transformedMouseEvent.positionInRootFrame());
+
+    EXPECT_EQ(webMouseEvent.x + elasticOverscroll.width(), position.x());
+    EXPECT_EQ(webMouseEvent.y + elasticOverscroll.height(), position.y());
+    EXPECT_EQ(webMouseEvent.globalX, transformedMouseEvent.globalX);
+    EXPECT_EQ(webMouseEvent.globalY, transformedMouseEvent.globalY);
   }
 }
 
diff --git a/third_party/WebKit/Source/wtf/HexNumber.h b/third_party/WebKit/Source/wtf/HexNumber.h
index a0ea7b5c..fb380d41 100644
--- a/third_party/WebKit/Source/wtf/HexNumber.h
+++ b/third_party/WebKit/Source/wtf/HexNumber.h
@@ -54,6 +54,14 @@
     destination.push_back(hexDigits[byte & 0xF]);
   }
 
+  static inline void appendByteAsHex(unsigned char byte,
+                                     Vector<char>& destination,
+                                     HexConversionMode mode = Uppercase) {
+    const LChar* hexDigits = hexDigitsForMode(mode);
+    destination.push_back(hexDigits[byte >> 4]);
+    destination.push_back(hexDigits[byte & 0xF]);
+  }
+
   template <typename T>
   static inline void appendUnsignedAsHex(unsigned number,
                                          T& destination,
diff --git a/third_party/WebKit/Source/wtf/Vector.h b/third_party/WebKit/Source/wtf/Vector.h
index 96a44076..6f522d50 100644
--- a/third_party/WebKit/Source/wtf/Vector.h
+++ b/third_party/WebKit/Source/wtf/Vector.h
@@ -949,8 +949,6 @@
   template <typename U>
   void append(const U*, size_t);
   template <typename U>
-  void append(U&&);
-  template <typename U>
   void push_back(U&&);
   template <typename... Args>
   T& emplace_back(Args&&...);
@@ -1199,7 +1197,7 @@
 void Vector<T, inlineCapacity, Allocator>::appendRange(Iterator start,
                                                        Iterator end) {
   for (Iterator it = start; it != end; ++it)
-    append(*it);
+    push_back(*it);
 }
 
 template <typename T, size_t inlineCapacity, typename Allocator>
@@ -1390,12 +1388,6 @@
 template <typename T, size_t inlineCapacity, typename Allocator>
 template <typename U>
 ALWAYS_INLINE void Vector<T, inlineCapacity, Allocator>::push_back(U&& val) {
-  return append(std::forward<U>(val));
-}
-
-template <typename T, size_t inlineCapacity, typename Allocator>
-template <typename U>
-ALWAYS_INLINE void Vector<T, inlineCapacity, Allocator>::append(U&& val) {
   DCHECK(Allocator::isAllocationAllowed());
   if (LIKELY(size() != capacity())) {
     ANNOTATE_CHANGE_SIZE(begin(), capacity(), m_size, m_size + 1);
@@ -1448,7 +1440,7 @@
     U&& val) {
 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER
   // Vectors in ASAN builds don't have inlineCapacity.
-  append(std::forward<U>(val));
+  push_back(std::forward<U>(val));
 #else
   DCHECK_LT(size(), capacity());
   ANNOTATE_CHANGE_SIZE(begin(), capacity(), m_size, m_size + 1);
diff --git a/third_party/WebKit/Source/wtf/VectorTest.cpp b/third_party/WebKit/Source/wtf/VectorTest.cpp
index 2ae71e9e..1b3f2b5 100644
--- a/third_party/WebKit/Source/wtf/VectorTest.cpp
+++ b/third_party/WebKit/Source/wtf/VectorTest.cpp
@@ -362,12 +362,12 @@
 #if defined(ANNOTATE_CONTIGUOUS_CONTAINER)
 TEST(VectorTest, ContainerAnnotations) {
   Vector<int> vectorA;
-  vectorA.append(10);
+  vectorA.push_back(10);
   vectorA.reserveCapacity(32);
 
   volatile int* intPointerA = vectorA.data();
   EXPECT_DEATH(intPointerA[1] = 11, "container-overflow");
-  vectorA.append(11);
+  vectorA.push_back(11);
   intPointerA[1] = 11;
   EXPECT_DEATH(intPointerA[2] = 12, "container-overflow");
   EXPECT_DEATH((void)intPointerA[2], "container-overflow");
@@ -384,7 +384,7 @@
   Vector<int> vectorC((Vector<int>(vectorA)));
   volatile int* intPointerC = vectorC.data();
   EXPECT_DEATH((void)intPointerC[2], "container-overflow");
-  vectorC.append(13);
+  vectorC.push_back(13);
   vectorC.swap(vectorB);
 
   volatile int* intPointerB2 = vectorB.data();
diff --git a/third_party/WebKit/public/platform/DEPS b/third_party/WebKit/public/platform/DEPS
index 76b11842..4caf401 100644
--- a/third_party/WebKit/public/platform/DEPS
+++ b/third_party/WebKit/public/platform/DEPS
@@ -21,6 +21,7 @@
     "-public/web",
     "+services/service_manager/public/interfaces",
     "+third_party/skia",
+    "+ui/gfx",
     "+url",
     "-web",
 ]
diff --git a/third_party/WebKit/public/platform/WebInputEvent.h b/third_party/WebKit/public/platform/WebInputEvent.h
index 99e27f0..9efd6a8 100644
--- a/third_party/WebKit/public/platform/WebInputEvent.h
+++ b/third_party/WebKit/public/platform/WebInputEvent.h
@@ -187,6 +187,11 @@
 
     ScrollLockOn = 1 << 18,
 
+    // Whether this is a compatibility event generated due to a
+    // native touch event. Mouse events generated from touch
+    // events will set this.
+    IsCompatibilityEventForTouch = 1 << 19,
+
     // The set of non-stateful modifiers that specifically change the
     // interpretation of the key being pressed. For example; IsLeft,
     // IsRight, IsComposing don't change the meaning of the key
diff --git a/third_party/WebKit/public/platform/WebMouseEvent.h b/third_party/WebKit/public/platform/WebMouseEvent.h
index ec23a72..c9e5a41 100644
--- a/third_party/WebKit/public/platform/WebMouseEvent.h
+++ b/third_party/WebKit/public/platform/WebMouseEvent.h
@@ -9,6 +9,8 @@
 
 namespace blink {
 
+class WebGestureEvent;
+
 // See WebInputEvent.h for details why this pack is here.
 #pragma pack(push, 4)
 
@@ -34,16 +36,69 @@
   int movementY;
   int clickCount;
 
-  WebMouseEvent(Type type, int modifiers, double timeStampSeconds)
-      : WebInputEvent(sizeof(WebMouseEvent), type, modifiers, timeStampSeconds),
-        WebPointerProperties() {}
+  WebMouseEvent(Type typeParam,
+                int xParam,
+                int yParam,
+                int globalXParam,
+                int globalYParam,
+                int modifiersParam,
+                double timeStampSecondsParam)
+      : WebInputEvent(sizeof(WebMouseEvent),
+                      typeParam,
+                      modifiersParam,
+                      timeStampSecondsParam),
+        WebPointerProperties(),
+        x(xParam),
+        y(yParam),
+        globalX(globalXParam),
+        globalY(globalYParam) {}
 
-  WebMouseEvent()
-      : WebInputEvent(sizeof(WebMouseEvent)), WebPointerProperties() {}
+  WebMouseEvent(Type typeParam,
+                WebFloatPoint position,
+                WebFloatPoint globalPosition,
+                Button buttonParam,
+                int clickCountParam,
+                int modifiersParam,
+                double timeStampSecondsParam)
+      : WebInputEvent(sizeof(WebMouseEvent),
+                      typeParam,
+                      modifiersParam,
+                      timeStampSecondsParam),
+        WebPointerProperties(buttonParam, PointerType::Mouse),
+        x(position.x),
+        y(position.y),
+        globalX(globalPosition.x),
+        globalY(globalPosition.y),
+        clickCount(clickCountParam) {}
+
+  WebMouseEvent(Type typeParam,
+                int modifiersParam,
+                double timeStampSecondsParam)
+      : WebMouseEvent(sizeof(WebMouseEvent),
+                      typeParam,
+                      modifiersParam,
+                      timeStampSecondsParam) {}
+
+  WebMouseEvent() : WebMouseEvent(sizeof(WebMouseEvent)) {}
+
+  bool fromTouch() const {
+    return (modifiers() & IsCompatibilityEventForTouch) != 0;
+  }
 
 #if INSIDE_BLINK
+  BLINK_PLATFORM_EXPORT WebMouseEvent(Type typeParam,
+                                      const WebGestureEvent&,
+                                      Button buttonParam,
+                                      int clickCountParam,
+                                      int modifiersParam,
+                                      double timeStampSecondsParam);
+
   BLINK_PLATFORM_EXPORT WebFloatPoint movementInRootFrame() const;
   BLINK_PLATFORM_EXPORT WebFloatPoint positionInRootFrame() const;
+
+  // Sets any scaled values to be their computed values and sets |frameScale|
+  // back to 1 and |translateX|, |translateY| back to 0.
+  BLINK_PLATFORM_EXPORT WebMouseEvent flattenTransform() const;
 #endif
 
  protected:
diff --git a/third_party/WebKit/public/platform/WebPointerProperties.h b/third_party/WebKit/public/platform/WebPointerProperties.h
index 86f29600..27e59c4 100644
--- a/third_party/WebKit/public/platform/WebPointerProperties.h
+++ b/third_party/WebKit/public/platform/WebPointerProperties.h
@@ -17,16 +17,6 @@
 // WebTouchEvent and WebTouchPoint and merge this into WebPointerEvent.
 class WebPointerProperties {
  public:
-  WebPointerProperties()
-      : id(0),
-        force(std::numeric_limits<float>::quiet_NaN()),
-        tiltX(0),
-        tiltY(0),
-        tangentialPressure(0.0f),
-        twist(0),
-        button(Button::NoButton),
-        pointerType(PointerType::Unknown) {}
-
   enum class Button { NoButton = -1, Left, Middle, Right, X1, X2, Eraser };
 
   enum class Buttons : unsigned {
@@ -48,6 +38,26 @@
     LastEntry = Touch  // Must be the last entry in the list
   };
 
+  WebPointerProperties()
+      : id(0),
+        force(std::numeric_limits<float>::quiet_NaN()),
+        tiltX(0),
+        tiltY(0),
+        tangentialPressure(0.0f),
+        twist(0),
+        button(Button::NoButton),
+        pointerType(PointerType::Unknown) {}
+
+  WebPointerProperties(Button buttonParam, PointerType pointerTypeParam)
+      : id(0),
+        force(std::numeric_limits<float>::quiet_NaN()),
+        tiltX(0),
+        tiltY(0),
+        tangentialPressure(0.0f),
+        twist(0),
+        button(buttonParam),
+        pointerType(pointerTypeParam) {}
+
   int id;
 
   // The valid range is [0,1], with NaN meaning pressure is not supported by
diff --git a/third_party/WebKit/public/platform/WebScreenInfo.h b/third_party/WebKit/public/platform/WebScreenInfo.h
index f51f78b..feaa33126 100644
--- a/third_party/WebKit/public/platform/WebScreenInfo.h
+++ b/third_party/WebKit/public/platform/WebScreenInfo.h
@@ -34,23 +34,27 @@
 #include "WebRect.h"
 #include "public/platform/ShapeProperties.h"
 #include "public/platform/modules/screen_orientation/WebScreenOrientationType.h"
+#include "ui/gfx/icc_profile.h"
 
 namespace blink {
 
 struct WebScreenInfo {
   // Device scale factor. Specifies the ratio between physical and logical
   // pixels.
-  float deviceScaleFactor;
+  float deviceScaleFactor = 1.f;
+
+  // The ICC profile of the output display.
+  gfx::ICCProfile iccProfile;
 
   // The screen depth in bits per pixel
-  int depth;
+  int depth = 0;
 
   // The bits per colour component. This assumes that the colours are balanced
   // equally.
-  int depthPerComponent;
+  int depthPerComponent = 0;
 
   // This can be true for black and white printers
-  bool isMonochrome;
+  bool isMonochrome = false;
 
   // This is set from the rcMonitor member of MONITORINFOEX, to whit:
   //   "A RECT structure that specifies the display monitor rectangle,
@@ -72,27 +76,20 @@
   // This is the orientation 'type' or 'name', as in landscape-primary or
   // portrait-secondary for examples.
   // See WebScreenOrientationType.h for the full list.
-  WebScreenOrientationType orientationType;
+  WebScreenOrientationType orientationType = WebScreenOrientationUndefined;
 
   // This is the orientation angle of the displayed content in degrees.
   // It is the opposite of the physical rotation.
-  uint16_t orientationAngle;
+  uint16_t orientationAngle = 0;
 
   // This is the shape of display.
-  DisplayShape displayShape;
+  DisplayShape displayShape = DisplayShapeRect;
 
-  WebScreenInfo()
-      : deviceScaleFactor(1),
-        depth(0),
-        depthPerComponent(0),
-        isMonochrome(false),
-        orientationType(WebScreenOrientationUndefined),
-        orientationAngle(0),
-        displayShape(DisplayShapeRect) {}
+  WebScreenInfo() = default;
 
   bool operator==(const WebScreenInfo& other) const {
     return this->deviceScaleFactor == other.deviceScaleFactor &&
-           this->depth == other.depth &&
+           this->iccProfile == other.iccProfile && this->depth == other.depth &&
            this->depthPerComponent == other.depthPerComponent &&
            this->isMonochrome == other.isMonochrome &&
            this->rect == other.rect &&
diff --git a/third_party/WebKit/public/web/WebWindowFeatures.h b/third_party/WebKit/public/web/WebWindowFeatures.h
index a1f6743..f00ed889 100644
--- a/third_party/WebKit/public/web/WebWindowFeatures.h
+++ b/third_party/WebKit/public/web/WebWindowFeatures.h
@@ -119,7 +119,7 @@
     result.fullscreen = fullscreen;
     result.dialog = dialog;
     for (size_t i = 0; i < additionalFeatures.size(); ++i)
-      result.additionalFeatures.append(additionalFeatures[i]);
+      result.additionalFeatures.push_back(additionalFeatures[i]);
     return result;
   }
 #endif
diff --git a/third_party/polymer/v1_0/bower.json b/third_party/polymer/v1_0/bower.json
index f276e58c..d87760d 100644
--- a/third_party/polymer/v1_0/bower.json
+++ b/third_party/polymer/v1_0/bower.json
@@ -57,7 +57,7 @@
     "paper-spinner": "PolymerElements/paper-spinner#1.2.0",
     "paper-styles": "PolymerElements/paper-styles#1.1.4",
     "paper-tabs": "PolymerElements/paper-tabs#1.6.2",
-    "paper-toggle-button": "PolymerElements/paper-toggle-button#1.2.0",
+    "paper-toggle-button": "PolymerElements/paper-toggle-button#1.3.0",
     "paper-toolbar": "PolymerElements/paper-toolbar#1.1.6",
     "paper-tooltip": "PolymerElements/paper-tooltip#1.1.3",
     "polymer": "Polymer/polymer#1.6.1",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/bower.json b/third_party/polymer/v1_0/components-chromium/paper-toggle-button/bower.json
index d29b9a4..8ef0949 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-toggle-button/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-toggle-button",
-  "version": "1.2.0",
+  "version": "1.3.0",
   "description": "A material design toggle button control",
   "authors": [
     "The Polymer Authors"
diff --git a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/paper-toggle-button.html b/third_party/polymer/v1_0/components-chromium/paper-toggle-button/paper-toggle-button.html
index 61a7bf0..e4204650 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-toggle-button/paper-toggle-button.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-toggle-button/paper-toggle-button.html
@@ -39,8 +39,10 @@
 `--paper-toggle-button-invalid-ink-color` | Selected/focus ripple color when the input is invalid | `--error-color`
 `--paper-toggle-button-unchecked-bar` | Mixin applied to the slider when the input is not checked | `{}`
 `--paper-toggle-button-unchecked-button` | Mixin applied to the slider button when the input is not checked | `{}`
+`--paper-toggle-button-unchecked-ink` | Mixin applied to the ripple when the input is not checked | `{}`
 `--paper-toggle-button-checked-bar` | Mixin applied to the slider when the input is checked | `{}`
 `--paper-toggle-button-checked-button` | Mixin applied to the slider button when the input is checked | `{}`
+`--paper-toggle-button-checked-ink` | Mixin applied to the ripple when the input is checked | `{}`
 `--paper-toggle-button-label-color` | Label color | `--primary-text-color`
 `--paper-toggle-button-label-spacing` | Spacing between the label and the button | `8px`
 
@@ -145,10 +147,14 @@
         opacity: 0.5;
         pointer-events: none;
         color: var(--paper-toggle-button-unchecked-ink-color, --primary-text-color);
+
+        @apply(--paper-toggle-button-unchecked-ink);
       }
 
       :host([checked]) .toggle-ink {
         color: var(--paper-toggle-button-checked-ink-color, --primary-color);
+
+        @apply(--paper-toggle-button-checked-ink);
       }
 
       .toggle-container {
diff --git a/third_party/polymer/v1_0/components_summary.txt b/third_party/polymer/v1_0/components_summary.txt
index f063557..6523c2b 100644
--- a/third_party/polymer/v1_0/components_summary.txt
+++ b/third_party/polymer/v1_0/components_summary.txt
@@ -330,9 +330,9 @@
 
 Name: paper-toggle-button
 Repository: https://github.com/PolymerElements/paper-toggle-button.git
-Tree: v1.2.0
-Revision: 6aab07244c07f9598584e6dbce366574f96072a3
-Tree link: https://github.com/PolymerElements/paper-toggle-button/tree/v1.2.0
+Tree: v1.3.0
+Revision: 2f279868a9c8965aba76017c7ee6008ac4879f6a
+Tree link: https://github.com/PolymerElements/paper-toggle-button/tree/v1.3.0
 
 Name: paper-toolbar
 Repository: https://github.com/PolymerElements/paper-toolbar.git
diff --git a/third_party/polymer/v1_0/reproduce.sh b/third_party/polymer/v1_0/reproduce.sh
index 8fb85b4..44a53b3 100755
--- a/third_party/polymer/v1_0/reproduce.sh
+++ b/third_party/polymer/v1_0/reproduce.sh
@@ -26,6 +26,8 @@
     "npm install -g polymer-css-build"
 check_dep "which rsync" "rsync" "apt-get install rsync"
 check_dep "python -c 'import bs4'" "bs4" "apt-get install python-bs4"
+check_dep "sed --version | grep GNU" \
+    "GNU sed as 'sed'" "'brew install gnu-sed --with-default-names'"
 
 set -e
 
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index c206b6f..b4af785 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -70242,6 +70242,23 @@
   <summary>The status when loading UKM PersistedLogs from Prefs.</summary>
 </histogram>
 
+<histogram name="UKM.Sources.MaxSourcesHit" units="BooleanHit">
+  <owner>holte@chromium.org</owner>
+  <owner>rkaplow@chromium.org</owner>
+  <summary>
+    Counter for the number of times an UKM source was discarded due to the max
+    in-memory limit being hit.
+  </summary>
+</histogram>
+
+<histogram name="UKM.Sources.SerializedCount">
+  <owner>holte@chromium.org</owner>
+  <owner>rkaplow@chromium.org</owner>
+  <summary>
+    Counter for number of serialized UKM sources when storing a UKM log.
+  </summary>
+</histogram>
+
 <histogram name="UKM.UnsentLogs.DroppedSize" units="bytes">
   <owner>holte@chromium.org</owner>
   <owner>rkaplow@chromium.org</owner>
@@ -96169,6 +96186,7 @@
   <int value="1209221384" label="enable-experimental-accessibility-features"/>
   <int value="1210343926" label="enable-drop-sync-credential"/>
   <int value="1219628795" label="PrintScaling:disabled"/>
+  <int value="1219826373" label="ServiceWorkerNavigationPreload:enabled"/>
   <int value="1220171692" label="SpeculativeLaunchServiceWorker:enabled"/>
   <int value="1220464509" label="enable-first-run-ui-transitions"/>
   <int value="1221559505" label="enable-spelling-feedback-field-trial"/>
@@ -96252,6 +96270,7 @@
   <int value="1511161758" label="BackgroundLoader:enabled"/>
   <int value="1515196403" label="fast-user-switching"/>
   <int value="1517863401" label="history-entry-requires-user-gesture"/>
+  <int value="1541723759" label="ServiceWorkerNavigationPreload:disabled"/>
   <int value="1548776701" label="AllBookmarks:disabled"/>
   <int value="1548942246" label="PassiveDocumentEventListeners:disabled"/>
   <int value="1560188739" label="reader-mode-heuristics"/>
@@ -99582,7 +99601,7 @@
   <int value="409" label="SEARCH_SUGGEST via SearchProvider"/>
   <int value="410" label="SEARCH_OTHER_ENGINE via SearchProvider"/>
   <int value="414" label="SEARCH_SUGGEST_ENTITY via SearchProvider"/>
-  <int value="415" label="SEARCH_SUGGEST_INFINITE via SearchProvider"/>
+  <int value="415" label="SEARCH_SUGGEST_TAIL via SearchProvider"/>
   <int value="416" label="SEARCH_SUGGEST_PERSONALIZED via SearchProvider"/>
   <int value="422" label="SEARCH_SUGGEST_ANSWER via SearchProvider"/>
   <int value="423" label="CALCULATOR via SearchProvider"/>
@@ -115590,6 +115609,8 @@
   <affected-histogram
       name="PageLoad.Clients.ServiceWorker.PaintTiming.NavigationToFirstContentfulPaint"/>
   <affected-histogram
+      name="PageLoad.Clients.ServiceWorker.ParseTiming.NavigationToParseStart"/>
+  <affected-histogram
       name="PageLoad.Clients.ServiceWorker.Timing2.NavigationToFirstContentfulPaint">
     <obsolete>
       Deprecated in favor of PaintTiming equivalent.
@@ -115941,6 +115962,7 @@
       name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/>
   <affected-histogram
       name="PageLoad.PaintTiming.ParseStartToFirstContentfulPaint"/>
+  <affected-histogram name="PageLoad.ParseTiming.NavigationToParseStart"/>
   <affected-histogram name="PageLoad.Timing2.NavigationToFirstContentfulPaint">
     <obsolete>
       Deprecated in favor of PaintTiming equivalent.
diff --git a/tools/metrics/rappor/rappor.xml b/tools/metrics/rappor/rappor.xml
index f29a359..99c9d93 100644
--- a/tools/metrics/rappor/rappor.xml
+++ b/tools/metrics/rappor/rappor.xml
@@ -1316,6 +1316,15 @@
   </summary>
 </rappor-metric>
 
+<rappor-metric name="Media.Session.APIUsage.Origin" type="ETLD_PLUS_ONE">
+  <owner>avayvod@chromium.org</owner>
+  <owner>mlamouri@chromium.org</owner>
+  <owner>zqzhang@chromium.org</owner>
+  <summary>
+    The eTLD+1 of the URL of frames using the Media Session API.
+  </summary>
+</rappor-metric>
+
 <rappor-metric name="NTP.ExplicitUserAction.PageNavigation.NTPTileClick"
     type="UMA_RAPPOR_TYPE">
   <owner>knn@chromium.org</owner>
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index 1250b4d..318c7361 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -208,7 +208,7 @@
       cc::AnimationTimeline::Create(cc::AnimationIdProvider::NextTimelineId());
   animation_host_->AddAnimationTimeline(animation_timeline_.get());
 
-  host_->GetLayerTree()->SetRootLayer(root_web_layer_);
+  host_->SetRootLayer(root_web_layer_);
   host_->SetFrameSinkId(frame_sink_id_);
   host_->SetVisible(true);
 
@@ -303,8 +303,7 @@
 
 void Compositor::SetHostHasTransparentBackground(
     bool host_has_transparent_background) {
-  host_->GetLayerTree()->set_has_transparent_background(
-      host_has_transparent_background);
+  host_->set_has_transparent_background(host_has_transparent_background);
 }
 
 void Compositor::ScheduleFullRedraw() {
@@ -312,8 +311,7 @@
   // will also commit.  This should probably just redraw the screen
   // from damage and not commit.  ScheduleDraw/ScheduleRedraw need
   // better names.
-  host_->SetNeedsRedrawRect(
-      gfx::Rect(host_->GetLayerTree()->device_viewport_size()));
+  host_->SetNeedsRedrawRect(gfx::Rect(host_->device_viewport_size()));
   host_->SetNeedsCommit();
 }
 
@@ -337,7 +335,7 @@
   DCHECK_GT(scale, 0);
   if (!size_in_pixel.IsEmpty()) {
     size_ = size_in_pixel;
-    host_->GetLayerTree()->SetViewportSize(size_in_pixel);
+    host_->SetViewportSize(size_in_pixel);
     root_web_layer_->SetBounds(size_in_pixel);
     // TODO(fsamuel): Get rid of ContextFactoryPrivate.
     if (context_factory_private_)
@@ -345,14 +343,14 @@
   }
   if (device_scale_factor_ != scale) {
     device_scale_factor_ = scale;
-    host_->GetLayerTree()->SetDeviceScaleFactor(scale);
+    host_->SetDeviceScaleFactor(scale);
     if (root_layer_)
       root_layer_->OnDeviceScaleFactorChanged(scale);
   }
 }
 
 void Compositor::SetDisplayColorSpace(const gfx::ColorSpace& color_space) {
-  host_->GetLayerTree()->SetDeviceColorSpace(color_space);
+  host_->SetDeviceColorSpace(color_space);
   color_space_ = color_space;
   // Color space is reset when the output surface is lost, so this must also be
   // updated then.
@@ -362,7 +360,7 @@
 }
 
 void Compositor::SetBackgroundColor(SkColor color) {
-  host_->GetLayerTree()->set_background_color(color);
+  host_->set_background_color(color);
   ScheduleDraw();
 }
 
diff --git a/ui/gfx/color_space.cc b/ui/gfx/color_space.cc
index 2bf317b..077e927 100644
--- a/ui/gfx/color_space.cc
+++ b/ui/gfx/color_space.cc
@@ -88,7 +88,7 @@
 
 // static
 ColorSpace ColorSpace::CreateSCRGBLinear() {
-  return ColorSpace(PrimaryID::BT709, TransferID::LINEAR, MatrixID::RGB,
+  return ColorSpace(PrimaryID::BT709, TransferID::LINEAR_HDR, MatrixID::RGB,
                     RangeID::FULL);
 }
 
@@ -129,7 +129,8 @@
 
 bool ColorSpace::IsHDR() const {
   return transfer_ == TransferID::SMPTEST2084 ||
-         transfer_ == TransferID::ARIB_STD_B67;
+         transfer_ == TransferID::ARIB_STD_B67 ||
+         transfer_ == TransferID::LINEAR_HDR;
 }
 
 bool ColorSpace::operator!=(const ColorSpace& other) const {
diff --git a/ui/gfx/color_space.h b/ui/gfx/color_space.h
index df90dab..dc54cb7 100644
--- a/ui/gfx/color_space.h
+++ b/ui/gfx/color_space.h
@@ -90,6 +90,8 @@
 
     // TODO(hubbe): Need to store an approximation of the gamma function(s).
     CUSTOM,
+    // Like LINEAR, but intended for HDR. (can go outside of 0-1)
+    LINEAR_HDR,
     LAST = CUSTOM,
   };
 
diff --git a/ui/gfx/color_space_win.cc b/ui/gfx/color_space_win.cc
index 2ff8fdc..b9e9a03 100644
--- a/ui/gfx/color_space_win.cc
+++ b/ui/gfx/color_space_win.cc
@@ -103,6 +103,7 @@
       format.VideoTransferFunction = DXVA2_VideoTransFunc_28;
       break;
     case gfx::ColorSpace::TransferID::LINEAR:
+    case gfx::ColorSpace::TransferID::LINEAR_HDR:
       format.VideoTransferFunction = DXVA2_VideoTransFunc_10;
       break;
     case gfx::ColorSpace::TransferID::IEC61966_2_1:
diff --git a/ui/gfx/color_transform.cc b/ui/gfx/color_transform.cc
index 3a63643..110521f 100644
--- a/ui/gfx/color_transform.cc
+++ b/ui/gfx/color_transform.cc
@@ -201,6 +201,7 @@
     }
 
     case ColorSpace::TransferID::LINEAR:
+    case ColorSpace::TransferID::LINEAR_HDR:
       return v;
 
     case ColorSpace::TransferID::LOG:
@@ -330,6 +331,7 @@
     }
 
     case ColorSpace::TransferID::LINEAR:
+    case ColorSpace::TransferID::LINEAR_HDR:
       return v;
 
     case ColorSpace::TransferID::LOG:
@@ -618,7 +620,12 @@
 class ColorTransformFromLinear : public ColorTransformInternal {
  public:
   explicit ColorTransformFromLinear(ColorSpace::TransferID transfer)
-      : transfer_(transfer) {}
+      : transfer_(transfer) {
+    // Map LINEAR_HDR to LINEAR for optimizations.
+    if (transfer_ == ColorSpace::TransferID::LINEAR_HDR) {
+      transfer_ = ColorSpace::TransferID::LINEAR;
+    }
+  }
   bool Prepend(ColorTransformInternal* prev) override {
     return prev->Join(*this);
   }
@@ -641,7 +648,12 @@
 class ColorTransformToLinear : public ColorTransformInternal {
  public:
   explicit ColorTransformToLinear(ColorSpace::TransferID transfer)
-      : transfer_(transfer) {}
+      : transfer_(transfer) {
+    // Map LINEAR_HDR to LINEAR for optimizations.
+    if (transfer_ == ColorSpace::TransferID::LINEAR_HDR) {
+      transfer_ = ColorSpace::TransferID::LINEAR;
+    }
+  }
 
   bool Prepend(ColorTransformInternal* prev) override {
     return prev->Join(*this);
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc
index aa002f2..2accca9 100644
--- a/ui/views/controls/menu/menu_controller.cc
+++ b/ui/views/controls/menu/menu_controller.cc
@@ -433,6 +433,12 @@
   } else {
     showing_ = true;
 
+    // TODO(jonross): remove after tracking down the cause of
+    // (crbug.com/683087).
+    // If we are not showing we should be shutting down, this could lead to
+    // incorrect delegate states.
+    CHECK(!running_);
+
     if (owner_)
       owner_->RemoveObserver(this);
     owner_ = parent;
@@ -470,6 +476,10 @@
   if (ViewsDelegate::GetInstance())
     ViewsDelegate::GetInstance()->AddRef();
 
+  // TODO(jonross): remove after tracking down the cause of (crbug.com/683087).
+  // About to either exit and run async, or nest message loop.
+  running_ = true;
+
   if (async_run_)
     return nullptr;
 
@@ -518,6 +528,11 @@
   SetSelection(NULL, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT);
 
   if (!blocking_run_) {
+    // TODO(jonross): remove after tracking down the cause of
+    // (crbug.com/683087).
+    bool nested = delegate_stack_.size() > 1;
+    CHECK(!nested);
+    base::WeakPtr<MenuController> this_ref = AsWeakPtr();
     // If we didn't block the caller we need to notify the menu, which
     // triggers deleting us.
     DCHECK(selected);
@@ -525,6 +540,7 @@
     delegate_->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
                             selected->GetRootMenuItem(), accept_event_flags_);
     // WARNING: the call to MenuClosed deletes us.
+    CHECK(!this_ref);
     return;
   }
 
@@ -544,6 +560,12 @@
 
 void MenuController::AddNestedDelegate(
     internal::MenuControllerDelegate* delegate) {
+  // TODO(jonross): remove after tracking down the cause of (crbug.com/683087).
+  for (auto delegates : delegate_stack_) {
+    // Having the same delegate in the stack could cause deletion order issues.
+    CHECK_NE(delegates.first, delegate);
+  }
+
   delegate_stack_.push_back(std::make_pair(delegate, async_run_));
   delegate_ = delegate;
 }
@@ -979,9 +1001,13 @@
     drop_target = drop_target->GetParentMenuItem();
 
   if (!IsBlockingRun()) {
+    // TODO(jonross): remove after tracking down the cause of
+    // (crbug.com/683087).
+    base::WeakPtr<MenuController> this_ref = AsWeakPtr();
     delegate_->OnMenuClosed(
         internal::MenuControllerDelegate::DONT_NOTIFY_DELEGATE,
         item->GetRootMenuItem(), accept_event_flags_);
+    CHECK(!this_ref);
   }
 
   // WARNING: the call to MenuClosed deletes us.
@@ -1380,6 +1406,7 @@
                                internal::MenuControllerDelegate* delegate)
     : blocking_run_(blocking),
       showing_(false),
+      running_(false),
       exit_type_(EXIT_NONE),
       did_capture_(false),
       result_(NULL),
@@ -2658,6 +2685,9 @@
 
     showing_ = false;
     did_capture_ = false;
+    // TODO(jonross): remove after tracking down the cause of
+    // (crbug.com/683087).
+    running_ = false;
   }
 
   MenuItemView* result = result_;
diff --git a/ui/views/controls/menu/menu_controller.h b/ui/views/controls/menu/menu_controller.h
index 697e9a5..d3a4177 100644
--- a/ui/views/controls/menu/menu_controller.h
+++ b/ui/views/controls/menu/menu_controller.h
@@ -574,6 +574,11 @@
   // If true, we're showing.
   bool showing_;
 
+  // TODO(jonross): remove after tracking down the cause of (crbug.com/683087).
+  // If true running has began and there are still delegates which have not been
+  // closed. We may not be showing.
+  bool running_;
+
   // Indicates what to exit.
   ExitType exit_type_;
 
diff --git a/ui/views/controls/menu/menu_runner_impl.cc b/ui/views/controls/menu/menu_runner_impl.cc
index a247d512..0bb9486 100644
--- a/ui/views/controls/menu/menu_runner_impl.cc
+++ b/ui/views/controls/menu/menu_runner_impl.cc
@@ -69,9 +69,15 @@
       controller_->Cancel(MenuController::EXIT_DESTROYED);
       return;
     }
-  }
 
-  delete this;
+    // TODO(jonross): remove after tracking down the cause of
+    // (crbug.com/683087).
+    // Update for the ASAN stack trace to determine if we are in the running
+    // state during the incorrect destruction order.
+    delete this;
+  } else {
+    delete this;
+  }
 }
 
 MenuRunner::RunResult MenuRunnerImpl::RunMenuAt(Widget* parent,
@@ -86,6 +92,12 @@
     return MenuRunner::NORMAL_EXIT;
   }
 
+  // TODO(jonross): remove after tracking down the cause of (crbug.com/683087).
+  // Verify that this was not a delegate previously used for a run, which was
+  // shutdown, but not deleted. Nesting the same delegate multiple times is
+  // dangerous.
+  CHECK(!controller_);
+
   MenuController* controller = MenuController::GetActiveInstance();
   if (controller) {
     if ((run_types & MenuRunner::IS_NESTED) != 0) {
@@ -121,6 +133,8 @@
   if (!controller) {
     // No menus are showing, show one.
     controller = new MenuController(!for_drop_, this);
+    // TODO(jonross): remove after tracking down the cause of
+    // (crbug.com/683087).
     owns_controller_ = true;
   }
   controller->SetAsyncRun(async_);
@@ -190,8 +204,9 @@
     // We created the controller and need to delete it.
     delete controller_.get();
     owns_controller_ = false;
+    controller_ = nullptr;
   }
-  controller_ = nullptr;
+
   // Make sure all the windows we created to show the menus have been
   // destroyed.
   menu_->DestroyAllMenuHosts();
diff --git a/ui/views/style/platform_style_mac.mm b/ui/views/style/platform_style_mac.mm
index 3785d83..a335d99 100644
--- a/ui/views/style/platform_style_mac.mm
+++ b/ui/views/style/platform_style_mac.mm
@@ -12,7 +12,7 @@
 #include "ui/resources/grit/ui_resources.h"
 #include "ui/views/controls/button/label_button.h"
 #import "ui/views/controls/scrollbar/cocoa_scroll_bar.h"
-#include "ui/views/resources/vector_icons/vector_icons.h"
+#include "ui/views/vector_icons.h"
 
 #import <Cocoa/Cocoa.h>
 
diff --git a/ui/views/view.cc b/ui/views/view.cc
index cf93f92c..04c5f2f 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -130,6 +130,7 @@
 #if DCHECK_IS_ON()
       iterating_(false),
 #endif
+      can_process_events_within_subtree_(true),
       visible_(true),
       enabled_(true),
       notify_enter_exit_on_child_(false),
@@ -988,7 +989,7 @@
 }
 
 bool View::CanProcessEventsWithinSubtree() const {
-  return true;
+  return can_process_events_within_subtree_;
 }
 
 View* View::GetTooltipHandlerForPoint(const gfx::Point& point) {
diff --git a/ui/views/view.h b/ui/views/view.h
index 19118be1..fcbee85 100644
--- a/ui/views/view.h
+++ b/ui/views/view.h
@@ -617,6 +617,12 @@
   // be the target of an event.
   virtual bool CanProcessEventsWithinSubtree() const;
 
+  // Sets whether this view or any of its descendants are permitted to be the
+  // target of an event.
+  void set_can_process_events_within_subtree(bool can_process) {
+    can_process_events_within_subtree_ = can_process;
+  }
+
   // Returns true if the mouse cursor is over |view| and mouse events are
   // enabled.
   bool IsMouseHovered() const;
@@ -1491,6 +1497,8 @@
   mutable bool iterating_;
 #endif
 
+  bool can_process_events_within_subtree_;
+
   // Size and disposition ------------------------------------------------------
 
   // This View's bounds in the parent coordinate system.